Skip to content

Instantly share code, notes, and snippets.

@richrd
Created November 18, 2020 16:58
Show Gist options
  • Save richrd/323871ede2ec456f777fc4e702083e25 to your computer and use it in GitHub Desktop.
Save richrd/323871ede2ec456f777fc4e702083e25 to your computer and use it in GitHub Desktop.
Simple Adaptive Mode for the UHK on Linux
import os
import Xlib
import Xlib.display
"""
Simple Adaptive Mode script for the Ultimate Hacking Keyboard on Linux
This script listens to window focus changes and switches keymaps when
a matching window is found. It switches back to the default keymap when
switching away from a matched window.
NOTE:
For this to work you need Node.js installed and the compiled version of
`switch-keymap.ts` on your system. To get the script clone the UHK Agent
repository on your system and compile the file with the Typescript compiler.
You might also need to run this with `sudo` if the `switch-keymap`
script complains about permissions.
"""
# Configuration:
# Default key map to use when no matching window is found
default_keymap = "QWR"
# Mapping from window name to keymap name
window_to_keymap = {
"teeworlds": "GAM",
"steam_app_881100": "GAM",
}
# Path to the UHK switch-keymap.js script
uhk_switch_keymap_path = "/home/user/code/javascript/uhk/agent/packages/usb/switch-keymap.js"
class WindowDetector:
# Adapted from https://www.nuomiphp.com/eplan/en/27421.html
def __init__(self, on_change = None):
self.running = False
self.on_change = on_change
def format_window_name(self, name):
return name.lower()
def window_changed(self, name):
print("The active window has changed to:", name)
if self.on_change:
self.on_change(name)
def run(self):
self.running = True
disp = Xlib.display.Display()
Xroot = disp.screen().root
NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW')
Xroot.change_attributes(event_mask=Xlib.X.PropertyChangeMask)
while self.running:
event = disp.next_event()
if (event.type == Xlib.X.PropertyNotify and
event.atom == NET_ACTIVE_WINDOW):
active = disp.get_input_focus().focus
try:
name = active.get_wm_class()[1]
except Xlib.error.BadWindow:
name = "unknown"
except TypeError:
name = "unknown"
name = self.format_window_name(name)
self.window_changed(name)
class AdaptiveMode:
def __init__(self, uhk_switch_keymap_path, default_keymap, window_to_keymap):
self.default_keymap = default_keymap
self.window_to_keymap = window_to_keymap
self.uhk_switch_keymap_path = uhk_switch_keymap_path
self.previous_window = None
self.window_detector = WindowDetector(self.window_changed)
def switch_to_keymap(self, name):
print("Switching to keymap:", name)
os.system('node {} {}'.format(self.uhk_switch_keymap_path, name))
def window_changed(self, name):
if name == "unknown":
return
if name in self.window_to_keymap.keys():
self.switch_to_keymap(window_to_keymap[name]);
self.previous_window = name
return
if self.previous_window in self.window_to_keymap.keys():
self.switch_to_keymap(self.default_keymap);
self.previous_window = name
def run(self):
print("Adaptive Mode Active")
print("Waiting for window focus changes...")
self.window_detector.run()
# Run Adaptive Mode
app = AdaptiveMode(uhk_switch_keymap_path, default_keymap, window_to_keymap)
app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment