From 6c87a29fb060b039342b1cb661553ef835369e23 Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Sat, 24 Jun 2023 14:19:33 +0800 Subject: [PATCH] IMKCandidates // Dissolve InputHandler.handleEvent(), etc. --- Source/Modules/InputHandler_Core.swift | 2 +- .../InputHandler_HandleCandidate.swift | 66 ++++++- Source/Modules/InputHandler_HandleEvent.swift | 181 ------------------ Source/Modules/InputHandler_TriageInput.swift | 2 +- Source/Modules/SessionCtl_HandleDisplay.swift | 9 - Source/Modules/SessionCtl_HandleEvent.swift | 2 +- .../CandidateUI/IMKCandidatesImpl.swift | 45 ++++- vChewing.xcodeproj/project.pbxproj | 4 - 8 files changed, 97 insertions(+), 214 deletions(-) delete mode 100644 Source/Modules/InputHandler_HandleEvent.swift diff --git a/Source/Modules/InputHandler_Core.swift b/Source/Modules/InputHandler_Core.swift index 7deb70d7..904f11be 100644 --- a/Source/Modules/InputHandler_Core.swift +++ b/Source/Modules/InputHandler_Core.swift @@ -29,7 +29,7 @@ public protocol InputHandlerProtocol { func clear() func clearComposerAndCalligrapher() func ensureKeyboardParser() - func handleEvent(_ event: NSEvent) -> Bool + func triageInput(event input: InputSignalProtocol) -> Bool func generateStateOfCandidates() -> IMEStateProtocol func generateStateOfInputting(sansReading: Bool) -> IMEStateProtocol func generateStateOfAssociates(withPair pair: Megrez.KeyValuePaired) -> IMEStateProtocol diff --git a/Source/Modules/InputHandler_HandleCandidate.swift b/Source/Modules/InputHandler_HandleCandidate.swift index 67c6acfb..b4bd09ba 100644 --- a/Source/Modules/InputHandler_HandleCandidate.swift +++ b/Source/Modules/InputHandler_HandleCandidate.swift @@ -22,7 +22,13 @@ extension InputHandler { guard let delegate = delegate else { return false } guard var ctlCandidate = delegate.candidateController() else { return false } let state = delegate.state - guard state.isCandidateContainer, !state.candidates.isEmpty else { return false } + guard state.isCandidateContainer else { return false } // 會自動判斷「isEmpty」。 + guard ctlCandidate.visible else { return false } + var input = input + + var imkC: CtlCandidateIMK? { + prefs.useIMKCandidateWindow ? (ctlCandidate as? CtlCandidateIMK) : nil + } // MARK: 選字窗內使用熱鍵升權、降權、刪詞。 @@ -85,6 +91,14 @@ extension InputHandler { // MARK: 批次集中處理某些常用功能鍵 + func confirmHighlightedCandidate() { + if let imkC = imkC, let enterEvent = KeyCode.kCarriageReturn.toEvent() { + imkC.process(event: enterEvent) + } else { + delegate.candidateSelectionConfirmedByInputHandler(at: ctlCandidate.highlightedIndex) + } + } + if let keyCodeType = KeyCode(rawValue: input.keyCode) { switch keyCodeType { case .kLineFeed, .kCarriageReturn: @@ -92,7 +106,7 @@ extension InputHandler { delegate.switchState(IMEState.ofAbortion()) return true } - delegate.candidateSelectionConfirmedByInputHandler(at: ctlCandidate.highlightedIndex) + confirmHighlightedCandidate() return true case .kTab: let updated: Bool = @@ -107,7 +121,7 @@ extension InputHandler { return true case .kSpace where state.type != .ofInputting: guard !(prefs.useSpaceToCommitHighlightedSCPCCandidate && prefs.useSCPCTypingMode) else { - delegate.candidateSelectionConfirmedByInputHandler(at: ctlCandidate.highlightedIndex) + confirmHighlightedCandidate() return true } let updated: Bool = @@ -140,11 +154,19 @@ extension InputHandler { } return true case .kHome: + if let imkC = imkC, let nsEvent = input as? NSEvent { + imkC.process(event: nsEvent) + return true + } _ = (ctlCandidate.highlightedIndex == 0) ? delegate.callError("9B6EDE8D") : (ctlCandidate.highlightedIndex = 0) return true case .kEnd: + if let imkC = imkC, let nsEvent = input as? NSEvent { + imkC.process(event: nsEvent) + return true + } let maxIndex = state.candidates.count - 1 _ = (ctlCandidate.highlightedIndex == maxIndex) @@ -154,10 +176,27 @@ extension InputHandler { } } + // MARK: 針對 IMKCandidates,將數字小鍵盤的事件置換掉 + + input = { + guard imkC != nil else { return input } + guard let eventToDeal = input as? NSEvent else { return input } + return CtlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal + }() + // MARK: 聯想詞處理 (Associated Phrases) 以及標準選字處理 if state.type == .ofAssociates { - if !input.isShiftHold { return false } + if !input.isShiftHold { + return false + } + // 將 input 訊號翻譯成去掉 Shift 的 NSEvent,然後再投餵給 IMKCandidates。 + if let imkC = imkC, let inputEvent = input as? NSEvent, + let inputEventShifted = CtlCandidateIMK.giveSelectionKeySansModifiers(from: inputEvent) + { + imkC.process(event: inputEventShifted) + return true + } } var index: Int? @@ -173,9 +212,19 @@ extension InputHandler { break checkSelectionKey } - if let index = index, let candidateIndex = ctlCandidate.candidateIndexAtKeyLabelIndex(index) { - delegate.candidateSelectionConfirmedByInputHandler(at: candidateIndex) - return true + // 標準選字處理 + if let index = index { + if let imkC = imkC, let oldEvent = input as? NSEvent { + if input.isShiftHold, let newEvent = CtlCandidateIMK.giveSelectionKeySansModifiers(from: oldEvent) { + imkC.process(event: newEvent) + } else { + imkC.process(event: oldEvent) + } + return true + } else if let candidateIndex = ctlCandidate.candidateIndexAtKeyLabelIndex(index) { + delegate.candidateSelectionConfirmedByInputHandler(at: candidateIndex) + return true + } } if state.type == .ofAssociates { return false } @@ -216,8 +265,7 @@ extension InputHandler { } if shouldAutoSelectCandidate { - guard let candidateIndex = ctlCandidate.candidateIndexAtKeyLabelIndex(0) else { return true } - delegate.candidateSelectionConfirmedByInputHandler(at: candidateIndex) + confirmHighlightedCandidate() // 此時的高亮候選字是第一個候選字。 delegate.switchState(IMEState.ofAbortion()) return triageInput(event: input) } diff --git a/Source/Modules/InputHandler_HandleEvent.swift b/Source/Modules/InputHandler_HandleEvent.swift deleted file mode 100644 index 6fd29030..00000000 --- a/Source/Modules/InputHandler_HandleEvent.swift +++ /dev/null @@ -1,181 +0,0 @@ -// (c) 2021 and onwards The vChewing Project (MIT-NTL License). -// ==================== -// This code is released under the MIT license (SPDX-License-Identifier: MIT) -// ... with NTL restriction stating that: -// No trademark license is granted to use the trade names, trademarks, service -// marks, or product names of Contributor, except as required to fulfill notice -// requirements defined in MIT License. - -/// 該檔案乃輸入調度模組當中用來預處理 NSEvent 的模組。 - -import CocoaExtension -import InputMethodKit -import Shared - -// MARK: - § 根據狀態調度按鍵輸入 (Handle Input with States) - -extension InputHandler { - /// 分診函式,會先確認是否是 IMK 選字窗要處理的事件、然後再決定處理步驟。 - /// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。 - /// - Returns: 回「`true`」以將該按鍵已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。 - public func handleEvent(_ event: NSEvent) -> Bool { - imkCandidatesEventPreHandler(event: event) ?? triageInput(event: event) - } - - /// 專門處理與 IMK 選字窗有關的判斷語句。 - /// 這樣分開處理很有必要,不然 handle() 函式會陷入無限迴圈。 - /// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。 - /// - Returns: 回「`true`」以將該按鍵已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。 - private func imkCandidatesEventPreHandler(event eventToDeal: NSEvent) -> Bool? { - guard prefs.useIMKCandidateWindow else { return nil } - guard let delegate = delegate, delegate.state.isCandidateContainer else { return nil } - - // IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。 - // 這樣可以讓 interpretKeyEvents() 函式自行判斷: - // - 是就地交給 imkCandidates.interpretKeyEvents() 處理? - // - 還是藉由 delegate 扔回 SessionCtl 給 InputHandler 處理? - if let imkCandidates = delegate.candidateController() as? CtlCandidateIMK, imkCandidates.visible { - let event: NSEvent = CtlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal - - // Shift+Enter 是個特殊情形,不提前攔截處理的話、會有垃圾參數傳給 delegate 的 inputHandler 從而崩潰。 - // 所以這裡直接將 Shift Flags 清空。 - if event.isShiftHold, event.isEnter { - guard let newEvent = event.reinitiate(modifierFlags: []) else { - IMEApp.buzz() - return true - } - - return imkCandidatesEventSubHandler(event: newEvent) - } - - // 聯想詞選字。 - if let newChar = CtlCandidateIMK.defaultIMKSelectionKey[event.keyCode], - event.isShiftHold, delegate.state.type == .ofAssociates, - let newEvent = event.reinitiate(modifierFlags: [], characters: newChar) - { - if #available(macOS 10.14, *) { - PrefMgr.shared.failureFlagForIMKCandidates = true - imkCandidates.handleKeyboardEvent(newEvent) - PrefMgr.shared.failureFlagForIMKCandidates = false - } else { - imkCandidates.interpretKeyEvents([newEvent]) - } - return true - } - - return imkCandidatesEventSubHandler(event: event) - } - return nil - } - - private func imkCandidatesEventSubHandler(event: NSEvent) -> Bool { - guard let delegate = delegate else { return false } - let eventArray = [event] - guard let imkC = delegate.candidateController() as? CtlCandidateIMK else { return false } - if event.isEsc || event.isBackSpace || event.isDelete || (event.isShiftHold && !event.isSpace) { - return triageInput(event: event) - } else if event.isSymbolMenuPhysicalKey { - // 符號鍵的行為是固定的,不受偏好設定影響。 - switch imkC.currentLayout { - case .horizontal: - switch event.modifierFlags { - case []: imkC.moveDown(self) - case .shift, - .option where delegate.state.type != .ofSymbolTable: - imkC.moveUp(self) - case .option where delegate.state.type == .ofSymbolTable: - handleHaninKeyboardSymbolModeToggle() - default: break - } - case .vertical: - switch event.modifierFlags { - case []: imkC.moveRight(self) - case .shift, - .option where delegate.state.type != .ofSymbolTable: - imkC.moveLeft(self) - case .option where delegate.state.type == .ofSymbolTable: - handleHaninKeyboardSymbolModeToggle() - default: break - } - @unknown default: break - } - return true - } else if event.isSpace { - if prefs.useSpaceToCommitHighlightedSCPCCandidate, prefs.useSCPCTypingMode, - let eventTranslated = event.reinitiate(keyCode: KeyCode.kCarriageReturn.rawValue) - { - if #available(macOS 10.14, *) { - PrefMgr.shared.failureFlagForIMKCandidates = true - imkC.handleKeyboardEvent(eventTranslated) - PrefMgr.shared.failureFlagForIMKCandidates = false - } else { - imkC.interpretKeyEvents([eventTranslated]) - } - return true - } - switch prefs.specifyShiftSpaceKeyBehavior { - case true: _ = event.isShiftHold ? imkC.highlightNextCandidate() : imkC.showNextPage() - case false: _ = event.isShiftHold ? imkC.showNextPage() : imkC.highlightNextCandidate() - } - return true - } else if event.isTab { - switch prefs.specifyShiftTabKeyBehavior { - case true: _ = event.isShiftHold ? imkC.showPreviousPage() : imkC.showNextPage() - case false: _ = event.isShiftHold ? imkC.highlightPreviousCandidate() : imkC.highlightNextCandidate() - } - return true - } else { - if let newChar = CtlCandidateIMK.defaultIMKSelectionKey[event.keyCode] { - /// 根據 KeyCode 重新換算一下選字鍵的 NSEvent,糾正其 Character 數值。 - /// 反正 IMK 選字窗目前也沒辦法修改選字鍵。 - let newEvent = event.reinitiate(characters: newChar) - if let newEvent = newEvent { - if prefs.useSCPCTypingMode, delegate.state.type == .ofAssociates { - // 註:input.isShiftHold 已經在 delegate.handle() 內處理,因為在那邊處理才有效。 - return event.isShiftHold ? true : triageInput(event: event) - } else { - if #available(macOS 10.14, *) { - PrefMgr.shared.failureFlagForIMKCandidates = true - imkC.handleKeyboardEvent(newEvent) - PrefMgr.shared.failureFlagForIMKCandidates = false - } else { - imkC.interpretKeyEvents([newEvent]) - } - return true - } - } - } - - // Shift+Command+[] 被 Chrome 系瀏覽器佔用,所以改用 Ctrl。 - let ctrlCMD: Bool = event.modifierFlags == [.control, .command] - let ctrlShiftCMD: Bool = event.modifierFlags == [.control, .command, .shift] - if ctrlShiftCMD || ctrlCMD { - // 此處 JIS 鍵盤判定無法用於螢幕鍵盤。所以,螢幕鍵盤的場合,系統會依照 US 鍵盤的判定方案。 - let isJIS: Bool = KBGetLayoutType(Int16(LMGetKbdType())) == kKeyboardJIS - switch (event.keyCode, isJIS) { - case (30, true), (33, false): - _ = imkC.highlightPreviousCandidate() ? {}() : delegate.callError("8B144DCD") - return true - case (42, true), (30, false): - _ = imkC.highlightNextCandidate() ? {}() : delegate.callError("D2ABB507") - return true - default: break - } - } - - if prefs.useSCPCTypingMode, !event.isReservedKey { - return triageInput(event: event) - } - - if delegate.state.type == .ofAssociates, - !event.isPageUp, !event.isPageDown, !event.isCursorForward, !event.isCursorBackward, - !event.isCursorClockLeft, !event.isCursorClockRight, !event.isSpace, - !event.isEnter || !prefs.alsoConfirmAssociatedCandidatesByEnter - { - return triageInput(event: event) - } - imkC.interpretKeyEvents(eventArray) - return true - } - } -} diff --git a/Source/Modules/InputHandler_TriageInput.swift b/Source/Modules/InputHandler_TriageInput.swift index e576184f..e7f5d9d1 100644 --- a/Source/Modules/InputHandler_TriageInput.swift +++ b/Source/Modules/InputHandler_TriageInput.swift @@ -16,7 +16,7 @@ import Shared // MARK: - § 根據狀態調度按鍵輸入 (Handle Input with States) * Triage -extension InputHandler { +public extension InputHandler { func triageInput(event input: InputSignalProtocol) -> Bool { guard let delegate = delegate else { return false } var state: IMEStateProtocol { delegate.state } diff --git a/Source/Modules/SessionCtl_HandleDisplay.swift b/Source/Modules/SessionCtl_HandleDisplay.swift index 4908aa47..92d85fb4 100644 --- a/Source/Modules/SessionCtl_HandleDisplay.swift +++ b/Source/Modules/SessionCtl_HandleDisplay.swift @@ -127,15 +127,6 @@ public extension SessionCtl { } }() - if #available(macOS 10.14, *) { - // Spotlight 視窗會擋住 IMK 選字窗,所以需要特殊處理。 - if let ctlCandidateCurrent = candidateUI as? CtlCandidateIMK { - PrefMgr.shared.failureFlagForIMKCandidates = true - ctlCandidateCurrent.setWindowLevel(UInt64(CGShieldingWindowLevel() + 2)) - PrefMgr.shared.failureFlagForIMKCandidates = false - } - } - if let ctlCandidateCurrent = candidateUI as? CtlCandidateTDK { ctlCandidateCurrent.useMouseScrolling = PrefMgr.shared.enableMouseScrollingForTDKCandidatesCocoa if #available(macOS 10.15, *) { diff --git a/Source/Modules/SessionCtl_HandleEvent.swift b/Source/Modules/SessionCtl_HandleEvent.swift index a94f5e61..378c7f94 100644 --- a/Source/Modules/SessionCtl_HandleEvent.swift +++ b/Source/Modules/SessionCtl_HandleEvent.swift @@ -150,7 +150,7 @@ public extension SessionCtl { Self.areWeNerfing = eventToDeal.modifierFlags == [.shift, .command] /// 直接交給 commonEventHandler 來處理。 - let result = inputHandler.handleEvent(eventToDeal) + let result = inputHandler.triageInput(event: eventToDeal) if !result { // 除非是 .ofMarking 狀態,否則讓某些不用去抓的按鍵起到「取消工具提示」的作用。 if [.ofEmpty].contains(state.type) { tooltipInstance.hide() } diff --git a/Source/Modules/UIModules/CandidateUI/IMKCandidatesImpl.swift b/Source/Modules/UIModules/CandidateUI/IMKCandidatesImpl.swift index 063f47c9..a4bf533d 100644 --- a/Source/Modules/UIModules/CandidateUI/IMKCandidatesImpl.swift +++ b/Source/Modules/UIModules/CandidateUI/IMKCandidatesImpl.swift @@ -45,9 +45,7 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol { public var candidateFont = NSFont.systemFont(ofSize: 16) { didSet { if #available(macOS 10.14, *) { - PrefMgr.shared.failureFlagForIMKCandidates = true - setFontSize(candidateFont.pointSize) - PrefMgr.shared.failureFlagForIMKCandidates = false + protectedCall { self.setFontSize(self.candidateFont.pointSize) } } var attributes = attributes() // FB11300759: Set "NSAttributedString.Key.font" doesn't work. @@ -97,6 +95,14 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol { fatalError("init(coder:) has not been implemented") } + private func protectedCall(_ task: @escaping () -> Void) { + guard #available(macOS 10.14, *) else { return } + let key = UserDef.kFailureFlagForIMKCandidates.rawValue + UserDefaults.standard.set(true, forKey: key) + task() + UserDefaults.standard.set(false, forKey: key) + } + public func reloadData() { // guard let delegate = delegate else { return } // 下文無效,所以這句沒用。 // 既然下述函式無效,那中間這段沒用的也都砍了。 @@ -105,18 +111,15 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol { update() } - /// 幹話:這裡很多函式內容亂寫也都無所謂了,因為都被 IMKCandidates 代管執行。 - /// 對於所有 IMK 選字窗的選字判斷動作,不是在 inputHandler 中,而是在 `SessionCtl_HandleEvent` 中。 - // 該函式會影響 IMK 選字窗。 @discardableResult public func showNextPage() -> Bool { - do { currentLayout == .vertical ? moveRight(self) : moveDown(self) } + scrollPageDown(self) return true } // 該函式會影響 IMK 選字窗。 @discardableResult public func showPreviousPage() -> Bool { - do { currentLayout == .vertical ? moveLeft(self) : moveUp(self) } + scrollPageUp(self) return true } @@ -155,6 +158,24 @@ public class CtlCandidateIMK: IMKCandidates, CtlCandidateProtocol { } set { selectCandidate(withIdentifier: newValue) } } + + @discardableResult public func process(event theEvent: NSEvent) -> Bool { + guard #available(macOS 10.14, *) else { + interpretKeyEvents([theEvent]) + return true + } + var result = true + protectedCall { result = self.handleKeyboardEvent(theEvent) } + return result + } + + override public func update() { + super.update() + guard #available(macOS 10.14, *) else { return } + // Spotlight 視窗自 macOS 10.14 開始會擋住 IMK 選字窗,所以需要特殊處理。 + let level = UInt64(CGShieldingWindowLevel() + 2) + protectedCall { self.setWindowLevel(level) } + } } // MARK: - Generate TISInputSource Object @@ -180,6 +201,14 @@ var currentTISInputSource: TISInputSource? { // MARK: - Translating NumPad KeyCodes to Default IMK Candidate Selection KeyCodes. public extension CtlCandidateIMK { + static func giveSelectionKeySansModifiers(from event: NSEvent) -> NSEvent? { + let mapDefaultIMKSelectionKey: [UInt16: String] = [ + 18: "1", 19: "2", 20: "3", 21: "4", 23: "5", 22: "6", 26: "7", 28: "8", 25: "9", + ] + guard let newChar = mapDefaultIMKSelectionKey[event.keyCode] else { return nil } + return event.reinitiate(modifierFlags: [], characters: newChar) + } + static func replaceNumPadKeyCodes(target event: NSEvent) -> NSEvent? { let mapNumPadKeyCodeTranslation: [UInt16: UInt16] = [ 83: 18, 84: 19, 85: 20, 86: 21, 87: 23, 88: 22, 89: 26, 91: 28, 92: 25, diff --git a/vChewing.xcodeproj/project.pbxproj b/vChewing.xcodeproj/project.pbxproj index 9a384f73..67261c91 100644 --- a/vChewing.xcodeproj/project.pbxproj +++ b/vChewing.xcodeproj/project.pbxproj @@ -96,7 +96,6 @@ 5BDB7A4128D4824A001AC277 /* Megrez in Frameworks */ = {isa = PBXBuildFile; productRef = 5BDB7A4028D4824A001AC277 /* Megrez */; }; 5BDB7A4528D4824A001AC277 /* ShiftKeyUpChecker in Frameworks */ = {isa = PBXBuildFile; productRef = 5BDB7A4428D4824A001AC277 /* ShiftKeyUpChecker */; }; 5BDB7A4728D4824A001AC277 /* Tekkon in Frameworks */ = {isa = PBXBuildFile; productRef = 5BDB7A4628D4824A001AC277 /* Tekkon */; }; - 5BE1F8A928F86AB5006C7FF5 /* InputHandler_HandleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE1F8A828F86AB5006C7FF5 /* InputHandler_HandleEvent.swift */; }; 5BE377A0288FED8D0037365B /* InputHandler_HandleComposition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE3779F288FED8D0037365B /* InputHandler_HandleComposition.swift */; }; 5BEDB721283B4C250078EB25 /* data-cns.json in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71D283B4AEA0078EB25 /* data-cns.json */; }; 5BEDB722283B4C250078EB25 /* data-zhuyinwen.json in Resources */ = {isa = PBXBuildFile; fileRef = 5BEDB71F283B4AEA0078EB25 /* data-zhuyinwen.json */; }; @@ -298,7 +297,6 @@ 5BDCBB4827B4F6C600D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = ""; }; 5BDCBB4927B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = ""; }; 5BDCBB4A27B4F6C700D0CC59 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = ""; }; - 5BE1F8A828F86AB5006C7FF5 /* InputHandler_HandleEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputHandler_HandleEvent.swift; sourceTree = ""; }; 5BE3779F288FED8D0037365B /* InputHandler_HandleComposition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputHandler_HandleComposition.swift; sourceTree = ""; }; 5BE8A8C4281EE65300197741 /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = ""; }; 5BEDB71C283B4AEA0078EB25 /* data-chs.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = "data-chs.json"; path = "Data/data-chs.json"; sourceTree = ""; }; @@ -693,7 +691,6 @@ 5BD0113C2818543900609769 /* InputHandler_Core.swift */, 5B782EC3280C243C007276DE /* InputHandler_HandleCandidate.swift */, 5BE3779F288FED8D0037365B /* InputHandler_HandleComposition.swift */, - 5BE1F8A828F86AB5006C7FF5 /* InputHandler_HandleEvent.swift */, 5B3133BE280B229700A4A505 /* InputHandler_HandleStates.swift */, 5B7F225C2808501000DDD3CB /* InputHandler_TriageInput.swift */, 5BAEFACF28012565001F42C9 /* LMMgr_Core.swift */, @@ -1128,7 +1125,6 @@ 5BB1D7F42999027200EA8D2C /* PrefUITabs.swift in Sources */, 5B33844F29B8B4C200FCB497 /* LMMgr_PhraseEditorDelegate.swift in Sources */, 5B21176C287539BB000443A9 /* SessionCtl_HandleStates.swift in Sources */, - 5BE1F8A928F86AB5006C7FF5 /* InputHandler_HandleEvent.swift in Sources */, 5B69938C293B811F0057CB8E /* VwrPrefPanePhrases.swift in Sources */, 5BAEFAD028012565001F42C9 /* LMMgr_Core.swift in Sources */, 5BCC631629407BBB00A2D84F /* CtlPrefWindow_PhraseEditor.swift in Sources */,