KeyHandlerInput // Implementing Apple On-Screen Keyboard Support.
This commit is contained in:
parent
7e8f770b20
commit
ae24a779a1
|
@ -0,0 +1,175 @@
|
|||
// 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 class AppleKeyboardConverter: NSObject {
|
||||
@objc class func isDynamicBaseKeyboardLayoutEnabled() -> Bool {
|
||||
switch Preferences.basisKeyboardLayout {
|
||||
case "com.apple.keylayout.ZhuyinBopomofo":
|
||||
return true
|
||||
case "com.apple.keylayout.ZhuyinEten":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
// 處理 Apple 注音鍵盤佈局類型
|
||||
@objc class func cnvApple2ABC(_ charCode: UniChar) -> UniChar {
|
||||
var charCode = charCode
|
||||
// 在按鍵資訊被送往 OVMandarin 之前,先轉換為可以被 OVMandarin 正常處理的資訊。
|
||||
if self.isDynamicBaseKeyboardLayoutEnabled() {
|
||||
// 保證 Apple 大千佈局內的符號鍵正常工作
|
||||
if charCode == 45 && (Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinBopomofo") { charCode = UniChar(96) }
|
||||
if charCode == 183 && (Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinEten") { charCode = UniChar(96) }
|
||||
// 注音鍵群。
|
||||
if (charCode == 12573) {charCode = UniChar(44)}
|
||||
if (charCode == 12582) {charCode = UniChar(45)}
|
||||
if (charCode == 12577) {charCode = UniChar(46)}
|
||||
if (charCode == 12581) {charCode = UniChar(47)}
|
||||
if (charCode == 12578) {charCode = UniChar(48)}
|
||||
if (charCode == 12549) {charCode = UniChar(49)}
|
||||
if (charCode == 12553) {charCode = UniChar(50)}
|
||||
if (charCode == 711) {charCode = UniChar(51)}
|
||||
if (charCode == 715) {charCode = UniChar(52)}
|
||||
if (charCode == 12563) {charCode = UniChar(53)}
|
||||
if (charCode == 714) {charCode = UniChar(54)}
|
||||
if (charCode == 729) {charCode = UniChar(55)}
|
||||
if (charCode == 12570) {charCode = UniChar(56)}
|
||||
if (charCode == 12574) {charCode = UniChar(57)}
|
||||
if (charCode == 12580) {charCode = UniChar(59)}
|
||||
if (charCode == 12551) {charCode = UniChar(97)}
|
||||
if (charCode == 12566) {charCode = UniChar(98)}
|
||||
if (charCode == 12559) {charCode = UniChar(99)}
|
||||
if (charCode == 12558) {charCode = UniChar(100)}
|
||||
if (charCode == 12557) {charCode = UniChar(101)}
|
||||
if (charCode == 12561) {charCode = UniChar(102)}
|
||||
if (charCode == 12565) {charCode = UniChar(103)}
|
||||
if (charCode == 12568) {charCode = UniChar(104)}
|
||||
if (charCode == 12571) {charCode = UniChar(105)}
|
||||
if (charCode == 12584) {charCode = UniChar(106)}
|
||||
if (charCode == 12572) {charCode = UniChar(107)}
|
||||
if (charCode == 12576) {charCode = UniChar(108)}
|
||||
if (charCode == 12585) {charCode = UniChar(109)}
|
||||
if (charCode == 12569) {charCode = UniChar(110)}
|
||||
if (charCode == 12575) {charCode = UniChar(111)}
|
||||
if (charCode == 12579) {charCode = UniChar(112)}
|
||||
if (charCode == 12550) {charCode = UniChar(113)}
|
||||
if (charCode == 12560) {charCode = UniChar(114)}
|
||||
if (charCode == 12555) {charCode = UniChar(115)}
|
||||
if (charCode == 12564) {charCode = UniChar(116)}
|
||||
if (charCode == 12583) {charCode = UniChar(117)}
|
||||
if (charCode == 12562) {charCode = UniChar(118)}
|
||||
if (charCode == 12554) {charCode = UniChar(119)}
|
||||
if (charCode == 12556) {charCode = UniChar(120)}
|
||||
if (charCode == 12567) {charCode = UniChar(121)}
|
||||
if (charCode == 12552) {charCode = UniChar(122)}
|
||||
// 除了數字鍵區以外的標點符號。
|
||||
if (charCode == 12289) {charCode = UniChar(92)}
|
||||
if (charCode == 12300) {charCode = UniChar(91)}
|
||||
if (charCode == 12301) {charCode = UniChar(93)}
|
||||
if (charCode == 12302) {charCode = UniChar(123)}
|
||||
if (charCode == 12303) {charCode = UniChar(125)}
|
||||
if (charCode == 65292) {charCode = UniChar(60)}
|
||||
if (charCode == 12290) {charCode = UniChar(62)}
|
||||
// 摁了 SHIFT 之後的數字區的符號。
|
||||
if (charCode == 65281) {charCode = UniChar(33)}
|
||||
if (charCode == 65312) {charCode = UniChar(64)}
|
||||
if (charCode == 65283) {charCode = UniChar(35)}
|
||||
if (charCode == 65284) {charCode = UniChar(36)}
|
||||
if (charCode == 65285) {charCode = UniChar(37)}
|
||||
if (charCode == 65087) {charCode = UniChar(94)}
|
||||
if (charCode == 65286) {charCode = UniChar(38)}
|
||||
if (charCode == 65290) {charCode = UniChar(42)}
|
||||
if (charCode == 65288) {charCode = UniChar(40)}
|
||||
if (charCode == 65289) {charCode = UniChar(41)}
|
||||
}
|
||||
return charCode
|
||||
}
|
||||
|
||||
@objc class func cnvStringApple2ABC(_ strProcessed: String) -> String {
|
||||
var strProcessed = strProcessed
|
||||
if self.isDynamicBaseKeyboardLayoutEnabled() {
|
||||
// 保證 Apple 大千佈局內的符號鍵正常工作
|
||||
if (strProcessed == "-" && Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinBopomofo") { strProcessed = "`" }
|
||||
if (strProcessed == "·" && Preferences.basisKeyboardLayout == "com.apple.keylayout.ZhuyinEten") { strProcessed = "`" }
|
||||
// 注音鍵群。
|
||||
if (strProcessed == "ㄝ") {strProcessed = ","}
|
||||
if (strProcessed == "ㄦ") {strProcessed = "-"}
|
||||
if (strProcessed == "ㄡ") {strProcessed = "."}
|
||||
if (strProcessed == "ㄥ") {strProcessed = "/"}
|
||||
if (strProcessed == "ㄢ") {strProcessed = "0"}
|
||||
if (strProcessed == "ㄅ") {strProcessed = "1"}
|
||||
if (strProcessed == "ㄉ") {strProcessed = "2"}
|
||||
if (strProcessed == "ˇ") {strProcessed = "3"}
|
||||
if (strProcessed == "ˋ") {strProcessed = "4"}
|
||||
if (strProcessed == "ㄓ") {strProcessed = "5"}
|
||||
if (strProcessed == "ˊ") {strProcessed = "6"}
|
||||
if (strProcessed == "˙") {strProcessed = "7"}
|
||||
if (strProcessed == "ㄚ") {strProcessed = "8"}
|
||||
if (strProcessed == "ㄞ") {strProcessed = "9"}
|
||||
if (strProcessed == "ㄤ") {strProcessed = ";"}
|
||||
if (strProcessed == "ㄇ") {strProcessed = "a"}
|
||||
if (strProcessed == "ㄖ") {strProcessed = "b"}
|
||||
if (strProcessed == "ㄏ") {strProcessed = "c"}
|
||||
if (strProcessed == "ㄎ") {strProcessed = "d"}
|
||||
if (strProcessed == "ㄍ") {strProcessed = "e"}
|
||||
if (strProcessed == "ㄑ") {strProcessed = "f"}
|
||||
if (strProcessed == "ㄕ") {strProcessed = "g"}
|
||||
if (strProcessed == "ㄘ") {strProcessed = "h"}
|
||||
if (strProcessed == "ㄛ") {strProcessed = "i"}
|
||||
if (strProcessed == "ㄨ") {strProcessed = "j"}
|
||||
if (strProcessed == "ㄜ") {strProcessed = "k"}
|
||||
if (strProcessed == "ㄠ") {strProcessed = "l"}
|
||||
if (strProcessed == "ㄩ") {strProcessed = "m"}
|
||||
if (strProcessed == "ㄙ") {strProcessed = "n"}
|
||||
if (strProcessed == "ㄟ") {strProcessed = "o"}
|
||||
if (strProcessed == "ㄣ") {strProcessed = "p"}
|
||||
if (strProcessed == "ㄆ") {strProcessed = "q"}
|
||||
if (strProcessed == "ㄐ") {strProcessed = "r"}
|
||||
if (strProcessed == "ㄋ") {strProcessed = "s"}
|
||||
if (strProcessed == "ㄔ") {strProcessed = "t"}
|
||||
if (strProcessed == "ㄧ") {strProcessed = "u"}
|
||||
if (strProcessed == "ㄒ") {strProcessed = "v"}
|
||||
if (strProcessed == "ㄊ") {strProcessed = "w"}
|
||||
if (strProcessed == "ㄌ") {strProcessed = "x"}
|
||||
if (strProcessed == "ㄗ") {strProcessed = "y"}
|
||||
if (strProcessed == "ㄈ") {strProcessed = "z"}
|
||||
// 除了數字鍵區以外的標點符號。
|
||||
if (strProcessed == "、") {strProcessed = "\\"}
|
||||
if (strProcessed == "「") {strProcessed = "["}
|
||||
if (strProcessed == "」") {strProcessed = "]"}
|
||||
if (strProcessed == "『") {strProcessed = "{"}
|
||||
if (strProcessed == "』") {strProcessed = "}"}
|
||||
if (strProcessed == ",") {strProcessed = "<"}
|
||||
if (strProcessed == "。") {strProcessed = ">"}
|
||||
// 摁了 SHIFT 之後的數字區的符號。
|
||||
if (strProcessed == "!") {strProcessed = "!"}
|
||||
if (strProcessed == "@") {strProcessed = "@"}
|
||||
if (strProcessed == "#") {strProcessed = "#"}
|
||||
if (strProcessed == "$") {strProcessed = "$"}
|
||||
if (strProcessed == "%") {strProcessed = "%"}
|
||||
if (strProcessed == "︿") {strProcessed = "^"}
|
||||
if (strProcessed == "&") {strProcessed = "&"}
|
||||
if (strProcessed == "*") {strProcessed = "*"}
|
||||
if (strProcessed == "(") {strProcessed = "("}
|
||||
if (strProcessed == ")") {strProcessed = ")"}
|
||||
}
|
||||
return strProcessed
|
||||
}
|
||||
}
|
|
@ -48,13 +48,15 @@ class KeyHandlerInput: NSObject {
|
|||
@objc private (set) var emacsKey: vChewingEmacsKey
|
||||
|
||||
@objc init(inputText: String?, keyCode: UInt16, charCode: UInt16, flags: NSEvent.ModifierFlags, isVerticalMode: Bool, inputTextIgnoringModifiers: String? = nil) {
|
||||
let inputText = AppleKeyboardConverter.cnvStringApple2ABC(inputText ?? "")
|
||||
let inputTextIgnoringModifiers = AppleKeyboardConverter.cnvStringApple2ABC(inputTextIgnoringModifiers ?? inputText)
|
||||
self.inputText = inputText
|
||||
self.inputTextIgnoringModifiers = inputTextIgnoringModifiers ?? inputText
|
||||
self.inputTextIgnoringModifiers = inputTextIgnoringModifiers
|
||||
self.keyCode = keyCode
|
||||
self.charCode = charCode
|
||||
self.charCode = AppleKeyboardConverter.cnvApple2ABC(charCode)
|
||||
self.flags = flags
|
||||
useVerticalMode = isVerticalMode
|
||||
emacsKey = EmacsKeyHelper.detect(charCode: charCode, flags: flags)
|
||||
emacsKey = EmacsKeyHelper.detect(charCode: AppleKeyboardConverter.cnvApple2ABC(charCode), flags: flags)
|
||||
cursorForwardKey = useVerticalMode ? .down : .right
|
||||
cursorBackwardKey = useVerticalMode ? .up : .left
|
||||
extraChooseCandidateKey = useVerticalMode ? .left : .down
|
||||
|
@ -64,8 +66,8 @@ class KeyHandlerInput: NSObject {
|
|||
}
|
||||
|
||||
@objc init(event: NSEvent, isVerticalMode: Bool) {
|
||||
inputText = event.characters
|
||||
inputTextIgnoringModifiers = event.charactersIgnoringModifiers
|
||||
inputText = AppleKeyboardConverter.cnvStringApple2ABC(event.characters ?? "")
|
||||
inputTextIgnoringModifiers = AppleKeyboardConverter.cnvStringApple2ABC(event.charactersIgnoringModifiers ?? "")
|
||||
keyCode = event.keyCode
|
||||
flags = event.modifierFlags
|
||||
useVerticalMode = isVerticalMode
|
||||
|
@ -76,8 +78,8 @@ class KeyHandlerInput: NSObject {
|
|||
let first = inputText[inputText.startIndex].utf16.first!
|
||||
return first
|
||||
}()
|
||||
self.charCode = charCode
|
||||
emacsKey = EmacsKeyHelper.detect(charCode: charCode, flags: event.modifierFlags)
|
||||
self.charCode = AppleKeyboardConverter.cnvApple2ABC(charCode)
|
||||
emacsKey = EmacsKeyHelper.detect(charCode: AppleKeyboardConverter.cnvApple2ABC(charCode), flags: event.modifierFlags)
|
||||
cursorForwardKey = useVerticalMode ? .down : .right
|
||||
cursorBackwardKey = useVerticalMode ? .up : .left
|
||||
extraChooseCandidateKey = useVerticalMode ? .left : .down
|
||||
|
@ -87,6 +89,9 @@ class KeyHandlerInput: NSObject {
|
|||
}
|
||||
|
||||
override var description: String {
|
||||
charCode = AppleKeyboardConverter.cnvApple2ABC(charCode)
|
||||
inputText = AppleKeyboardConverter.cnvStringApple2ABC(inputText ?? "")
|
||||
inputTextIgnoringModifiers = AppleKeyboardConverter.cnvStringApple2ABC(inputTextIgnoringModifiers ?? "")
|
||||
return "<\(super.description) inputText:\(String(describing: inputText)), inputTextIgnoringModifiers:\(String(describing: inputTextIgnoringModifiers)) charCode:\(charCode), keyCode:\(keyCode), flags:\(flags), cursorForwardKey:\(cursorForwardKey), cursorBackwardKey:\(cursorBackwardKey), extraChooseCandidateKey:\(extraChooseCandidateKey), absorbedArrowKey:\(absorbedArrowKey), verticalModeOnlyChooseCandidateKey:\(verticalModeOnlyChooseCandidateKey), emacsKey:\(emacsKey), useVerticalMode:\(useVerticalMode)>"
|
||||
}
|
||||
|
||||
|
@ -199,6 +204,7 @@ class KeyHandlerInput: NSObject {
|
|||
|
||||
class EmacsKeyHelper: NSObject {
|
||||
@objc static func detect(charCode: UniChar, flags: NSEvent.ModifierFlags) -> vChewingEmacsKey {
|
||||
let charCode = AppleKeyboardConverter.cnvApple2ABC(charCode)
|
||||
if flags.contains(.control) {
|
||||
return vChewingEmacsKey(rawValue: charCode) ?? .none
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
/* Begin PBXBuildFile section */
|
||||
5B0AF8B527B2C8290096FE54 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0AF8B427B2C8290096FE54 /* StringExtension.swift */; };
|
||||
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */; };
|
||||
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 */; };
|
||||
5B62A31727AE73A700A19448 /* unzip.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A30927AE73A700A19448 /* unzip.m */; };
|
||||
|
@ -137,6 +138,7 @@
|
|||
5B05A47F27AFF84200437698 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/frmAboutWindow.strings; sourceTree = "<group>"; };
|
||||
5B0AF8B427B2C8290096FE54 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
|
||||
5B0CF37F27AD476E00784B08 /* SwiftyOpenCC */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = SwiftyOpenCC; path = Packages/SwiftyOpenCC; sourceTree = "<group>"; };
|
||||
5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleKeyboardConverter.swift; sourceTree = "<group>"; };
|
||||
5B2DB16D27AF6891006D874E /* data-chs.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "data-chs.txt"; path = "Data/data-chs.txt"; sourceTree = "<group>"; };
|
||||
5B2DB16E27AF6891006D874E /* data-cht.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "data-cht.txt"; path = "Data/data-cht.txt"; sourceTree = "<group>"; };
|
||||
5B2DB17127AF8771006D874E /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Data/Makefile; sourceTree = "<group>"; };
|
||||
|
@ -361,6 +363,7 @@
|
|||
5B62A31F27AE74E900A19448 /* ControllerModules */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */,
|
||||
D4E569DA27A34CC100AC2CEF /* KeyHandler.h */,
|
||||
D4E569DB27A34CC100AC2CEF /* KeyHandler.mm */,
|
||||
D456576D279E4F7B00DF6BC9 /* KeyHandlerInput.swift */,
|
||||
|
@ -930,6 +933,7 @@
|
|||
D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */,
|
||||
D47D73AC27A6CAE600255A50 /* AssociatedPhrases.mm in Sources */,
|
||||
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */,
|
||||
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */,
|
||||
5B62A31827AE73A700A19448 /* zip.m in Sources */,
|
||||
5B62A32E27AE78B000A19448 /* CNSLM.mm in Sources */,
|
||||
D41355DB278E6D17005E5CBD /* vChewingLM.mm in Sources */,
|
||||
|
|
Loading…
Reference in New Issue