Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to break xlib's next_event()?

I am using QThread (pyside) for handling global hot-keys on X11. I have some simple while loop which looks like:

while self.doRun:                
      event=root.display.next_event()
      if event.type==X.KeyPress:
      ....

But next_event() is known for waiting for actual event. So how do I stop that loop without waiting for another keystroke? I was thinking about sending fake event with keypress via Xlib but I don't think that's a right way. Also .terminate() on that event is not an option... with pyside it crashes whole app with:

Fatal Python error: This thread state must be current when releasing

Any ideas?

like image 896
middleofdreams Avatar asked Nov 02 '25 15:11

middleofdreams


1 Answers

It's a late answer, but I had the same issue, so maybe it's still helpful for someone.

Based on the documentation, you can use Python's select module to receive events with a time-out.

A solution using select basically consists of two steps: 1) work off all pending events, and 2) wait with a select call until new I/O-events arrive. If no events arrive, the method will timeout after a certain time.

Such an event loop could look like this:


# Main loop, handling events
def loop(self):
  self.loop_cond = True
  timeout=5 # timeout in seconds

  while self.loop_cond:
    # handle all available events
    i = self.d.pending_events()
    while i > 0:
      event = self.display.next_event()
      self.handle_event(event)
      i = i - 1

    # Wait for display to send something, or a timeout of one second
    readable, w, e = select.select([self.display], [], [], timeout)

    # if no files are ready to be read, it's an timeout
    if not readable:
      self.handle_timeout()

I've created a gist with a small example.

like image 116
Stefan Avatar answered Nov 04 '25 05:11

Stefan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!