1
0
Fork 0

x11: switch from wait_for_event() to directly using poll()

This commit is contained in:
William Light 2020-09-11 16:13:32 +02:00
parent c76f089c96
commit dcb99e5c43
2 changed files with 35 additions and 4 deletions

View file

@ -18,6 +18,7 @@ raw-window-handle = "0.3.3"
xcb = { version = "0.9", features = ["thread", "xlib_xcb", "dri2"] }
x11 = { version = "2.18", features = ["xlib"] }
libc = "0.2"
nix = "0.18"
[target.'cfg(target_os="windows")'.dependencies]
winapi = { version = "0.3.8", features = ["libloaderapi", "winuser", "windef", "minwindef", "guiddef", "combaseapi", "wingdi", "errhandlingapi"] }

View file

@ -1,9 +1,10 @@
use std::os::raw::{c_ulong, c_void};
use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle};
use super::XcbConnection;
use crate::{Event, MouseButtonID, MouseScroll, Parent, WindowHandler, WindowOpenOptions};
use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle};
pub struct Window {
xcb_connection: XcbConnection,
@ -101,14 +102,43 @@ impl Window {
WindowHandle
}
// Event loop
fn run_event_loop<H: WindowHandler>(&mut self, handler: &mut H) {
loop {
let ev = self.xcb_connection.conn.wait_for_event();
if let Some(event) = ev {
#[inline]
fn drain_xcb_events<H: WindowHandler>(&mut self, handler: &mut H) {
while let Some(event) = self.xcb_connection.conn.poll_for_event() {
self.handle_xcb_event(handler, event);
}
}
// Event loop
// FIXME: poll() acts fine on linux, sometimes funky on *BSD. XCB upstream uses a define to
// switch between poll() and select() (the latter of which is fine on *BSD), and we should do
// the same.
fn run_event_loop<H: WindowHandler>(&mut self, handler: &mut H) {
use nix::poll::*;
let xcb_fd = unsafe {
let raw_conn = self.xcb_connection.conn.get_raw_conn();
xcb::ffi::xcb_get_file_descriptor(raw_conn)
};
loop {
let mut fds = [
PollFd::new(xcb_fd, PollFlags::POLLIN)
];
// FIXME: handle errors
poll(&mut fds, -1).unwrap();
if let Some(revents) = fds[0].revents() {
if revents.contains(PollFlags::POLLERR) {
panic!("xcb connection poll error");
}
if revents.contains(PollFlags::POLLIN) {
self.drain_xcb_events(handler);
}
}
}
}
fn handle_xcb_event<H: WindowHandler>(&mut self, handler: &mut H, event: xcb::GenericEvent) {