@@ -21,6 +21,7 @@ class FcitxInputController: IMKInputController {
2121 let client : Any !
2222 var accentColor = " "
2323 var selection : NSRange ? = nil
24+ var obeySecureInput = true
2425
2526 // A registry of live FcitxInputController objects.
2627 // Use NSHashTable to store weak references.
@@ -70,6 +71,33 @@ class FcitxInputController: IMKInputController {
7071 return response. accepted
7172 }
7273
74+ // Normal apps like Chrome calls EnableSecureEventInput when its password input is focused,
75+ // and calls DisableSecureEventInput on blur of input or app itself. Abnormal apps call
76+ // EnableSecureEventInput but doesn't call DisableSecureEventInput on blur, so we can't
77+ // rely on IsSecureEventInputEnabled's true return value, as obeying it will lock keyboard-us.
78+ // Users observe https://discussions.apple.com/thread/253793652 but it's also possible that
79+ // other apps are abusing, see comments for getSecureInputProcessPID.
80+ func getSecureInputInfo( isOnFocus: Bool ) -> Bool {
81+ if appId == " com.apple.loginwindow " {
82+ return true
83+ }
84+ if !IsSecureEventInputEnabled( ) {
85+ return false
86+ }
87+ if isOnFocus {
88+ let pid = getSecureInputProcessPID ( )
89+ let runningApp = pid == nil ? nil : NSRunningApplication ( processIdentifier: pid!)
90+ obeySecureInput = runningApp? . bundleIdentifier == appId
91+ if !obeySecureInput {
92+ FCITX_WARN (
93+ " Secure input is abused by (possibly) \( runningApp? . localizedName ?? " ? " ) : \( runningApp? . bundleIdentifier ?? " ? " ) pid= \( pid ?? - 1 ) "
94+ )
95+ }
96+ }
97+ // On keyDown, don't call getSecureInputProcessPID for performance.
98+ return obeySecureInput
99+ }
100+
73101 func processKey( _ unicode: UInt32 , _ modsVal: UInt32 , _ code: UInt16 , _ isRelease: Bool ) -> Bool {
74102 guard let client = client as? IMKTextInput else {
75103 return false
@@ -83,7 +111,7 @@ class FcitxInputController: IMKInputController {
83111 process_key ( uuid, 0 , 0 , 0 , false , false )
84112 }
85113 // It can change within an IMKInputController (e.g. sudo in Terminal), so must reevaluate before each key sent to IM.
86- let isPassword = IsSecureEventInputEnabled ( )
114+ let isPassword = getSecureInputInfo ( isOnFocus : false )
87115 let res = String ( process_key ( uuid, unicode, modsVal, code, isRelease, isPassword) )
88116 return processRes ( client, res)
89117 }
@@ -151,7 +179,7 @@ class FcitxInputController: IMKInputController {
151179 // activateServer is called when app is in foreground but not necessarily a text field is selected.
152180 hasCursor = false
153181 // Make sure status bar is updated on click password input, before first key event.
154- let isPassword = IsSecureEventInputEnabled ( )
182+ let isPassword = getSecureInputInfo ( isOnFocus : true )
155183 focus_in ( uuid, isPassword)
156184 }
157185
0 commit comments