Stabilne przełączanie układu klawiatury w Windows 11 za pomocą AutoHotkey v2
W Windows 11 standardowa kombinacja Alt+Shift czasami pomija przełączenie języka podczas szybkiego pisania. Po ponownym uruchomieniu systemu wszystko działa poprawnie, ale po pewnym czasie mechanizm zaczyna zawodzić. Przełączanie za pomocą Win+Spacja pozostaje stabilne, co wskazuje na opóźnienia w obsłudze skrótów klawiszowych przez standardowy handler.
Typowe zalecenia — wyłączenie klawiszy trwałych, ponowne uruchomienie ctfmon.exe lub ponowna instalacja pakietów językowych — w większości przypadków nie rozwiązują problemu.
Rozwiązanie oparte na AutoHotkey v2
Przechwytujemy kombinację Alt+Shift za pomocą skryptu AutoHotkey v2, który bezpośrednio wywołuje API Windows w celu zmiany układu klawiatury. To omija wbudowany mechanizm, zapewniając przewidywalne działanie bez pominięć.
Zalety podejścia
- Szybkie uruchamianie nawet przy częstych naciśnięciach.
- Ochrona przed zdublowanymi zdarzeniami.
- Działa w wątkach aktywnego okna (thread-specific layout).
Alternatywą jest Punto Switcher z automatycznym przełączaniem, ale dla programistów ręczne sterowanie jest preferowane ze względu na elastyczność.
Konfiguracja skryptu
Zainstaluj AutoHotkey v2. Utwórz plik LangSwitch.ahk i wklej kod:
#Requires AutoHotkey v2.0
#SingleInstance Force
; Przełączanie między PL i EN za pomocą Alt+Shift (w dowolnej kolejności naciśnięcia)
~*LAlt::TrySwitch()
~*RAlt::TrySwitch()
~*LShift::TrySwitch()
~*RShift::TrySwitch()
TrySwitch() {
static lastTick := 0
if !(GetKeyState("Alt", "P") && GetKeyState("Shift", "P"))
return
; Ochrona przed podwójnym uruchomieniem przy jednoczesnych zdarzeniach klawiszy
now := A_TickCount
if (now - lastTick < 150)
return
lastTick := now
TogglePlEn()
}
TogglePlEn() {
static PL := 0x0415
static EN := 0x0409
hwnd := WinActive("A")
if !hwnd
return
; Aktualny układ klawiatury wątku aktywnego okna
threadId := DllCall("GetWindowThreadProcessId", "Ptr", hwnd, "UInt*", 0, "UInt")
hkl := DllCall("GetKeyboardLayout", "UInt", threadId, "UPtr")
langId := hkl & 0xFFFF
target := (langId = PL) ? EN : PL
targetHKL := (target << 16) | target
; WM_INPUTLANGCHANGEREQUEST
DllCall("PostMessage", "Ptr", hwnd, "UInt", 0x50, "Ptr", 0, "Ptr", targetHKL)
}
Analiza logiki skryptu
- Haki klawiszy:
~LAlt,~RAltitd. uruchamiają się przy naciśnięciu bez blokowania (~) i w dowolnej kolejności. - Sprawdzenie kombinacji:
GetKeyStatepotwierdza jednoczesne naciśnięcie Alt+Shift. - Debounce: Interwał 150 ms zapobiega wielokrotnym wywołaniom przy drganiu klawiszy.
- Pobieranie układu:
GetKeyboardLayoutdla threadId aktywnego okna zwraca HKL bieżącego wątku. - Zmiana:
PostMessagezWM_INPUTLANGCHANGEREQUEST (0x50)stosuje target HKL.
Wyłączenie standardowego skrótu klawiszowego
Ustawienia → Czas i język → Wprowadzanie → Zaawansowane ustawienia klawiatury → Skróty klawiszowe dla języków wprowadzania.
Wybierz „Przełącz język wprowadzania” → „Zmień skrót klawiszowy” → „Nie przypisano”.
Autostart i UAC
- Utwórz skrót skryptu w
shell:startup. - Do działania w aplikacjach UAC: uruchom przez
C:\Program Files\AutoHotkey\v2\AutoHotkey64_UIA.exe(uiAccess).
Wymaga instalacji AutoHotkey w Program Files.
Co jest ważne
- Skrypt używa thread-specific layout przez
GetWindowThreadProcessIdiGetKeyboardLayout. PostMessage(0x50)gwarantuje zmianę bez skupienia na oknie.- Debounce 150 ms minimalizuje fałszywe uruchomienia przy szybkim wprowadzaniu.
- Tryb UIAccess rozwiązuje problemy z uprawnieniami administratora.
- Obsługa PL/EN: 0x0415 i 0x0409.
— Editorial Team
Brak komentarzy.