From 7d6b4c3fe5b6445b1ec7bf03f1c1e9efe9453180 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Mon, 23 Jan 2017 23:25:41 -0500 Subject: [PATCH 1/2] Naive implementation of resize events for OS X. These events are batched, and delievered en masse at the end of the resize. This isn't a great developer experience (and it should probably be called out in the docs), but it makes it possible for winit client applications to detect and respond to resizes without special-casing Mac OS targets. See #39. This is only a partial fix, and does not provide on-the-fly resize events. --- src/platform/macos/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index bd06414b..8b73d66b 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -75,13 +75,15 @@ impl WindowDelegate { // need to notify context before (?) event // let _: () = msg_send![*state.context, update]; + let rect = NSView::frame(*state.view); + let scale_factor = NSWindow::backingScaleFactor(*state.window) as f32; + let width = (scale_factor * rect.size.width as f32) as u32; + let height = (scale_factor * rect.size.height as f32) as u32; if let Some(handler) = state.resize_handler { - let rect = NSView::frame(*state.view); - let scale_factor = NSWindow::backingScaleFactor(*state.window) as f32; - (handler)((scale_factor * rect.size.width as f32) as u32, - (scale_factor * rect.size.height as f32) as u32); + (handler)(width, height); } + (*state).pending_events.lock().unwrap().push_back(Event::Resized(width, height)); } } From 6f82ccfba9278019bb0e08cffa1b29a3a73530ea Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 24 Jan 2017 12:39:35 -0500 Subject: [PATCH 2/2] De-duplicate resize events. This tracks resizes separately, and synthesizes them for the event iterators as needed, so that OS X apps don't generate a whole set of resize events after each resize. --- src/platform/macos/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 8b73d66b..3aadfe76 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -43,6 +43,7 @@ struct DelegateState { view: IdRef, window: IdRef, resize_handler: Option, + pending_resize: Mutex>, /// Events that have been retreived with XLib but not dispatched with iterators yet pending_events: Mutex>, @@ -83,7 +84,7 @@ impl WindowDelegate { if let Some(handler) = state.resize_handler { (handler)(width, height); } - (*state).pending_events.lock().unwrap().push_back(Event::Resized(width, height)); + *state.pending_resize.lock().unwrap() = Some((width, height)); } } @@ -211,6 +212,10 @@ impl<'a> Iterator for PollEventsIterator<'a> { type Item = Event; fn next(&mut self) -> Option { + if let Some((width, height)) = self.window.delegate.state.pending_resize.lock().unwrap().take() { + return Some(Event::Resized(width, height)); + } + if let Some(ev) = self.window.delegate.state.pending_events.lock().unwrap().pop_front() { return Some(ev); } @@ -240,6 +245,10 @@ impl<'a> Iterator for WaitEventsIterator<'a> { type Item = Event; fn next(&mut self) -> Option { + if let Some((width, height)) = self.window.delegate.state.pending_resize.lock().unwrap().take() { + return Some(Event::Resized(width, height)); + } + if let Some(ev) = self.window.delegate.state.pending_events.lock().unwrap().pop_front() { return Some(ev); } @@ -313,6 +322,7 @@ impl Window { view: view.clone(), window: window.clone(), resize_handler: None, + pending_resize: Mutex::new(None), pending_events: Mutex::new(VecDeque::new()), };