diff --git a/src/lib.rs b/src/lib.rs index d03dc60..fb84d94 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -use std::ffi::c_void; +use raw_window_handle::RawWindowHandle; #[cfg(target_os = "windows")] mod win; @@ -25,7 +25,7 @@ pub use mouse_cursor::MouseCursor; pub enum Parent { None, AsIfParented, - WithParent(*mut c_void), + WithParent(RawWindowHandle), } unsafe impl Send for Parent {} diff --git a/src/win/window.rs b/src/win/window.rs index 81a9439..6e077a6 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -16,7 +16,11 @@ use std::ffi::c_void; use std::ptr::null_mut; use std::rc::Rc; -use raw_window_handle::{windows::WindowsHandle, HasRawWindowHandle, RawWindowHandle}; +use raw_window_handle::{ + windows::WindowsHandle, + HasRawWindowHandle, + RawWindowHandle +}; use crate::{ Event, KeyboardEvent, MouseButton, MouseEvent, Parent::WithParent, ScrollDelta, WindowEvent, @@ -187,11 +191,13 @@ impl Window { // todo: add check flags https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L351 let parent = match options.parent { - WithParent(p) => { + WithParent(RawWindowHandle::Windows(h)) => { flags = WS_CHILD | WS_VISIBLE; - p + h.hwnd } + WithParent(h) => panic!("unsupported parent handle {:?}", h), + _ => { AdjustWindowRectEx(&mut rect, flags, FALSE, 0); null_mut() diff --git a/src/x11/window.rs b/src/x11/window.rs index 4ad84b4..ef4e00b 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -3,7 +3,11 @@ use std::sync::mpsc; use std::time::*; use std::thread; -use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle}; +use raw_window_handle::{ + unix::XlibHandle, + HasRawWindowHandle, + RawWindowHandle +}; use super::XcbConnection; use crate::{ @@ -19,6 +23,8 @@ pub struct Window { frame_interval: Duration, event_loop_running: bool, + + new_size: Option<(u32, u32)> } // FIXME: move to outer crate context @@ -68,7 +74,11 @@ impl Window { // Convert parent into something that X understands let parent_id = match options.parent { - Parent::WithParent(p) => p as u32, + Parent::WithParent(RawWindowHandle::Xlib(h)) => h.window as u32, + Parent::WithParent(RawWindowHandle::Xcb(h)) => h.window, + Parent::WithParent(h) => + panic!("unsupported parent handle type {:?}", h), + Parent::None | Parent::AsIfParented => screen.root(), }; @@ -150,6 +160,8 @@ impl Window { frame_interval: Duration::from_millis(15), event_loop_running: false, + + new_size: None }; let mut handler = H::build(&mut window); @@ -193,9 +205,23 @@ impl Window { #[inline] fn drain_xcb_events(&mut self, handler: &mut H) { + // the X server has a tendency to send spurious/extraneous configure notify events when a + // window is resized, and we need to batch those together and just send one resize event + // when they've all been coalesced. + self.new_size = None; + while let Some(event) = self.xcb_connection.conn.poll_for_event() { self.handle_xcb_event(handler, event); } + + if let Some((width, height)) = self.new_size.take() { + self.window_info.width = width; + self.window_info.height = height; + + handler.on_event(self, Event::Window( + WindowEvent::Resized(self.window_info) + )) + } } // Event loop @@ -293,14 +319,7 @@ impl Window { xcb::CONFIGURE_NOTIFY => { let event = unsafe { xcb::cast_event::(&event) }; - if self.window_info.width != event.width() as u32 - || self.window_info.height != event.height() as u32 - { - self.window_info.width = event.width() as u32; - self.window_info.height = event.height() as u32; - - handler.on_event(self, Event::Window(WindowEvent::Resized(self.window_info))) - } + self.new_size = Some((event.width() as u32, event.height() as u32)); } ////