implement try_send_message for Linux
This commit is contained in:
parent
72d55c9dba
commit
f696c7d14d
|
@ -32,7 +32,7 @@ pub enum Parent {
|
||||||
unsafe impl Send for Parent {}
|
unsafe impl Send for Parent {}
|
||||||
|
|
||||||
pub trait WindowHandler {
|
pub trait WindowHandler {
|
||||||
type Message: Send;
|
type Message: Send + 'static;
|
||||||
|
|
||||||
fn on_frame(&mut self);
|
fn on_frame(&mut self);
|
||||||
fn on_event(&mut self, window: &mut Window, event: Event);
|
fn on_event(&mut self, window: &mut Window, event: Event);
|
||||||
|
|
|
@ -8,12 +8,13 @@ use raw_window_handle::{
|
||||||
HasRawWindowHandle,
|
HasRawWindowHandle,
|
||||||
RawWindowHandle
|
RawWindowHandle
|
||||||
};
|
};
|
||||||
|
use rtrb::{RingBuffer, Producer, Consumer, PushError};
|
||||||
|
|
||||||
use super::XcbConnection;
|
use super::XcbConnection;
|
||||||
use crate::{
|
use crate::{
|
||||||
Event, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta,
|
Event, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta,
|
||||||
WindowEvent, WindowHandler, WindowInfo, WindowOpenOptions,
|
WindowEvent, WindowHandler, WindowInfo, WindowOpenOptions,
|
||||||
WindowScalePolicy, PhyPoint, PhySize,
|
WindowScalePolicy, PhyPoint, PhySize, MESSAGE_QUEUE_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::keyboard::{convert_key_press_event, convert_key_release_event};
|
use super::keyboard::{convert_key_press_event, convert_key_release_event};
|
||||||
|
@ -27,12 +28,11 @@ pub struct Window {
|
||||||
frame_interval: Duration,
|
frame_interval: Duration,
|
||||||
event_loop_running: bool,
|
event_loop_running: bool,
|
||||||
|
|
||||||
new_physical_size: Option<PhySize>
|
new_physical_size: Option<PhySize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowHandle<H: WindowHandler> {
|
pub struct WindowHandle<H: WindowHandler> {
|
||||||
// FIXME: replace this with channel sender
|
message_tx: Producer<H::Message>,
|
||||||
phantom_data: std::marker::PhantomData<H::Message>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <H: WindowHandler>WindowHandle<H> {
|
impl <H: WindowHandler>WindowHandle<H> {
|
||||||
|
@ -40,7 +40,8 @@ impl <H: WindowHandler>WindowHandle<H> {
|
||||||
&mut self,
|
&mut self,
|
||||||
message: H::Message
|
message: H::Message
|
||||||
) -> Result<(), 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::<WindowOpenResult>(1);
|
let (tx, rx) = mpsc::sync_channel::<WindowOpenResult>(1);
|
||||||
|
|
||||||
|
let (message_tx, message_rx) = RingBuffer::new(MESSAGE_QUEUE_LEN)
|
||||||
|
.split();
|
||||||
|
|
||||||
let thread = thread::spawn(move || {
|
let thread = thread::spawn(move || {
|
||||||
if let Err(e) = Self::window_thread::<H, B>(options, build, tx.clone()) {
|
if let Err(e) = Self::window_thread::<H, B>(options, build, tx.clone(), message_rx) {
|
||||||
let _ = tx.send(Err(e));
|
let _ = tx.send(Err(e));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -79,7 +83,7 @@ impl Window {
|
||||||
let _ = rx.recv();
|
let _ = rx.recv();
|
||||||
|
|
||||||
let window_handle = crate::WindowHandle(WindowHandle {
|
let window_handle = crate::WindowHandle(WindowHandle {
|
||||||
phantom_data: std::marker::PhantomData
|
message_tx
|
||||||
});
|
});
|
||||||
|
|
||||||
let opt_app_runner = if is_not_parented {
|
let opt_app_runner = if is_not_parented {
|
||||||
|
@ -92,7 +96,9 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window_thread<H, B>(options: WindowOpenOptions, build: B,
|
fn window_thread<H, B>(options: WindowOpenOptions, build: B,
|
||||||
tx: mpsc::SyncSender<WindowOpenResult>) -> WindowOpenResult
|
tx: mpsc::SyncSender<WindowOpenResult>,
|
||||||
|
message_rx: Consumer<H::Message>,
|
||||||
|
) -> WindowOpenResult
|
||||||
where H: WindowHandler,
|
where H: WindowHandler,
|
||||||
B: FnOnce(&mut crate::Window) -> H,
|
B: FnOnce(&mut crate::Window) -> H,
|
||||||
B: Send + 'static
|
B: Send + 'static
|
||||||
|
@ -205,7 +211,7 @@ impl Window {
|
||||||
|
|
||||||
let _ = tx.send(Ok(()));
|
let _ = tx.send(Ok(()));
|
||||||
|
|
||||||
window.run_event_loop(&mut handler);
|
window.run_event_loop(&mut handler, message_rx);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +269,7 @@ impl Window {
|
||||||
// FIXME: poll() acts fine on linux, sometimes funky on *BSD. XCB upstream uses a define to
|
// 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
|
// switch between poll() and select() (the latter of which is fine on *BSD), and we should do
|
||||||
// the same.
|
// the same.
|
||||||
fn run_event_loop<H: WindowHandler>(&mut self, handler: &mut H) {
|
fn run_event_loop<H: WindowHandler>(&mut self, handler: &mut H, mut message_rx: Consumer<H::Message>) {
|
||||||
use nix::poll::*;
|
use nix::poll::*;
|
||||||
|
|
||||||
let xcb_fd = unsafe {
|
let xcb_fd = unsafe {
|
||||||
|
@ -299,6 +305,13 @@ impl Window {
|
||||||
self.drain_xcb_events(handler);
|
self.drain_xcb_events(handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while let Ok(message) = message_rx.pop(){
|
||||||
|
handler.on_message(
|
||||||
|
&mut crate::Window(self),
|
||||||
|
message
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue