diff --git a/Source/Data b/Source/Data index bc21120f..58fa2581 160000 --- a/Source/Data +++ b/Source/Data @@ -1 +1 @@ -Subproject commit bc21120f7241f61d968d291c988c2c34df4a1263 +Subproject commit 58fa2581c5b6819b3c2d029a11537b81442f1afc diff --git a/Source/Modules/AppDelegate.swift b/Source/Modules/AppDelegate.swift index d80355ca..47bb231b 100644 --- a/Source/Modules/AppDelegate.swift +++ b/Source/Modules/AppDelegate.swift @@ -296,27 +296,3 @@ class AppDelegate: NSObject, NSApplicationDelegate, ctlNonModalAlertWindowDelega NSApplication.shared.activate(ignoringOtherApps: true) } } - -@objc public class IME: NSObject { - // Print debug information to the console. - @objc static func prtDebugIntel(_ strPrint: String) { - if mgrPrefs.isDebugModeEnabled { - NSLog("vChewingErrorCallback: %@", strPrint) - } - } - @objc static func isDarkMode() -> Bool { - if #available(macOS 10.15, *) { - let appearanceDescription = NSApplication.shared.effectiveAppearance.debugDescription.lowercased() - if appearanceDescription.contains("dark") { - return true - } - } else if #available(macOS 10.14, *) { - if let appleInterfaceStyle = UserDefaults.standard.object(forKey: "AppleInterfaceStyle") as? String { - if appleInterfaceStyle.lowercased().contains("dark") { - return true - } - } - } - return false - } -} diff --git a/Source/Modules/ControllerModules/AppleKeyboardConverter.swift b/Source/Modules/ControllerModules/AppleKeyboardConverter.swift index 122002d9..87bd1888 100644 --- a/Source/Modules/ControllerModules/AppleKeyboardConverter.swift +++ b/Source/Modules/ControllerModules/AppleKeyboardConverter.swift @@ -35,6 +35,16 @@ import Cocoa return true case "org.atelierInmu.vChewing.keyLayouts.vchewingeten": return true + case "org.unknown.keylayout.vChewingDachen": + return true + case "org.unknown.keylayout.vChewingFakeSeigyou": + return true + case "org.unknown.keylayout.vChewingETen": + return true + case "org.unknown.keylayout.vChewingIBM": + return true + case "org.unknown.keylayout.vChewingMiTAC": + return true default: return false } @@ -165,6 +175,8 @@ import Cocoa if (charCode == 65290) {charCode = UniChar(42)} if (charCode == 65288) {charCode = UniChar(40)} if (charCode == 65289) {charCode = UniChar(41)} + // 摁了 Alt 的符號。 + if (charCode == 8212) {charCode = UniChar(45)} // Apple 倚天注音佈局追加符號糾正項目。 if mgrPrefs.basisKeyboardLayout == "com.apple.keylayout.ZhuyinEten" { if (charCode == 65343) {charCode = UniChar(95)} @@ -301,6 +313,8 @@ import Cocoa if (strProcessed == "*") {strProcessed = "*"} if (strProcessed == "(") {strProcessed = "("} if (strProcessed == ")") {strProcessed = ")"} + // 摁了 Alt 的符號。 + if (strProcessed == "—") {strProcessed = "-"} // Apple 倚天注音佈局追加符號糾正項目。 if mgrPrefs.basisKeyboardLayout == "com.apple.keylayout.ZhuyinEten" { if (strProcessed == "_") {strProcessed = "_"} diff --git a/Source/Modules/ControllerModules/KeyHandler.h b/Source/Modules/ControllerModules/KeyHandler.h index 730ab28a..0b3c4cef 100644 --- a/Source/Modules/ControllerModules/KeyHandler.h +++ b/Source/Modules/ControllerModules/KeyHandler.h @@ -19,7 +19,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH #import -@class KeyHandlerInput; +@class keyParser; @class InputState; NS_ASSUME_NONNULL_BEGIN @@ -40,7 +40,7 @@ extern InputMode imeModeNULL; @interface KeyHandler : NSObject - (BOOL)isBuilderEmpty; -- (BOOL)handleInput:(KeyHandlerInput *)input +- (BOOL)handleInput:(keyParser *)input state:(InputState *)state stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback NS_SWIFT_NAME(handle(input:state:stateCallback:errorCallback:)); diff --git a/Source/Modules/ControllerModules/KeyHandler.mm b/Source/Modules/ControllerModules/KeyHandler.mm index 0bdbcd03..5414dd3c 100644 --- a/Source/Modules/ControllerModules/KeyHandler.mm +++ b/Source/Modules/ControllerModules/KeyHandler.mm @@ -260,7 +260,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; return layout; } -- (BOOL)handleInput:(KeyHandlerInput *)input state:(InputState *)inState stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback +- (BOOL)handleInput:(keyParser *)input state:(InputState *)inState stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback { InputState *state = inState; UniChar charCode = input.charCode; @@ -272,7 +272,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; } // if the composing buffer is empty and there's no reading, and there is some function key combination, we ignore it - BOOL isFunctionKey = ([input isCommandHold] || [input isOptionHold] || [input isNumericPad]) || [input isControlHotKey]; + BOOL isFunctionKey = ([input isCommandHold] || [input isOptionHotKey] || [input isNumericPad]) || [input isControlHotKey]; if (![state isKindOfClass:[InputStateNotEmpty class]] && ![state isKindOfClass:[InputStateAssociatedPhrases class]] && isFunctionKey) { @@ -345,7 +345,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; } bool composeReading = false; - BOOL skipBpmfHandling = [input isReservedKey] || [input isControlHold]; + BOOL skipBpmfHandling = [input isReservedKey] || [input isControlHold] || [input isOptionHold]; // MARK: Handle BPMF Keys @@ -562,7 +562,9 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; // if nothing is matched, see if it's a punctuation key for current layout. std::string punctuationNamePrefix; - if ([input isControlHold]) { + if ([input isOptionHold]) { + punctuationNamePrefix = std::string("_alt_punctuation_"); + } else if ([input isControlHold]) { punctuationNamePrefix = std::string("_ctrl_punctuation_"); } else if (mgrPrefs.halfWidthPunctuationEnabled) { punctuationNamePrefix = std::string("_half_punctuation_"); @@ -638,7 +640,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; return YES; } -- (BOOL)_handleBackwardWithState:(InputState *)state input:(KeyHandlerInput *)input stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback +- (BOOL)_handleBackwardWithState:(InputState *)state input:(keyParser *)input stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback { if (![state isKindOfClass:[InputStateInputting class]]) { return NO; @@ -679,7 +681,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; return YES; } -- (BOOL)_handleForwardWithState:(InputState *)state input:(KeyHandlerInput *)input stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback +- (BOOL)_handleForwardWithState:(InputState *)state input:(keyParser *)input stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback { if (![state isKindOfClass:[InputStateInputting class]]) { return NO; @@ -920,7 +922,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; - (BOOL)_handleMarkingState:(InputStateMarking *)state - input:(KeyHandlerInput *)input + input:(keyParser *)input stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback { @@ -992,7 +994,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; - (BOOL)_handleCandidateState:(InputState *)state - input:(KeyHandlerInput *)input + input:(keyParser *)input stateCallback:(void (^)(InputState *))stateCallback errorCallback:(void (^)(void))errorCallback; { @@ -1239,7 +1241,9 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot"; if (mgrPrefs.useSCPCTypingMode) { std::string layout = [self _currentLayout]; std::string punctuationNamePrefix; - if ([input isControlHold]) { + if ([input isOptionHold]) { + punctuationNamePrefix = std::string("_alt_punctuation_"); + } else if ([input isControlHold]) { punctuationNamePrefix = std::string("_ctrl_punctuation_"); } else if (mgrPrefs.halfWidthPunctuationEnabled) { punctuationNamePrefix = std::string("_half_punctuation_"); diff --git a/Source/Modules/ControllerModules/KeyHandlerInput.swift b/Source/Modules/ControllerModules/KeyParser.swift similarity index 97% rename from Source/Modules/ControllerModules/KeyHandlerInput.swift rename to Source/Modules/ControllerModules/KeyParser.swift index f29097fa..36054d5e 100644 --- a/Source/Modules/ControllerModules/KeyHandlerInput.swift +++ b/Source/Modules/ControllerModules/KeyParser.swift @@ -50,7 +50,7 @@ enum CharCode: UInt/*16*/ { // - CharCode is not reliable at all. KeyCode is the most accurate. KeyCode doesn't give a phuque about the character sent through macOS keyboard layouts but only focuses on which physical key is pressed. } -class KeyHandlerInput: NSObject { +class keyParser: NSObject { @objc private (set) var useVerticalMode: Bool @objc private (set) var inputText: String? @objc private (set) var inputTextIgnoringModifiers: String? @@ -134,6 +134,10 @@ class KeyHandlerInput: NSObject { flags.contains([.control]) && inputText?.first?.isLetter ?? false } + @objc var isOptionHotKey: Bool { + flags.contains([.option]) && inputText?.first?.isLetter ?? false + } + @objc var isOptionHold: Bool { flags.contains([.option]) } @@ -146,6 +150,10 @@ class KeyHandlerInput: NSObject { flags.contains([.numericPad]) } + @objc var isFunctionKeyHold: Bool { + flags.contains([.function]) + } + @objc var isReservedKey: Bool { guard let code = KeyCode(rawValue: keyCode) else { return false diff --git a/Source/Modules/IME.swift b/Source/Modules/IME.swift new file mode 100644 index 00000000..5f898e26 --- /dev/null +++ b/Source/Modules/IME.swift @@ -0,0 +1,56 @@ +// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License). +/* +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +1. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +2. 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 above. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +import Cocoa + +@objc public class IME: NSObject { + // 直接在 AppleKeyboardConverter 內使用 KeyParser 判定修飾鍵狀態的話,會出現蛇吞自己尾巴的現象。 + // 所以就藉由 ctlInputMethod 的這幾個常態變數來判斷。 + // 這裡不會列出全部的 modifier flags,只會列出可能會影響符號輸入的 flags、主要用於 AppleKeyboardConverter。 + @objc static var isOptionPressed: Bool = false + @objc static var isShiftPressed: Bool = false + @objc static var isCapsLockOn: Bool = false + @objc static var isCommandPressed: Bool = false + @objc static var isNumericPad: Bool = false + @objc static var isFunction: Bool = false + + // MARK: - Functions + + // Print debug information to the console. + @objc static func prtDebugIntel(_ strPrint: String) { + if mgrPrefs.isDebugModeEnabled { + NSLog("vChewingErrorCallback: %@", strPrint) + } + } + + @objc static func isDarkMode() -> Bool { + if #available(macOS 10.15, *) { + let appearanceDescription = NSApplication.shared.effectiveAppearance.debugDescription.lowercased() + if appearanceDescription.contains("dark") { + return true + } + } else if #available(macOS 10.14, *) { + if let appleInterfaceStyle = UserDefaults.standard.object(forKey: "AppleInterfaceStyle") as? String { + if appleInterfaceStyle.lowercased().contains("dark") { + return true + } + } + } + return false + } +} diff --git a/Source/Modules/IMEModules/ctlInputMethod.swift b/Source/Modules/IMEModules/ctlInputMethod.swift index 6713f2dc..fbb4d106 100644 --- a/Source/Modules/IMEModules/ctlInputMethod.swift +++ b/Source/Modules/IMEModules/ctlInputMethod.swift @@ -55,12 +55,43 @@ class ctlInputMethod: IMKInputController { // 想讓 keyHandler 能夠被外界調查狀態與參數的話,就得對 keyHandler 做常態處理。 // 這樣 InputState 可以藉由這個 ctlInputMethod 了解到當前的輸入模式是簡體中文還是繁體中文。 - // 然而,要是直接對 keyHandler 做常態處理的話,反而會導致 keyHandlerInput 無法協同處理。 + // 然而,要是直接對 keyHandler 做常態處理的話,反而會導致 keyParser 無法協同處理。 // 所以才需要「currentKeyHandler」這個假 keyHandler。 // 這個「currentKeyHandler」僅用來讓其他模組知道當前的輸入模式是什麼模式,除此之外別無屌用。 static var currentKeyHandler: KeyHandler = KeyHandler() @objc static var currentInputMode = "" + // MARK: - Keyboard Layout Specifier + + func getKeyLayoutFlagsCondition(_ event: NSEvent!) -> Bool { + event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(NSEvent.ModifierFlags(rawValue: ~(NSEvent.ModifierFlags.shift.rawValue))) || + (event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.shift) && mgrPrefs.functionKeyKeyboardLayoutOverrideIncludeShiftKey) + } + + @objc func setKeyLayout(isfunctionKeyboardLayout: Bool = false) { + let client = client().self as IMKTextInput + client.overrideKeyboard(withKeyboardNamed: isfunctionKeyboardLayout ? mgrPrefs.functionKeyboardLayout : mgrPrefs.basisKeyboardLayout) + } + + func updateModifierFlags(_ event: NSEvent!) { + // 這裡不會列出全部的 modifier flags,只會列出可能會影響符號輸入的 flags、主要用於 AppleKeyboardConverter。 + IME.isShiftPressed = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.shift) + IME.isOptionPressed = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.option) + IME.isCapsLockOn = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock) + IME.isCommandPressed = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.command) + IME.isNumericPad = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.numericPad) + IME.isFunction = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.function) + } + + func resetModifierFlags() { + IME.isShiftPressed = false + IME.isOptionPressed = false + IME.isCapsLockOn = false + IME.isCommandPressed = false + IME.isNumericPad = false + IME.isFunction = false + } + // MARK: - IMKInputController methods override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) { @@ -133,6 +164,9 @@ class ctlInputMethod: IMKInputController { if optionKeyPressed { menu.addItem(withTitle: NSLocalizedString("Reboot vChewing…", comment: ""), action: #selector(selfTerminate(_:)), keyEquivalent: "") } + + // NSMenu 會阻止任何 modified key 相關的訊號傳回輸入法,所以咱們在此重設鍵盤佈局 + setKeyLayout(isfunctionKeyboardLayout: false) return menu } @@ -141,8 +175,8 @@ class ctlInputMethod: IMKInputController { override func activateServer(_ client: Any!) { UserDefaults.standard.synchronize() - // Override the keyboard layout. Use US if not set. - (client as? IMKTextInput)?.overrideKeyboard(withKeyboardNamed: mgrPrefs.basisKeyboardLayout) + // Override the keyboard layout to the basic one. + setKeyLayout(isfunctionKeyboardLayout: false) // reset the state currentCandidateClient = nil @@ -169,14 +203,17 @@ class ctlInputMethod: IMKInputController { newInputMode = InputMode.imeModeNULL } mgrLangModel.loadDataModel(newInputMode) + + // Remember to override the keyboard layout again -- treat this as an activate event. + setKeyLayout(isfunctionKeyboardLayout: false) + if keyHandler.inputMode != newInputMode { UserDefaults.standard.synchronize() - // Remember to override the keyboard layout again -- treat this as an activate event. - (client as? IMKTextInput)?.overrideKeyboard(withKeyboardNamed: mgrPrefs.basisKeyboardLayout) keyHandler.clear() keyHandler.inputMode = newInputMode self.handle(state: .Empty(), client: client) } + // 讓外界知道目前的簡繁體輸入模式。 ctlInputMethod.currentKeyHandler.inputMode = keyHandler.inputMode } @@ -189,28 +226,24 @@ class ctlInputMethod: IMKInputController { } override func handle(_ event: NSEvent!, client: Any!) -> Bool { + //重設且更新全局共用狀態開關的參數。 + resetModifierFlags() + updateModifierFlags(event) - // 這裡仍舊需要判斷 flags。之前使輸入法狀態卡住無法敲漢字的問題已在 KeyHandler 內修復。 - // 這裡不判斷 flags 的話,用方向鍵前後定位光標之後,再次試圖觸發組字區時、反而會在首次按鍵時失敗。 - // 同時注意:必須將 event.type == .flagsChanged 放在最外圍、且在其結尾插入 return false, - // 否則,每次處理這種判斷時都會觸發 NSInternalInconsistencyException。 - if (mgrPrefs.functionKeyboardLayout != mgrPrefs.basisKeyboardLayout) && (event.type == .flagsChanged) { - let includeShift = mgrPrefs.functionKeyKeyboardLayoutOverrideIncludeShiftKey - if (event.modifierFlags == .capsLock || - event.modifierFlags.contains(.command) || - event.modifierFlags.contains(.option) || - event.modifierFlags.contains(.control) || - event.modifierFlags.contains(.function) || - (event.modifierFlags.contains(.shift) && includeShift)) { - (client as? IMKTextInput)?.overrideKeyboard(withKeyboardNamed: mgrPrefs.functionKeyboardLayout) - } else { - (client as? IMKTextInput)?.overrideKeyboard(withKeyboardNamed: mgrPrefs.basisKeyboardLayout) + if mgrPrefs.functionKeyboardLayout != mgrPrefs.basisKeyboardLayout { + // 這裡仍舊需要判斷 flags。之前使輸入法狀態卡住無法敲漢字的問題已在 KeyHandler 內修復。 + // 這裡不判斷 flags 的話,用方向鍵前後定位光標之後,再次試圖觸發組字區時、反而會在首次按鍵時失敗。 + // 同時注意:必須在 event.type == .flagsChanged 結尾插入 return false, + // 否則,每次處理這種判斷時都會觸發 NSInternalInconsistencyException。 + if event.type == .flagsChanged { + setKeyLayout(isfunctionKeyboardLayout: getKeyLayoutFlagsCondition(event)) + return false } - // 準備修飾鍵,用來判定是否需要利用就地新增語彙時的 Enter 鍵來砍詞。 - ctlInputMethod.areWeDeleting = event.modifierFlags.contains([.shift, .command]) - return false } + // 準備修飾鍵,用來判定是否需要利用就地新增語彙時的 Enter 鍵來砍詞。 + ctlInputMethod.areWeDeleting = event.modifierFlags.contains([.shift, .command]) + var textFrame = NSRect.zero let attributes: [AnyHashable: Any]? = (client as? IMKTextInput)?.attributes(forCharacterIndex: 0, lineHeightRectangle: &textFrame) let useVerticalMode = (attributes?["IMKTextOrientation"] as? NSNumber)?.intValue == 0 || false @@ -221,7 +254,7 @@ class ctlInputMethod: IMKInputController { ctlInputMethod.areWeUsingOurOwnPhraseEditor = false } - let input = KeyHandlerInput(event: event, isVerticalMode: useVerticalMode) + let input = keyParser(event: event, isVerticalMode: useVerticalMode) let result = keyHandler.handle(input: input, state: state) { newState in self.handle(state: newState, client: client) diff --git a/Update-Info.plist b/Update-Info.plist index f5f4c724..98d0431a 100644 --- a/Update-Info.plist +++ b/Update-Info.plist @@ -7,8 +7,8 @@ UpdateInfoSite https://gitee.com/vChewing/vChewing-macOS/releases CFBundleVersion - 1942 + 1943 CFBundleShortVersionString - 1.4.2 + 1.4.3 diff --git a/vChewing.pkgproj b/vChewing.pkgproj index c4d9d51d..a2bf29ec 100644 --- a/vChewing.pkgproj +++ b/vChewing.pkgproj @@ -726,7 +726,7 @@ USE_HFS+_COMPRESSION VERSION - 1.4.2 + 1.4.3 TYPE 0 diff --git a/vChewing.xcodeproj/project.pbxproj b/vChewing.xcodeproj/project.pbxproj index 01fd02fa..59bdecf3 100644 --- a/vChewing.xcodeproj/project.pbxproj +++ b/vChewing.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 5B27AD6B27CB1F9B000ED75B /* data-zhuyinwen.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B27AD6927CB1F9B000ED75B /* data-zhuyinwen.txt */; }; 5B2DB16F27AF6891006D874E /* data-chs.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B2DB16D27AF6891006D874E /* data-chs.txt */; }; 5B2DB17027AF6891006D874E /* data-cht.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5B2DB16E27AF6891006D874E /* data-cht.txt */; }; + 5B5E535227EF261400C6AA1E /* IME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E535127EF261400C6AA1E /* IME.swift */; }; 5B62A32927AE77D100A19448 /* FSEventStreamHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */; }; 5B62A32F27AE78B000A19448 /* CoreLM.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A32D27AE78B000A19448 /* CoreLM.mm */; }; 5B62A33227AE792F00A19448 /* InputSourceHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33127AE792F00A19448 /* InputSourceHelper.swift */; }; @@ -70,7 +71,7 @@ D41355DE278EA3ED005E5CBD /* UserPhrasesLM.mm in Sources */ = {isa = PBXBuildFile; fileRef = D41355DC278EA3ED005E5CBD /* UserPhrasesLM.mm */; }; D427F76C278CA2B0004A2160 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D427F76B278CA1BA004A2160 /* AppDelegate.swift */; }; D44FB74D2792189A003C80A6 /* PhraseReplacementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = D44FB74B2792189A003C80A6 /* PhraseReplacementMap.mm */; }; - D456576E279E4F7B00DF6BC9 /* KeyHandlerInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = D456576D279E4F7B00DF6BC9 /* KeyHandlerInput.swift */; }; + D456576E279E4F7B00DF6BC9 /* KeyParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = D456576D279E4F7B00DF6BC9 /* KeyParser.swift */; }; D461B792279DAC010070E734 /* InputState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D461B791279DAC010070E734 /* InputState.swift */; }; D47B92C027972AD100458394 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D47B92BF27972AC800458394 /* main.swift */; }; D47D73AC27A6CAE600255A50 /* AssociatedPhrases.mm in Sources */ = {isa = PBXBuildFile; fileRef = D47D73AA27A6CAE600255A50 /* AssociatedPhrases.mm */; }; @@ -162,6 +163,7 @@ 5B2DB16E27AF6891006D874E /* data-cht.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "data-cht.txt"; path = "Data/data-cht.txt"; sourceTree = ""; }; 5B2DB17127AF8771006D874E /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Data/Makefile; sourceTree = ""; }; 5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = vChewingKeyLayout.bundle; sourceTree = ""; }; + 5B5E535127EF261400C6AA1E /* IME.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IME.swift; sourceTree = ""; }; 5B62A32627AE77BB00A19448 /* LMConsolidator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LMConsolidator.h; sourceTree = ""; }; 5B62A32727AE77BB00A19448 /* LMConsolidator.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LMConsolidator.mm; sourceTree = ""; }; 5B62A32827AE77D100A19448 /* FSEventStreamHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FSEventStreamHelper.swift; sourceTree = ""; }; @@ -262,7 +264,7 @@ D427F76B278CA1BA004A2160 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; D44FB74B2792189A003C80A6 /* PhraseReplacementMap.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PhraseReplacementMap.mm; sourceTree = ""; }; D44FB74C2792189A003C80A6 /* PhraseReplacementMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PhraseReplacementMap.h; sourceTree = ""; }; - D456576D279E4F7B00DF6BC9 /* KeyHandlerInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyHandlerInput.swift; sourceTree = ""; }; + D456576D279E4F7B00DF6BC9 /* KeyParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyParser.swift; sourceTree = ""; }; D461B791279DAC010070E734 /* InputState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputState.swift; sourceTree = ""; }; D47B92BF27972AC800458394 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; D47D73AA27A6CAE600255A50 /* AssociatedPhrases.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AssociatedPhrases.mm; sourceTree = ""; }; @@ -373,7 +375,7 @@ D461B791279DAC010070E734 /* InputState.swift */, D4E569DA27A34CC100AC2CEF /* KeyHandler.h */, D4E569DB27A34CC100AC2CEF /* KeyHandler.mm */, - D456576D279E4F7B00DF6BC9 /* KeyHandlerInput.swift */, + D456576D279E4F7B00DF6BC9 /* KeyParser.swift */, 6ACC3D3E27914F2400F1B140 /* KeyValueBlobReader.cpp */, 6ACC3D3C27914AAB00F1B140 /* KeyValueBlobReader.h */, 5B62A33727AE79CD00A19448 /* NSStringUtils.swift */, @@ -673,6 +675,7 @@ isa = PBXGroup; children = ( D427F76B278CA1BA004A2160 /* AppDelegate.swift */, + 5B5E535127EF261400C6AA1E /* IME.swift */, D47B92BF27972AC800458394 /* main.swift */, 5B62A31F27AE74E900A19448 /* ControllerModules */, 5B62A32127AE755D00A19448 /* FileHandlers */, @@ -963,7 +966,7 @@ D47F7DD0278C0897002F9DD7 /* ctlNonModalAlertWindow.swift in Sources */, 5B62A32F27AE78B000A19448 /* CoreLM.mm in Sources */, 5BE78BE027B38804005EA1BE /* LMConsolidator.mm in Sources */, - D456576E279E4F7B00DF6BC9 /* KeyHandlerInput.swift in Sources */, + D456576E279E4F7B00DF6BC9 /* KeyParser.swift in Sources */, D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */, D47D73AC27A6CAE600255A50 /* AssociatedPhrases.mm in Sources */, 5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */, @@ -974,6 +977,7 @@ 5B62A33627AE795800A19448 /* mgrPrefs.swift in Sources */, 5B62A33827AE79CD00A19448 /* NSStringUtils.swift in Sources */, 5B62A33227AE792F00A19448 /* InputSourceHelper.swift in Sources */, + 5B5E535227EF261400C6AA1E /* IME.swift in Sources */, 5B62A34927AE7CD900A19448 /* TooltipController.swift in Sources */, 6A0D4F4515FC0EB100ABF4B3 /* Mandarin.cpp in Sources */, 5B62A34827AE7CD900A19448 /* VerticalCandidateController.swift in Sources */, @@ -1179,7 +1183,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1942; + CURRENT_PROJECT_VERSION = 1943; DEBUG_INFORMATION_FORMAT = dwarf; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; @@ -1202,7 +1206,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.4.2; + MARKETING_VERSION = 1.4.3; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor; @@ -1235,7 +1239,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1942; + CURRENT_PROJECT_VERSION = 1943; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1254,7 +1258,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.4.2; + MARKETING_VERSION = 1.4.3; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor; @@ -1369,7 +1373,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1942; + CURRENT_PROJECT_VERSION = 1943; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1404,7 +1408,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.4.2; + MARKETING_VERSION = 1.4.3; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1437,7 +1441,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1942; + CURRENT_PROJECT_VERSION = 1943; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; @@ -1467,7 +1471,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.4.2; + MARKETING_VERSION = 1.4.3; PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1551,7 +1555,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1942; + CURRENT_PROJECT_VERSION = 1943; DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; @@ -1576,7 +1580,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.4.2; + MARKETING_VERSION = 1.4.3; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1604,7 +1608,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1942; + CURRENT_PROJECT_VERSION = 1943; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1624,7 +1628,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.11.5; - MARKETING_VERSION = 1.4.2; + MARKETING_VERSION = 1.4.3; PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "";