한글 입력 중에만 단축키가 안 된다면, 키와 문자를 따로 보세요

영문 입력 상태에서는 작동하던 ⌘I가 한글 입력 상태에서만 조용해집니다.
같은 키를 눌렀고 Command도 누르고 있으니 단축키 설정을 다시 저장하거나 앱을 재시작하고 싶어집니다.
하지만 앱이 비교하고 있는 값이 i가 아니라 ㅑ라면 설정을 다시 저장해도 맞아떨어지지 않습니다.
macOS의 입력 이벤트에는 키 코드, 입력 문자, 수정 키를 일부 제외한 문자처럼 서로 다른 값이 들어 있습니다. 단축키 문제를 좁히려면 먼저 앱이 어느 값을 키 이름으로 쓰는지 확인해야 합니다.
charactersIgnoringModifiers는 영문 키로 바꾸는 함수가 아닙니다
Apple은 NSEvent.charactersIgnoringModifiers를 Shift를 제외한 수정 키가 적용되지 않은 것처럼 생성한 문자라고 설명합니다.
이름에 “IgnoringModifiers”가 있다고 해서 현재 입력 소스까지 무시하거나 항상 영문 키를 반환한다는 뜻은 아닙니다.
(Apple의 프로퍼티 설명)
확인한 Warp 소스에서는 from_native()가 이 값을 읽어 Keystroke.key를 만듭니다.
Command·Shift·Control 등의 상태는 별도 필드에 넣습니다.
따라서 이 경로에서 읽은 문자가 ㅑ이면 Command가 눌렸다는 사실만으로 cmd-i가 되지는 않습니다.
관련 PR #16192는 한국어 두벌식 입력 소스에서 바로 이 차이를 기록합니다.
로컬에서 구성한 이벤트의 Cmd+I는 characters가 i, charactersIgnoringModifiers가 ㅑ였습니다.
이 관찰은 단축키 매칭에 후자를 사용하던 경로에서 왜 cmd-i와 일치하지 않는지 설명합니다.
이 PR은 병합되지 않고 닫혔습니다. 따라서 여기서 다루는 것은 이미 출시된 해결책이 아니라 입력값을 구분해 문제를 진단한 기록입니다.
앱을 빌드하기 전에 이벤트의 두 값을 읽어 보기
앱 전체를 빌드하기 전에 현재 입력 소스에서 이벤트가 어떤 값을 만드는지 확인할 수 있습니다.
아래 Swift 예제는 이벤트 객체만 구성합니다.
post()를 호출하지 않으므로 실행 중인 앱에 단축키를 보내지는 않습니다.
import AppKit
import Carbon
let event = CGEvent(
keyboardEventSource: nil,
virtualKey: CGKeyCode(kVK_ANSI_I),
keyDown: true
)!
event.flags = .maskCommand
let native = NSEvent(cgEvent: event)!
print(native.characters ?? "nil")
print(native.charactersIgnoringModifiers ?? "nil")
예제를 key-event-probe.swift로 저장한 뒤 실행합니다.
swift key-event-probe.swift
2026-10-27에 확인한 한국어 두벌식 환경에서도 두 값은 각각 i와 ㅑ였습니다.
이 결과는 현재 입력 소스에서 객체가 제공한 문자값을 확인한 것입니다.
실제 키보드 입력이 앱 내부의 단축키 처리까지 도달했거나 해당 동작이 실행됐다는 증거는 아닙니다.
직접 조사할 때는 영문 입력과 한국어 입력에서 각각 실행해 비교하면 됩니다. 결과가 다르면 그 차이가 앱의 매칭 코드까지 어떻게 전달되는지 따라갑니다. 두 환경에서 같은 값이 나온다면 이 사례의 원인을 그대로 적용하지 말고 동작 활성화 조건이나 다른 입력 경로를 확인해야 합니다.
characters로 바꾸는 것만으로 끝나지 않는 이유
Cmd+I에서 characters가 i로 보이면 그 값을 쓰면 될 것 같습니다.
그런데 Shift를 함께 누른 조합은 별도로 확인해야 합니다.
이번 로컬 프로브에서 Cmd+Shift+I의 characters도 소문자 i였습니다.
관련 PR의 기록 역시 단순한 대체만으로는 영문 입력 소스에서 얻는 Shift 조합의 키 이름을 재현하지 못한다고 설명합니다.
PR은 Command 조합의 일부 경로에 ASCII-capable 키보드 레이아웃 변환을 적용하는 방안을 제안했습니다.
하지만 이것을 모든 앱과 모든 입력 소스에 적용할 정답으로 받아들이기는 어렵습니다.
같은 PR에도 기존에 cmd-ㅑ 같은 문자로 직접 바인딩한 사용자는 동작이 달라진다는 조건이 적혀 있습니다.
키 위치를 기준으로 할지, 현재 레이아웃의 문자를 기준으로 할지는 사용자에게 보이는 단축키 정책입니다. “한글에서도 동작하게 만들었다”는 결과만으로 다른 레이아웃과 사용자 지정 조합까지 보존했다고 말할 수는 없습니다. 일반 문자, Shift 조합, 이미 ASCII 문자를 만드는 레이아웃, 사용자 재지정 조합을 나눠 비교해야 합니다.
단축키가 실행되는 것과 조합 중인 글자가 남는 것은 별개입니다
한국어 입력에서는 글자가 아직 조합 중인 순간도 확인해야 합니다.
관련 PR에는 안녕하를 입력하는 도중 단축키를 누르면 마지막 조합 글자인 하가 사라지는 별도 관찰이 있습니다.
이것은 PR에 기록된 당시 동작입니다.
이번 글에서 현재 배포판으로 재현한 결과는 아닙니다.
기록은 이벤트 순서를 원인으로 지목합니다. 키를 처리한 경우에는 IME가 확정한 문자를 삽입하지 않는다고 설명합니다. 키 이름을 고쳐 단축키가 더 자주 매칭되게 만드는 것만으로는 그 순서가 바뀌지 않습니다. 단축키의 성공 여부와 입력한 텍스트의 보존 여부를 함께 봐야 하는 이유입니다.
입력 버그를 검토할 때 다음 순서로 범위를 좁힐 수 있습니다.
- 영문 입력에서도 같은 동작이 활성화되어 있는지 먼저 확인합니다. 로그인이나 기능 설정이 다르면 비교 기준이 달라집니다.
- 같은 물리 키의
characters,charactersIgnoringModifiers, modifier flags를 기록합니다. - 기본 조합과 Shift 조합을 따로 확인하고 앱이 비교하는 최종 키 이름을 대조합니다.
- 한국어 조합을 끝낸 상태와 조합 중인 상태에서 각각 실행해 동작 실행과 텍스트 보존을 따로 검사합니다.
한글 입력 상태에서만 안 되는 단축키는 키가 안 눌린 문제가 아닐 수 있습니다. 이벤트가 만든 문자, 단축키가 기대하는 이름, IME가 확정한 텍스트가 서로 다른 경로로 처리되는지를 먼저 보면 조사할 지점이 구체적으로 드러납니다.
다음 글도 받아보세요.
글을 끝까지 읽으셨다면, 다음 글은 받은편지함이나 RSS 리더에서 만나보세요.