Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

캡스락 활성화 #19

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions SokIM.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@
DF9286C126F5CFAE00002080 = {
isa = PBXGroup;
children = (
DF9286CC26F5CFAE00002080 /* SokIM */,
DF9286CB26F5CFAE00002080 /* Products */,
DF9286CC26F5CFAE00002080 /* SokIM */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -378,7 +378,7 @@
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 18;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = MHKL47BD47;
DEVELOPMENT_TEAM = 3SC5M9PT96;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "$(SRCROOT)/SokIM/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
Expand Down Expand Up @@ -407,7 +407,7 @@
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 18;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = MHKL47BD47;
DEVELOPMENT_TEAM = 3SC5M9PT96;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "$(SRCROOT)/SokIM/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
Expand Down
8 changes: 8 additions & 0 deletions SokIM/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
NSEvent.addGlobalMonitorForEvents(matching: .leftMouseDown.union(.rightMouseDown).union(.otherMouseDown)) {
self.reset($0)
}

// CapsLock 상태를 모니터링
NSEvent.addGlobalMonitorForEvents(matching: .flagsChanged, handler: capsLockHasToggled)

// 사용자의 한/A 전환키 조합을 시스템에 등록, 더미 함수 호출
var eventSpec = EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyPressed))
Expand Down Expand Up @@ -275,4 +278,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
break
}
}

/** CapsLock 상태를 반영 */
private func capsLockHasToggled(with event: NSEvent) {
state.capsLockState = event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock)
}
}
38 changes: 27 additions & 11 deletions SokIM/Engine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,32 @@ protocol Engine {

extension Engine {
/** USB HID Usage -> CharTuple 매핑 */
static func usageToTuple(_ usage: UInt32, _ isAltDown: Bool, _ isShiftDown: Bool) -> CharTuple? {
static func usageToTuple(_ usage: UInt32, _ isAltDown: Bool, _ isShiftDown: Bool, _ isQwertyCapsLockOn: Bool) -> CharTuple? {
let map = usageToTupleMap[usage]

switch (isAltDown, isShiftDown) {
case (true, true):
return map?.altShift
case (true, false):
return map?.alt
case (false, true):
return map?.shift
case (false, false):
return map?.base
if isQwertyCapsLockOn && usage >= 0x04 && usage <= 0x1D {
switch (isAltDown, !isShiftDown) {
case (true, true):
return map?.altShift
case (true, false):
return map?.alt
case (false, true):
return map?.shift
case (false, false):
return map?.base
}
}
else {
switch (isAltDown, isShiftDown) {
case (true, true):
return map?.altShift
case (true, false):
return map?.alt
case (false, true):
return map?.shift
case (false, false):
return map?.base
}
}
}

Expand All @@ -119,9 +133,11 @@ extension Engine {
// Alt, Shift: keyDown 상태
let isAltDown = flags.contains(.option)
let isShiftDown = flags.contains(.shift)
let isCapsLockOn = flags.intersection(.deviceIndependentFlagsMask).contains(.capsLock)
let isQwerty = Self.self == QwertyEngine.self

if let usage = keyCodeToUsage[Int(keyCode)],
let tuple = usageToTuple(usage, isAltDown, isShiftDown) {
let tuple = usageToTuple(usage, isAltDown, isShiftDown, isCapsLockOn && isQwerty) {
return tuple
} else {
return nil
Expand Down
6 changes: 5 additions & 1 deletion SokIM/InputMonitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ class InputMonitor {
if (
(type, key) == (.keyDown, .capsLock)
&& Preferences.rotateShortcut == .capsLock
&& modifier[.leftShift] != .keyDown // Shift가 눌려있을 경우 한영전환 표시 무시
&& modifier[.rightShift] != .keyDown
) || (
(type, key) == (.keyDown, .rightCommand)
&& Preferences.rotateShortcut == .rightCommand
Expand All @@ -198,7 +200,9 @@ class InputMonitor {
}

// 별도 처리: Caps Lock Up: 상태 및 LED 자동으로 끄기
if (type, key) == (.keyUp, .capsLock) {
if (type, key) == (.keyUp, .capsLock)
&& modifier[.leftShift] != .keyDown // Shift가 눌려있을 경우 캡스락 자동 끄기 안함
&& modifier[.rightShift] != .keyDown {
setKeyboardCapsLock(enabled: false)
}
}
Expand Down
11 changes: 10 additions & 1 deletion SokIM/State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ struct State: CustomStringConvertible {

/** modifier 키 눌림 상태 (InputMonitor와 유사) */
var modifier: [ModifierUsage: InputType] = [:]
var capsLockState = false {
didSet {
let isQwertyKeyboard = engine == QwertyEngine.self
qwertyCapsLockState = isQwertyKeyboard && capsLockState
}
}
var qwertyCapsLockState = false // 쿼티 키보드 + 캡스락인지

/** 현재 눌려있는 Input, 반복 입력 시 사용 */
private(set) var down: Input?
Expand All @@ -29,6 +36,8 @@ struct State: CustomStringConvertible {
if (
(type, key) == (.keyDown, .capsLock)
&& Preferences.rotateShortcut == .capsLock
&& modifier[.leftShift] != .keyDown // Shift가 눌려있을 경우 rotate 차단
&& modifier[.rightShift] != .keyDown
) || (
(type, key) == (.keyDown, .rightCommand)
&& Preferences.rotateShortcut == .rightCommand
Expand Down Expand Up @@ -81,7 +90,7 @@ struct State: CustomStringConvertible {
let elapsed = ms(since: input.timestamp)

// engine으로 현재 input을 tuple로 변환 가능하며 처리 시간이 3000ms 이내면
if var tuple = engine.usageToTuple(usage, isAltDown, isShiftDown), elapsed < 3000 {
if var tuple = engine.usageToTuple(usage, isAltDown, isShiftDown, qwertyCapsLockState), elapsed < 3000 {
// "₩ 대신 ` 입력" 처리
if tuple.char == "₩" && Preferences.graveOverWon {
tuple.char = "`"
Expand Down