from Xlib.display import Display from Xlib.ext.xtest import fake_input from Xlib import X from os import environ _display = Display(environ['DISPLAY']) def tap(keycode): down(keycode) time.sleep(0.05) up(keycode) def down(keycode): if environ.get("DRY"): return fake_input(_display, X.KeyPress, keycode) _display.sync() def up(keycode): if environ.get("DRY"): return fake_input(_display, X.KeyRelease, keycode) _display.sync() def __init_keys__(): import subprocess _p = subprocess.run( "xmodmap -pke".split(), capture_output=True, ) assert(_p.returncode == 0) stdout = _p.stdout result = {} allowed = ["F"+str(i) for i in range(13, 25)] unassigned = [] # already assigned for line in stdout.split("\n".encode())[1:]: if line: words = line.split() key = int(words[1]) if len(words) < 4: unassigned.append(key) elif words[3].decode() in allowed: allowed.remove(words[3].decode()) result[key] = words[3].decode() # not assigned for key in unassigned: if not allowed: break word = allowed.pop() if word: assert(subprocess.run([ "xmodmap", "-e", f"keycode {key} = {word}", ]).returncode == 0) result[key] = word print("unassigned", unassigned) print("allowed", allowed) print("result", result) return result keys = __init_keys__() if __name__ == "__main__": import time for key in keys: print("key", key, "in...") n = 2 for i in range(n): print(" ", n-i, "...") time.sleep(1) down(key) time.sleep(0.1) up(key) print(" /key", key) time.sleep(3)