diff --git a/Source/Modules/ControllerModules/ctlInputMethod_Common.swift b/Source/Modules/ControllerModules/ctlInputMethod_Common.swift index e11b958d..c19c2ecc 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_Common.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_Common.swift @@ -15,7 +15,7 @@ extension ctlInputMethod { /// 這樣分開處理很有必要,不然 handle() 函式會陷入無限迴圈。 /// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。 /// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。 - func commonEventHandler(_ event: NSEvent!) -> Bool { + func commonEventHandler(_ event: NSEvent) -> Bool { // 用 Shift 開關半形英數模式,僅對 macOS 10.15 及之後的 macOS 有效。 let shouldUseHandle = (IME.arrClientShiftHandlingExceptionList.contains(clientBundleIdentifier) diff --git a/Source/Modules/ControllerModules/ctlInputMethod_Core.swift b/Source/Modules/ControllerModules/ctlInputMethod_Core.swift index 26837504..0f4a692e 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_Core.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_Core.swift @@ -197,18 +197,21 @@ class ctlInputMethod: IMKInputController { /// 接受所有鍵鼠事件為 NSEvent,讓輸入法判斷是否要處理、該怎樣處理。 /// - Parameters: - /// - event: 裝置操作輸入事件。 + /// - event: 裝置操作輸入事件,可能會是 nil。 /// - sender: 呼叫了該函式的客體(無須使用)。 /// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。 @objc(handleEvent:client:) override func handle(_ event: NSEvent!, client sender: Any!) -> Bool { _ = sender // 防止格式整理工具毀掉與此對應的參數。 + // 就這傳入的 NSEvent 都還有可能是 nil,Apple InputMethodKit 團隊到底在搞三小。 + guard let event = event else { return false } + // IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。 // 這樣可以讓 interpretKeyEvents() 函式自行判斷: // - 是就地交給 super.interpretKeyEvents() 處理? // - 還是藉由 delegate 扔回 ctlInputMethod 給 KeyHandler 處理? if let ctlCandidateCurrent = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK, ctlCandidateCurrent.visible { - let event: NSEvent! = ctlCandidateIMK.replaceNumPadKeyCodes(target: event) ?? event + let event: NSEvent = ctlCandidateIMK.replaceNumPadKeyCodes(target: event) ?? event let input = InputSignal(event: event) // Shift+Enter 是個特殊情形,不提前攔截處理的話、會有垃圾參數傳給 delegate 的 keyHandler 從而崩潰。 // 所以這裡直接將 Shift Flags 清空。 diff --git a/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift b/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift index ce1397af..1d634e75 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift @@ -62,7 +62,7 @@ extension ctlInputMethod: ctlCandidateDelegate { /// 該函式僅由 IMK 選字窗來存取,且對接給 commonEventHandler()。 /// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。 /// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。 - @discardableResult func sharedEventHandler(_ event: NSEvent!) -> Bool { + @discardableResult func sharedEventHandler(_ event: NSEvent) -> Bool { commonEventHandler(event) } diff --git a/Source/Modules/UIModules/CandidateUI/ctlCandidate.swift b/Source/Modules/UIModules/CandidateUI/ctlCandidate.swift index 7a79b603..04ca1a5f 100644 --- a/Source/Modules/UIModules/CandidateUI/ctlCandidate.swift +++ b/Source/Modules/UIModules/CandidateUI/ctlCandidate.swift @@ -28,7 +28,7 @@ public class CandidateKeyLabel: NSObject { public protocol ctlCandidateDelegate: AnyObject { var isAssociatedPhrasesState: Bool { get } - func sharedEventHandler(_ event: NSEvent!) -> Bool + func sharedEventHandler(_ event: NSEvent) -> Bool func candidateCountForController(_ controller: ctlCandidateProtocol) -> Int func candidatesForController(_ controller: ctlCandidateProtocol) -> [(String, String)] func ctlCandidate(_ controller: ctlCandidateProtocol, candidateAtIndex index: Int)