Windows 11에서 AutoHotkey v2로 안정적인 키보드 레이아웃 전환하기
Windows 11에서 표준 Alt+Shift 단축키는 빠른 타이핑 중에 언어 전환이 제대로 안 될 때가 있습니다. 시스템 재부팅 후에는 정상 작동하지만, 시간이 지나면 메커니즘이 제대로 작동하지 않기 시작합니다. Win+Space로 전환하는 방법은 안정적으로 작동하는데, 이는 표준 핫키 핸들러의 처리 지연을 나타냅니다.
일반적인 권장 사항인 고정 키 비활성화, ctfmon.exe 재시작, 또는 언어 팩 재설치는 대부분의 경우 문제를 해결하지 못합니다.
AutoHotkey v2 기반 솔루션
AutoHotkey v2 스크립트를 통해 Alt+Shift 조합을 가로채어 Windows API를 직접 호출하여 레이아웃을 변경합니다. 이는 내장 메커니즘을 우회하여 예측 가능한 작동을 보장하며, 누락 없이 안정적으로 작동합니다.
이 접근법의 장점
- 빈번한 누름에도 빠른 트리거.
- 중복 이벤트 방지.
- 활성 창 스레드에서 작동(스레드별 레이아웃).
대안으로는 자동 전환 기능이 있는 Punto Switcher가 있지만, 개발자에게는 유연성을 고려하여 수동 제어가 선호됩니다.
스크립트 설정
AutoHotkey v2를 설치하세요. LangSwitch.ahk 파일을 생성하고 다음 코드를 삽입하세요:
#Requires AutoHotkey v2.0
#SingleInstance Force
; Alt+Shift로 RU와 EN 사이 전환 (누르는 순서 무관)
~*LAlt::TrySwitch()
~*RAlt::TrySwitch()
~*LShift::TrySwitch()
~*RShift::TrySwitch()
TrySwitch() {
static lastTick := 0
if !(GetKeyState("Alt", "P") && GetKeyState("Shift", "P"))
return
; 동시 키 이벤트로 인한 이중 트리거 방지
now := A_TickCount
if (now - lastTick < 150)
return
lastTick := now
ToggleRuEn()
}
ToggleRuEn() {
static RU := 0x0419
static EN := 0x0409
hwnd := WinActive("A")
if !hwnd
return
; 활성 창 스레드의 현재 레이아웃
threadId := DllCall("GetWindowThreadProcessId", "Ptr", hwnd, "UInt*", 0, "UInt")
hkl := DllCall("GetKeyboardLayout", "UInt", threadId, "UPtr")
langId := hkl & 0xFFFF
target := (langId = RU) ? EN : RU
targetHKL := (target << 16) | target
; WM_INPUTLANGCHANGEREQUEST
DllCall("PostMessage", "Ptr", hwnd, "UInt", 0x50, "Ptr", 0, "Ptr", targetHKL)
}
스크립트 로직 설명
- 키 훅:
~LAlt,~RAlt등은 누를 때 트리거되며, 차단 없이(~) 어떤 순서로든 작동합니다. - 조합 확인:
GetKeyState로 Alt+Shift 동시 누름을 확인합니다. - 디바운스: 150ms 간격으로 키 지터로 인한 다중 호출을 방지합니다.
- 레이아웃 가져오기: 활성 창의 threadId에 대한
GetKeyboardLayout이 현재 스레드의 HKL을 반환합니다. - 전환:
WM_INPUTLANGCHANGEREQUEST (0x50)와 함께PostMessage를 사용하여 대상 HKL을 적용합니다.
표준 핫키 비활성화
설정 → 시간 및 언어 → 입력 → 고급 키보드 설정 → 입력 언어 핫키.
"입력 언어 전환" 선택 → "키 시퀀스 변경" → "할당되지 않음".
자동 시작 및 UAC
shell:startup에 스크립트 바로 가기를 생성하세요.- UAC 애플리케이션의 경우:
C:\Program Files\AutoHotkey\v2\AutoHotkey64_UIA.exe(uiAccess)를 통해 실행하세요.
AutoHotkey가 Program Files에 설치되어 있어야 합니다.
핵심 포인트
- 스크립트는
GetWindowThreadProcessId와GetKeyboardLayout을 통해 스레드별 레이아웃을 사용합니다. PostMessage(0x50)는 창 포커스 없이 전환을 보장합니다.- 150ms 디바운스는 빠른 입력 중 오작동을 최소화합니다.
- UIAccess 모드는 관리자 권한 문제를 해결합니다.
- RU/EN 지원: 0x0419 및 0x0409.
— Editorial Team
아직 댓글이 없습니다.