Skip to content

Commit

Permalink
Merge pull request #644 from jeemyeong/toggle_layout_with_right_gui
Browse files Browse the repository at this point in the history
Feat: toggle layout with right gui key
  • Loading branch information
youknowone committed Oct 20, 2019
2 parents b2ce89b + dc8209e commit cfa5d0a
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 25 deletions.
13 changes: 13 additions & 0 deletions OSXCore/Configuration.swift
Expand Up @@ -39,6 +39,8 @@ enum ConfigurationName {
static let hangulNonChoseongCombination = "HangulNonChoseongCombination"
/// 세벌식 정석 강요.
static let hangulForceStrictCombinationRule = "HangulForceStrictCombinationRule"
/// 우측 커맨드 키로 언어 전환
static let switchLanguageForRightGui = "SwitchLanguageForRightGui"
}

// MARK: - Configuration 클래스
Expand Down Expand Up @@ -84,6 +86,7 @@ public class Configuration: UserDefaults {
ConfigurationName.hangulAutoReorder: false,
ConfigurationName.hangulNonChoseongCombination: false,
ConfigurationName.hangulForceStrictCombinationRule: false,
ConfigurationName.switchLanguageForRightGui: false,
])
}

Expand Down Expand Up @@ -224,6 +227,16 @@ public class Configuration: UserDefaults {
`set`(newValue, forKey: ConfigurationName.hangulForceStrictCombinationRule)
}
}

/// 우측 커맨드 키로 언어 전환
var switchLanguageForRightGui: Bool {
get {
return bool(forKey: ConfigurationName.switchLanguageForRightGui)
}
set {
`set`(newValue, forKey: ConfigurationName.switchLanguageForRightGui)
}
}
}

private extension Configuration {
Expand Down
7 changes: 7 additions & 0 deletions OSXCore/InputController.swift
Expand Up @@ -37,6 +37,7 @@ struct InputResult: Equatable {
enum ChangeLayout {
case toggle
case toggleByCapsLock
case toggleByRightGui
case hangul
case roman
case search
Expand Down Expand Up @@ -143,6 +144,12 @@ public extension InputController { // IMKServerInputHandleEvent
}
}

if InputMethodServer.shared.io.resolveRightGuiPressed() {
let result = receiver.input(event: .changeLayout(.toggleByRightGui, true), client: client)
dlog(DEBUG_IOKIT_EVENT, "controller detected right gui")
return result.processed
}

dlog(DEBUG_LOGGING, "LOGGING::UNHANDLED::%@/%@", event, sender as! NSObject)
dlog(DEBUG_INPUTCONTROLLER, "** InputController -handleEvent:client: with event: %@ / sender: %@", event, sender as! NSObject)
return false
Expand Down
41 changes: 41 additions & 0 deletions OSXCore/InputMethodServer.swift
Expand Up @@ -47,9 +47,11 @@ class IOKitty {
let service: SIOService
let connect: SIOConnect
let manager: IOHIDManager
let rightGuiManager: IOHIDManager
private var defaultCapsLockState: Bool = false
var capsLockDate: Date?
var rollback: (() -> Void)?
var rightGuiPressed = false

init?() {
guard let _service = SIOService(name: kIOHIDSystemClass) else {
Expand All @@ -67,6 +69,10 @@ class IOKitty {
manager.setDeviceMatching(page: kHIDPage_GenericDesktop, usage: kHIDUsage_GD_Keyboard)
manager.setInputValueMatching(min: kHIDUsage_KeyboardCapsLock, max: kHIDUsage_KeyboardCapsLock)

rightGuiManager = IOHIDManager.create()
rightGuiManager.setDeviceMatching(page: kHIDPage_GenericDesktop, usage: kHIDUsage_GD_Keyboard)
rightGuiManager.setInputValueMatching(min: kHIDUsage_KeyboardRightGUI, max: kHIDUsage_KeyboardRightGUI)

let _self = Unmanaged.passUnretained(self)
// Set input value callback
manager.registerInputValueCallback({
Expand Down Expand Up @@ -105,13 +111,40 @@ class IOKitty {
if r != kIOReturnSuccess {
dlog(DEBUG_IOKIT_EVENT, "IOHIDManagerOpen failed")
}

rightGuiManager.registerInputValueCallback({
inContext, _, _, value in
guard Configuration.shared.switchLanguageForRightGui else {
return
}
guard let inContext = inContext else {
dlog(true, "IOKit callback inContext is nil - impossible")
return
}
let pressed = value.integerValue > 0
dlog(DEBUG_IOKIT_EVENT, "right gui pressed: \(pressed)")
let _self = Unmanaged<IOKitty>.fromOpaque(inContext).takeUnretainedValue()
if pressed {
_self.rightGuiPressed = true
dlog(DEBUG_IOKIT_EVENT, "right gui pressed set in context")
}

}, context: _self.toOpaque())

rightGuiManager.schedule(runloop: .current, mode: .default)
if rightGuiManager.open() != kIOReturnSuccess {
dlog(DEBUG_IOKIT_EVENT, "IOHIDManagerOpen failed")
}
}

deinit {
manager.unschedule(runloop: .current, mode: .default)
manager.unregisterInputValueCallback()
let r = manager.close()
assert(r == 0)
rightGuiManager.unschedule(runloop: .current, mode: .default)
rightGuiManager.unregisterInputValueCallback()
assert(rightGuiManager.close() == 0)
}

var capsLockTriggered: Bool {
Expand All @@ -123,6 +156,14 @@ class IOKitty {
dlog(DEBUG_IOKIT_EVENT, " triggered: interval \(interval)")
return interval < 0.5
}

func resolveRightGuiPressed() -> Bool {
if !rightGuiPressed {
return false
}
rightGuiPressed = false
return true
}
}

/*!
Expand Down
2 changes: 1 addition & 1 deletion OSXCore/InputReceiver.swift
Expand Up @@ -134,7 +134,7 @@ public class InputReceiver: InputTextDelegate {
func input(event: InputEvent, client sender: IMKTextInput & IMKUnicodeTextInput) -> InputResult {
switch event {
case let .changeLayout(layout, processed):
let innerLayout = layout == .toggleByCapsLock ? .toggle : layout
let innerLayout = layout == .toggleByCapsLock || layout == .toggleByRightGui ? .toggle : layout
let result = composer.changeLayout(innerLayout, client: sender)
// 합성 후보가 있다면 보여준다
InputMethodServer.shared.showOrHideCandidates(controller: controller)
Expand Down

0 comments on commit cfa5d0a

Please sign in to comment.