Skip to content

Instantly share code, notes, and snippets.

@QXD-me
Forked from drmfinlay/_win32_hkl_switch.py
Created December 27, 2020 23:45
Show Gist options
  • Save QXD-me/3399bceb59e30d36ebd75d8877ec03ab to your computer and use it in GitHub Desktop.
Save QXD-me/3399bceb59e30d36ebd75d8877ec03ab to your computer and use it in GitHub Desktop.
Module for working around Dragonfly issues with custom keyboard layouts
"""
This command module automatically posts input language change request
messages to all top-level windows as a workaround for keyboard layouts where
Dragonfly's Win32 key input doesn't work properly.
Use this module by loading it as a Dragonfly command module.
"""
import time
import win32con
import win32gui
from dragonfly import RecognitionObserver
PROCESSING_LAYOUT_HKL = 0x8090809 # HKL for English (UK) - QWERTY
NORMAL_LAYOUT_HKL = -0xf3ff7f7 # HKL for English (UK) - Colemak
def postLangChangeReqMsg(hwnd, wParam, lParam):
"""
Post a WM_INPUTLANGCHANGEREQUEST message with the specified parameters.
"""
win32gui.PostMessage(hwnd, win32con.WM_INPUTLANGCHANGEREQUEST, wParam,
lParam)
class HackyObserver(RecognitionObserver):
"""
A hacky recognition observer class for setting the keyboard layout
before and after recognition processing.
"""
def on_recognition(self, words):
# Set the keyboard layout for the foreground window.
hwnd = win32gui.GetForegroundWindow()
# hwnd = win32con.HWND_BROADCAST # Use on Windows versions below 8.
hkl = PROCESSING_LAYOUT_HKL
# print("Setting layout to %08x." % hkl)
postLangChangeReqMsg(hwnd, 0, hkl)
# Wait a moment.
time.sleep(0.001)
def on_post_recognition(self, words):
# Set the keyboard layout for the foreground window.
hwnd = win32gui.GetForegroundWindow()
# hwnd = win32con.HWND_BROADCAST # Use on Windows versions below 8.
hkl = NORMAL_LAYOUT_HKL
# print("Setting layout to %08x." % hkl)
postLangChangeReqMsg(hwnd, 0, hkl)
# Wait a moment.
time.sleep(0.001)
# Register the observer.
observer = HackyObserver()
observer.register()
print('Test')
# Unload function which will be called by natlink at unload time.
def unload():
global observer
if observer:
observer.unregister()
observer = None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment