IMKCandidates // Move its key handling process to ctlIME.
This commit is contained in:
parent
7c3d90dc80
commit
0ce0604c16
|
@ -25,8 +25,6 @@ public class CandidateKeyLabel: NSObject {
|
|||
}
|
||||
|
||||
public protocol ctlCandidateDelegate: AnyObject {
|
||||
var isAssociatedPhrasesState: Bool { get }
|
||||
func sharedEventHandler(_ event: NSEvent) -> Bool
|
||||
func candidateCountForController(_ controller: ctlCandidateProtocol) -> Int
|
||||
func candidatesForController(_ controller: ctlCandidateProtocol) -> [(String, String)]
|
||||
func ctlCandidate(_ controller: ctlCandidateProtocol, candidateAtIndex index: Int)
|
||||
|
|
|
@ -185,74 +185,6 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
|
|||
|
||||
setCandidateFrameTopLeft(adjustedPoint)
|
||||
}
|
||||
|
||||
override public func interpretKeyEvents(_ eventArray: [NSEvent]) {
|
||||
// 鬼知道為什麼這個函式接收的參數是陣列,但經過測試卻發現這個函式收到的陣列往往內容只有一個。
|
||||
// 這也可能是 Objective-C 當中允許接收內容為 nil 的一種方式。
|
||||
guard !eventArray.isEmpty else { return }
|
||||
let event = eventArray[0]
|
||||
guard let delegate = delegate else { return }
|
||||
if event.isEsc || event.isBackSpace || event.isDelete || (event.isShiftHold && !event.isSpace) {
|
||||
_ = delegate.sharedEventHandler(event)
|
||||
} else if event.isSymbolMenuPhysicalKey {
|
||||
// 符號鍵的行為是固定的,不受偏好設定影響。
|
||||
switch currentLayout {
|
||||
case .horizontal: event.isShiftHold ? moveUp(self) : moveDown(self)
|
||||
case .vertical: event.isShiftHold ? moveLeft(self) : moveRight(self)
|
||||
}
|
||||
} else if event.isSpace {
|
||||
switch PrefMgr.shared.specifyShiftSpaceKeyBehavior {
|
||||
case true: _ = event.isShiftHold ? highlightNextCandidate() : showNextPage()
|
||||
case false: _ = event.isShiftHold ? showNextPage() : highlightNextCandidate()
|
||||
}
|
||||
} else if event.isTab {
|
||||
switch PrefMgr.shared.specifyShiftTabKeyBehavior {
|
||||
case true: _ = event.isShiftHold ? showPreviousPage() : showNextPage()
|
||||
case false: _ = event.isShiftHold ? highlightPreviousCandidate() : highlightNextCandidate()
|
||||
}
|
||||
} else {
|
||||
if let newChar = Self.defaultIMKSelectionKey[event.keyCode] {
|
||||
/// 根據 KeyCode 重新換算一下選字鍵的 NSEvent,糾正其 Character 數值。
|
||||
/// 反正 IMK 選字窗目前也沒辦法修改選字鍵。
|
||||
let newEvent = event.reinitiate(characters: newChar)
|
||||
if let newEvent = newEvent {
|
||||
if PrefMgr.shared.useSCPCTypingMode, delegate.isAssociatedPhrasesState {
|
||||
// 註:input.isShiftHold 已經在 ctlInputMethod.handle() 內處理,因為在那邊處理才有效。
|
||||
if !event.isShiftHold {
|
||||
_ = delegate.sharedEventHandler(event)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if #available(macOS 10.14, *) {
|
||||
handleKeyboardEvent(newEvent)
|
||||
} else {
|
||||
super.interpretKeyEvents([newEvent])
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if PrefMgr.shared.useSCPCTypingMode, !event.isReservedKey {
|
||||
_ = delegate.sharedEventHandler(event)
|
||||
return
|
||||
}
|
||||
|
||||
if delegate.isAssociatedPhrasesState,
|
||||
!event.isPageUp, !event.isPageDown, !event.isCursorForward, !event.isCursorBackward,
|
||||
!event.isCursorClockLeft, !event.isCursorClockRight, !event.isSpace,
|
||||
!event.isEnter || !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter
|
||||
{
|
||||
_ = delegate.sharedEventHandler(event)
|
||||
return
|
||||
}
|
||||
super.interpretKeyEvents(eventArray)
|
||||
}
|
||||
}
|
||||
|
||||
public func superInterpretKeyEvents(_ eventArray: [NSEvent]) {
|
||||
super.interpretKeyEvents(eventArray)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Generate TISInputSource Object
|
||||
|
|
|
@ -322,7 +322,7 @@ class ctlInputMethod: IMKInputController {
|
|||
Self.areWeNerfing = eventToDeal.modifierFlags.contains([.shift, .command])
|
||||
|
||||
// IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。
|
||||
if let result = imkCandidatesEventHandler(event: eventToDeal) {
|
||||
if let result = imkCandidatesEventPreHandler(event: eventToDeal) {
|
||||
if shouldUseShiftToggleHandle {
|
||||
rencentKeyHandledByKeyHandlerEtc = result
|
||||
}
|
||||
|
|
|
@ -50,17 +50,6 @@ extension ctlInputMethod: KeyHandlerDelegate {
|
|||
// MARK: - Candidate Controller Delegate
|
||||
|
||||
extension ctlInputMethod: ctlCandidateDelegate {
|
||||
var isAssociatedPhrasesState: Bool { state.type == .ofAssociates }
|
||||
|
||||
/// 完成 handle() 函式本該完成的內容,但去掉了與 IMK 選字窗有關的判斷語句。
|
||||
/// 這樣分開處理很有必要,不然 handle() 函式會陷入無限迴圈。
|
||||
/// 該函式僅由 IMK 選字窗來存取,且對接給 commonEventHandler()。
|
||||
/// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。
|
||||
/// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。
|
||||
@discardableResult func sharedEventHandler(_ event: NSEvent) -> Bool {
|
||||
commonEventHandler(event)
|
||||
}
|
||||
|
||||
func candidateCountForController(_ controller: ctlCandidateProtocol) -> Int {
|
||||
_ = controller // 防止格式整理工具毀掉與此對應的參數。
|
||||
if state.isCandidateContainer {
|
||||
|
|
|
@ -37,10 +37,10 @@ extension ctlInputMethod {
|
|||
/// 這樣分開處理很有必要,不然 handle() 函式會陷入無限迴圈。
|
||||
/// - Parameter event: 由 IMK 選字窗接收的裝置操作輸入事件。
|
||||
/// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。
|
||||
func imkCandidatesEventHandler(event eventToDeal: NSEvent) -> Bool? {
|
||||
func imkCandidatesEventPreHandler(event eventToDeal: NSEvent) -> Bool? {
|
||||
// IMK 選字窗處理,當且僅當啟用了 IMK 選字窗的時候才會生效。
|
||||
// 這樣可以讓 interpretKeyEvents() 函式自行判斷:
|
||||
// - 是就地交給 super.interpretKeyEvents() 處理?
|
||||
// - 是就地交給 imkCandidates.interpretKeyEvents() 處理?
|
||||
// - 還是藉由 delegate 扔回 ctlInputMethod 給 KeyHandler 處理?
|
||||
if let imkCandidates = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK, imkCandidates.visible {
|
||||
let event: NSEvent = ctlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal
|
||||
|
@ -52,25 +52,85 @@ extension ctlInputMethod {
|
|||
NSSound.beep()
|
||||
return true
|
||||
}
|
||||
imkCandidates.interpretKeyEvents([newEvent])
|
||||
return true
|
||||
|
||||
return imkCandidatesEventSubHandler(event: newEvent)
|
||||
}
|
||||
|
||||
// 聯想詞選字。
|
||||
if let newChar = ctlCandidateIMK.defaultIMKSelectionKey[event.keyCode],
|
||||
event.isShiftHold, isAssociatedPhrasesState,
|
||||
event.isShiftHold, state.type == .ofAssociates,
|
||||
let newEvent = event.reinitiate(modifierFlags: [], characters: newChar)
|
||||
{
|
||||
if #available(macOS 10.14, *) {
|
||||
imkCandidates.handleKeyboardEvent(newEvent)
|
||||
} else {
|
||||
imkCandidates.superInterpretKeyEvents([newEvent])
|
||||
imkCandidates.interpretKeyEvents([newEvent])
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
imkCandidates.interpretKeyEvents([event])
|
||||
return true
|
||||
return imkCandidatesEventSubHandler(event: event)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func imkCandidatesEventSubHandler(event: NSEvent) -> Bool {
|
||||
let eventArray = [event]
|
||||
guard let imkC = Self.ctlCandidateCurrent as? ctlCandidateIMK else { return false }
|
||||
if event.isEsc || event.isBackSpace || event.isDelete || (event.isShiftHold && !event.isSpace) {
|
||||
return commonEventHandler(event)
|
||||
} else if event.isSymbolMenuPhysicalKey {
|
||||
// 符號鍵的行為是固定的,不受偏好設定影響。
|
||||
switch imkC.currentLayout {
|
||||
case .horizontal: _ = event.isShiftHold ? imkC.moveUp(self) : imkC.moveDown(self)
|
||||
case .vertical: _ = event.isShiftHold ? imkC.moveLeft(self) : imkC.moveRight(self)
|
||||
}
|
||||
return true
|
||||
} else if event.isSpace {
|
||||
switch PrefMgr.shared.specifyShiftSpaceKeyBehavior {
|
||||
case true: _ = event.isShiftHold ? imkC.highlightNextCandidate() : imkC.showNextPage()
|
||||
case false: _ = event.isShiftHold ? imkC.showNextPage() : imkC.highlightNextCandidate()
|
||||
}
|
||||
return true
|
||||
} else if event.isTab {
|
||||
switch PrefMgr.shared.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 PrefMgr.shared.useSCPCTypingMode, state.type == .ofAssociates {
|
||||
// 註:input.isShiftHold 已經在 ctlInputMethod.handle() 內處理,因為在那邊處理才有效。
|
||||
return event.isShiftHold ? true : commonEventHandler(event)
|
||||
} else {
|
||||
if #available(macOS 10.14, *) {
|
||||
imkC.handleKeyboardEvent(newEvent)
|
||||
} else {
|
||||
imkC.interpretKeyEvents([newEvent])
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if PrefMgr.shared.useSCPCTypingMode, !event.isReservedKey {
|
||||
return commonEventHandler(event)
|
||||
}
|
||||
|
||||
if state.type == .ofAssociates,
|
||||
!event.isPageUp, !event.isPageDown, !event.isCursorForward, !event.isCursorBackward,
|
||||
!event.isCursorClockLeft, !event.isCursorClockRight, !event.isSpace,
|
||||
!event.isEnter || !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter
|
||||
{
|
||||
return commonEventHandler(event)
|
||||
}
|
||||
imkC.interpretKeyEvents(eventArray)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue