1 year ago

#252545

test-img

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

Accepted video resources