Created
November 18, 2020 16:58
-
-
Save richrd/323871ede2ec456f777fc4e702083e25 to your computer and use it in GitHub Desktop.
Simple Adaptive Mode for the UHK on Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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