mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
Fix busy loop in X11 WaitEventsIterator
WaitEventsIterator implements waiting by first calling XPeekEvent which will block until at least 1 event is queued, and then it delegates to PollEventsIterator to actually handle the new event. PollEventsIterator was previously picky about which events it would process. Events of other types would get stuck at the head of the X event queue, and PollEventsIterator would return None. This initiated a busy loop in the WaitEventsIterator because it would XPeekEvent, see that something is there, and then PollEventsIterator would return None, and the process would repeat. This is resolved by using XNextEvent in the PollEventsIterator instead of XCheckTypedEvent. Any event in the queue will be popped. Even if winit isn't interested in the event, this means XPeekEvent will block again to wait for another event instead of the previous behavior.
This commit is contained in:
parent
adf42909c8
commit
2ee658048a
|
@ -158,18 +158,26 @@ impl<'a> Iterator for PollEventsIterator<'a> {
|
|||
}
|
||||
|
||||
let mut xev = unsafe { mem::uninitialized() };
|
||||
let res = unsafe { (xlib.XCheckMaskEvent)(self.window.x.display.display, -1, &mut xev) };
|
||||
|
||||
if res == 0 {
|
||||
let res = unsafe { (xlib.XCheckTypedEvent)(self.window.x.display.display, ffi::ClientMessage, &mut xev) };
|
||||
|
||||
if res == 0 {
|
||||
let res = unsafe { (xlib.XCheckTypedEvent)(self.window.x.display.display, ffi::GenericEvent, &mut xev) };
|
||||
if res == 0 {
|
||||
return None;
|
||||
}
|
||||
// Get the next X11 event. XNextEvent will block if there's no
|
||||
// events available; checking the count first ensures an event will
|
||||
// be returned without blocking.
|
||||
//
|
||||
// Functions like XCheckTypedEvent can prevent events from being
|
||||
// popped if they are of the wrong type in which case winit would
|
||||
// enter a busy loop. To avoid that, XNextEvent is used to pop
|
||||
// events off the queue since it will accept any event type.
|
||||
unsafe {
|
||||
let count = (xlib.XPending)(self.window.x.display.display);
|
||||
if count == 0 {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
let res = (xlib.XNextEvent)(self.window.x.display.display, &mut xev);
|
||||
|
||||
// Can res ever be none zero if count is > 0?
|
||||
assert!(res == 0);
|
||||
};
|
||||
|
||||
match xev.get_type() {
|
||||
ffi::MappingNotify => {
|
||||
|
|
Loading…
Reference in a new issue