1 year ago
#252545
Joël Vermeulen
No keypress events recieved - python-xlib window manager
I am trying to write a simple tiling window manager in python using python-xlib. The problem is, i can not get keypress events to work. As you can see in my code, i have grabbed all keys with X.AnyKey. I am not able to get any log files from my python script, as I have to reboot the raspberry pi I am testing the script on to exit the window manager, because the exit keybind also is not working. My code is a bit of a mess, and I apologise for that. I have tried to set a time limit on my script, but that does not always work and sometimes the script does not exit after 15 seconds even after I spam press keys. Can anyone help find why I do not recieve keypress events?
Here is the code:
#!/usr/bin/env python3
GAP_SIZE = 10
FOCUSED_GAP_SIZE = 5
TERMINAL_KEY = 'U'
EXIT_KEY = 'Q'
TERMINAL_COMMAND = 'xterm'
import os
import time
from Xlib.display import Display
from Xlib import X, XK
dpy = Display()
root = dpy.screen().root
def grab_events(w):
w.change_attributes(event_mask = (
X.SubstructureRedirectMask |
X.SubstructureNotifyMask |
X.KeyPressMask ))
w.grab_key(X.AnyKey, X.Mod4Mask,
True, X.GrabModeSync, X.GrabModeSync)
grab_events(root)
root.set_wm_name("pyTiles")
os.popen("xsetroot -cursor_name left_ptr")
flat_windows_list = []
windows = [[]]
place_new_horizontal = True
focus = {'y': 0, 'x': 0}
def find_2d(il, i):
for iy, l in enumerate(il):
for ix, v in enumerate(l):
if v == i:
return iy, ix
def conf_size(window):
width = root.get_geometry().width
height = root.get_geometry().height
max_windows_width = 0
for l in windows:
max_windows_width = max(len(l), max_windows_width)
w = width / max_windows_width
h = height / len(windows)
y, x = find_2d(windows, window)
gap = FOCUSED_GAP_SIZE if y == focus['y'] and x == focus['x'] else GAP_SIZE
window.configure(
x = w * x + gap,
y = h * y + gap,
width = w - 2 * gap,
height = h - 2 * gap
)
debug_max_loop_duration = 15
debug_loop_start_time = time.time()
while True:
#_DEBUG
if time.time() > debug_loop_start_time + debug_max_loop_duration: break
#_ENDDEBUG
dpy.sync()
ev = dpy.next_event()
print('ev.type', ev.type)
if ev.type == X.ConfigureRequest:
if ev.window not in flat_windows_list:
if place_new_horizontal:
windows[focus['y']].insert(focus['x']+1, ev.window)
else:
windows.insert(focus['y']+1, [ev.window])
grab_events(ev.window)
flat_windows_list.append(ev.window)
conf_size(ev.window)
print('configured', ev.window)
if ev.type == X.MapRequest:
ev.window.map()
print('mapped', ev.window)
if ev.type == X.CirculateRequest:
ev.window.send_event(ev)
if ev.type == X.DestroyNotify:
r = find_2d(windows, ev.window)
if not r: continue
y, x = r
del windows[y][x]
if len(windows[y]) == 0:
del windows[y]
if ev.type == X.KeyPress:
print('pressed', ev.detail)
if ev.detail == dpy.keysym_to_keycode(XK.string_to_keysym(EXIT_KEY)):
break
if ev.detail == dpy.keysym_to_keycode(XK.string_to_keysym(TERMINAL_KEY)):
os.system(TERMINAL_COMMAND)
python
x11
window-managers
0 Answers
Your Answer