Skip to content

Instantly share code, notes, and snippets.

@fphammerle
Last active January 14, 2018 13:13
Show Gist options
  • Save fphammerle/d81ca3ff0a169f062a9f28e57b18f04d to your computer and use it in GitHub Desktop.
Save fphammerle/d81ca3ff0a169f062a9f28e57b18f04d to your computer and use it in GitHub Desktop.
Wrap python-xlib's Xlib.display.next_event() so it does not block the main loop
"""
python-xlib's Xlib.display.next_event() does not have a timeout when waiting for an event to be queued.
It may block the script's execution forever.
Workaround:
Call display.next_event() only if an event is available in the queue.
Use select.select() on the xserver's socket to wait for an event and specify a timeout.
based on: https://stackoverflow.com/a/8592969/5894777
python-xlib: https://github.com/python-xlib/python-xlib
tags: x11, xorg, x.org, xwindow-system, xlib, python-xlib, event queue, XNextEvent, wait, non-blocking, timeout
"""
import select
import Xlib.display
def x_wait_for_event(xdisplay, timeout_seconds):
""" Wait up to `timeout_seconds` seconds for an event to be queued.
Return True, if a xevent is available.
Return False, if the timeout was reached. """
rlist = select.select(
[xdisplay.display.socket], # rlist
[], # wlist
[], # xlist
timeout_seconds, # timeout [seconds]
)[0]
return len(rlist) > 0
def handle_xevent(event):
xdisplay = Xlib.display.Display()
# setup x client etc.
# ...
# main loop:
while True:
while xdisplay.pending_events():
print(xdisplay.next_event())
if not x_wait_for_event(xdisplay, timeout_seconds=1):
print('timeout')
# check other sources for events...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment