CrownyAI 브라우저 한/영 — 앱 전용 토글 폐기, macOS 입력소스 추종
개요
CrownyAI 브라우저(native/crowny-browser.m) 네이티브 앱뷰(CrownyAppView, 메모/터미널
등)의 한/영 판정을 앱 전용 Ctrl+Space 토글에서 macOS OS 입력소스 추종으로 전환했다.
사장님 확정 설계: 조합(자모→음절)은 크라우니 한글조합기.toau(헌법 — 맥 IME 조합 비의존)를
그대로 쓰되, "지금 한/영 어느 쪽인가"라는 판정만 OS에 묻는다.
배경 — 왜 바꿨나 (실측)
기존 구현은 CrownyAppView.한글모드 플래그를 keyDown에서 Ctrl+Space로 토글했다.
그런데 macOS는 Ctrl+Space를 시스템 "이전 입력기 선택" 단축키로 이미 선점하고 있어
이벤트가 애초에 앱까지 오지 않는다 — 사용자 실측: 눌러도 배지가 안 바뀜. 즉 "앱 전용
한/영 모드"라는 설계 자체가 macOS 표준 단축키 정책과 충돌하는 구조적 오류였다.
확정 설계
- 판정 = OS 입력소스 추종. 사용자가 평소 쓰는 맥 한영키(⌘Space 계열 또는 사용자 지정
- 조합 = 크라우니 조합기 유지. 한/영 판정만 OS에서 가져오고, 자모를 음절로 합치는
appRunComposeCmd("JAMO"/"COMMIT"/"BS") 경로 그대로 — macOS TSM/IME
조합에 의존하지 않는다(헌법 — 외부 의존성 최소화).구현 (native/crowny-browser.m)
- TIS 감지 헬퍼
cbIsKoreanInputSource()(crowny-browser.m:686 부근,cbWriteInputMode
TISCopyCurrentKeyboardInputSource() + kTISPropertyInputSourceID로
현재 입력소스 ID를 얻어 "com.apple.inputmethod.Korean"(2벌식/3벌식/390 등 macOS 내장
한국어 IME 전부 이 접두사) 또는 방어적으로 "com.apple.keylayout.Korean"(하드웨어
레이아웃형) 접두사면 한글로 판정.
- 변경 감지 — 두 경로 병행
kTISNotifySelectedKeyboardInputSourceChanged 분산 알림을
NSDistributedNotificationCenter로 구독(initWithService:에서 등록,
- (void)onInputSourceChanged:가 핸들러). TIS 알림은 Darwin 배포센터
(CFNotificationCenterGetDistributedCenter) 경유로 발행되고, NSDistributedNotificationCenter가
같은 이름으로 수신 가능 — 사용자 실제 한영키 입력 시 즉시 배지 갱신.
- ② keyDown 진입 시마다 cbIsKoreanInputSource() 재확인(알림 유실 대비 보험,
TIS 호출은 저비용이라 매 키 입력 부담 무시 가능 실측).
- 둘 다: 값이 바뀌면 조합세션이 있으면 먼저 COMMIT, cbWriteInputMode()로
/tmp/입력모드.psv 갱신, renderAndReload.
- Ctrl+Space 토글 제거 —
keyDown의 기존 토글 분기(구 :1051~1059)를 삭제하고
- 초기값 —
_한글모드를 서비스별 하드코딩(메모=한글 기본/터미널=영문 기본)에서
cbIsKoreanInputSource() 단일 판정으로 통일(서비스 무관, OS가 유일한 진실).
- 키 처리 매트릭스 (코드 주석에도 명시, crowny-browser.m keyDown 내):
injectJamo 직행, 이중 처리 금지.
- 한국어 소스 + 라틴 수신(레이아웃/엣지케이스로 커밋 방식이 다른 경우) →
usKeyToJamo()로 두벌식 환산 후 injectJamo.
- 영어 소스 → 자모 매핑 스킵, 라틴 직행(injectKey).
- 이 구조 자체는 기존 코드(라인 순서)와 동일 — 달라진 것은 한글모드가 이제
"OS가 한국어 소스인가"를 뜻한다는 점뿐.
- 배지 문구 —
src/터미널앱.한선:"A · Ctrl+Space 한/영"→"A · 한/영=맥 한영키",
"한 · 한/영=맥 한영키". 상태 파일 설명 주석도 "브라우저 한/영 토글이 기록"
→ "브라우저가 OS 입력소스 추종값을 기록"으로 정정.
- Makefile —
crowny-browser.m을 링크하는 타깃(기본LDFLAGS,crownyonly인라인
-framework Carbon 추가. standalone(별도 소스
crowny-browser-standalone.m)은 이번 작업 범위 밖 — 미변경.검증
- 빌드:
make web(기본 CrownyBrowser) exit 0, Carbon.framework 링크 확인
otool -L → /System/Library/Frameworks/Carbon.framework/...). 경고는 기존부터
있던 무관한 1건(crownyButlerRoot unused)뿐, 신규 에러/경고 0.
make public universal crownyonly 3변종도 전부 exit 0(crownyonly는 WebKit 링크
0 유지 확인 — otool grep).
- 3곳 배치: 빌드 산출물을 스크래치 임시경로에 cp한 뒤 각 목적지로 mv(제자리 cp
native/CrownyBrowser, CrownyAI.app/Contents/MacOS/CrownyBrowser,
CrownyBrowser.app/Contents/MacOS/CrownyBrowser 3파일 SHA1 전부 동일:
45c6a413579da8d40a3e4943eca3f231107b8037.
- TIS 감지 단독 헤드리스 테스트:
crowny-browser.m의cbIsKoreanInputSource()
tis_probe.m, Cocoa+Carbon만 링크, GUI 불요)를
스크래치에 빌드·실행 — 이 세션 진행 중 실제 맥 현재 입력소스 판정:
입력소스ID=com.apple.inputmethod.Korean.2SetKorean
한글여부=YES
접두사 매칭 로직이 실제 macOS 2벌식 입력소스 ID를 정확히 한글로 판정함을 확인.
- 터미널앱.한선 컴파일+배지:
hanseonc_high컴파일 exit 0(4604토큰, 12439큐브).
/tmp/입력모드.psv를 모드|영문/모드|한글로 바꿔가며 crownyc run cmd 스트림을
헤드리스로 검사 — 두 경우 모두 exit 0, 배지 TEXT 명령이 각각
A · 한/영=맥 한영키 / 한 · 한/영=맥 한영키로 정확히 렌더됨(색상도 130/125/115↔
201/169/97로 정상 스위칭).
- GUI 실측(맥 한영키 눌러 배지·입력 실제 전환)은 사용자 몫 — 헤드리스로는
크라우니코드 보고
- lookup-first 조회:
crownycode-learn.sh search "입력소스 한영"/"TIS 키보드"→
- 생성: TIS 판정 헬퍼 1건(
cbIsKoreanInputSource) 직접 작성. - 학습:
crownycode-learn.sh add tis입력소스한영추종 "<코드>"→ 학습완료. - 크라우니코드: lookup HIT 0건(재사용) / MISS 2건(생성) / learn 추가 1건.
.한선 신규 로직이 아니라 macOS Carbon API 연동이라 한선씨 동반 대상 아님.
단 로직을 학습DB엔 패턴으로 등록해 재사용 가능하게 함.)윈도우 대응 방법론 (조사만 — 구현은 별도 에이전트 담당)
macOS TIS의 Win32 대응:
- 현재 IME 언어 감지:
WM_INPUTLANGCHANGE메시지(윈도우가 입력 언어 변경 시 수신,
lParam=새 HKL)를 훅해 실시간 갱신하거나, 폴링 시 GetKeyboardLayout(threadId)로
현재 HKL을 얻고 LOWORD(hkl)(Language Identifier)을
MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN)(0x0412)과 비교해 한국어 여부 판정.
단, 같은 "Korean" 키보드 레이아웃 안에서 IME 켬/끔(한/영 전환)이 별도 상태로
존재하는 경우가 많아 — 이 경우 ImmGetContext(hwnd) + ImmGetConversionStatus()로
IME conversion mode(한글 입력 on/off)를 추가로 확인해야 정확하다(레이아웃=언어,
IME conversion=한/영 실제 스위치, 둘이 분리된 개념).
- 조합은 OS IME에 맡기지 않고 크라우니 조합기 사용:
WM_IME_COMPOSITION/
WM_IME_CHAR를 받으면 이미 OS가 조합을 끝낸 결과라 크라우니 조합기와 이중 처리
충돌이 남. macOS와 동일한 원칙(OS 조합 비의존)을 지키려면
ImmAssociateContext(hwnd, NULL)로 해당 윈도우의 IME 컨텍스트를 분리해 원시
WM_KEYDOWN(VK 코드)이 그대로 넘어오게 한 뒤, usKeyToJamo()와 동일한
VK→두벌식 자모 매핑 테이블(예: VK_R→ㄱ, VK_S→ㄴ 등, US QWERTY 물리 배치 기준)로
크라우니 조합기(JAMO/COMMIT/BS)에 그대로 이벤트를 넘기면 macOS 경로와 대칭 구조가
된다.
- 결론: 감지=
WM_INPUTLANGCHANGE+GetKeyboardLayout(+필요시ImmGetConversionStatus),
ImmAssociateContext(hwnd,NULL)로 OS IME 비활성화 후 VK 매핑 경유 크라우니
조합기 — macOS TIS+자체조합 구조와 1:1 대응.관련 파일
/Users/ef/CrownyBrowser/native/crowny-browser.m—cbIsKoreanInputSource(),
initWithService:(초기값+알림 구독), onInputSourceChanged:, dealloc,
keyDown:(토글 제거+재확인+매트릭스 주석) 수정.
/Users/ef/CrownyBrowser/native/Makefile—LDFLAGS/crownyonly타깃에
-framework Carbon 추가.
/Users/ef/CrownyBrowser/src/터미널앱.한선— 배지 문구·주석 정정./Users/ef/CrownyBrowser/native/CrownyBrowser,
/Users/ef/CrownyBrowser/CrownyAI.app/Contents/MacOS/CrownyBrowser,
/Users/ef/CrownyBrowser/CrownyBrowser.app/Contents/MacOS/CrownyBrowser — 재빌드
배치(SHA1 45c6a413579da8d40a3e4943eca3f231107b8037 동일).잔여 이슈
- GUI 실측(실제 맥 한영키 전환 시 배지·입력 변화)은 미실증 — 사용자 확인 필요.
크라우니앱뷰어.m(/Users/ef/CrownyBrowser/native/)은 같은 Ctrl+Space 토글 패턴을
crowny-browser-standalone.m(standalone 빌드 타깃 소스)도 별도 파일이라 이번