diff --git a/src/lib.rs b/src/lib.rs index 4a0d9e9..4cde2e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ pub enum Parent { unsafe impl Send for Parent {} pub trait WindowHandler { - type Message: Send; + type Message: Send + 'static; fn on_frame(&mut self); fn on_event(&mut self, window: &mut Window, event: Event); diff --git a/src/x11/window.rs b/src/x11/window.rs index 049ffc1..abc7fbf 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -8,12 +8,13 @@ use raw_window_handle::{ HasRawWindowHandle, RawWindowHandle }; +use rtrb::{RingBuffer, Producer, Consumer, PushError}; use super::XcbConnection; use crate::{ Event, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta, WindowEvent, WindowHandler, WindowInfo, WindowOpenOptions, - WindowScalePolicy, PhyPoint, PhySize, + WindowScalePolicy, PhyPoint, PhySize, MESSAGE_QUEUE_LEN, }; use super::keyboard::{convert_key_press_event, convert_key_release_event}; @@ -27,12 +28,11 @@ pub struct Window { frame_interval: Duration, event_loop_running: bool, - new_physical_size: Option + new_physical_size: Option, } pub struct WindowHandle { - // FIXME: replace this with channel sender - phantom_data: std::marker::PhantomData, + message_tx: Producer, } impl WindowHandle { @@ -40,7 +40,8 @@ impl WindowHandle { &mut self, message: H::Message ) -> Result<(), H::Message> { - Err(message) + self.message_tx.push(message) + .map_err(|PushError::Full(message)| message) } } @@ -69,8 +70,11 @@ impl Window { let (tx, rx) = mpsc::sync_channel::(1); + let (message_tx, message_rx) = RingBuffer::new(MESSAGE_QUEUE_LEN) + .split(); + let thread = thread::spawn(move || { - if let Err(e) = Self::window_thread::(options, build, tx.clone()) { + if let Err(e) = Self::window_thread::(options, build, tx.clone(), message_rx) { let _ = tx.send(Err(e)); } }); @@ -79,7 +83,7 @@ impl Window { let _ = rx.recv(); let window_handle = crate::WindowHandle(WindowHandle { - phantom_data: std::marker::PhantomData + message_tx }); let opt_app_runner = if is_not_parented { @@ -92,7 +96,9 @@ impl Window { } fn window_thread(options: WindowOpenOptions, build: B, - tx: mpsc::SyncSender) -> WindowOpenResult + tx: mpsc::SyncSender, + message_rx: Consumer, + ) -> WindowOpenResult where H: WindowHandler, B: FnOnce(&mut crate::Window) -> H, B: Send + 'static @@ -205,7 +211,7 @@ impl Window { let _ = tx.send(Ok(())); - window.run_event_loop(&mut handler); + window.run_event_loop(&mut handler, message_rx); Ok(()) } @@ -263,7 +269,7 @@ impl Window { // 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(&mut self, handler: &mut H) { + fn run_event_loop(&mut self, handler: &mut H, mut message_rx: Consumer) { use nix::poll::*; let xcb_fd = unsafe { @@ -299,6 +305,13 @@ impl Window { self.drain_xcb_events(handler); } } + + while let Ok(message) = message_rx.pop(){ + handler.on_message( + &mut crate::Window(self), + message + ) + } } }