diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index cd2c66e84b8..84ef6deed95 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -1003,7 +1003,8 @@ impl IOCompositor { if pipeline_details.animations_running || pipeline_details.animation_callbacks_running { - self.constellation_chan.0.send(ConstellationMsg::TickAnimation(*pipeline_id)).unwrap(); + self.constellation_chan.0.send(ConstellationMsg::TickAnimation(*pipeline_id)) + .unwrap(); } } } @@ -1064,7 +1065,10 @@ impl IOCompositor { if let Some(min_zoom) = self.min_viewport_zoom.as_ref() { viewport_zoom = min_zoom.get().max(viewport_zoom) } - let viewport_zoom = self.max_viewport_zoom.as_ref().map_or(1., |z| z.get()).min(viewport_zoom); + let viewport_zoom = self.max_viewport_zoom + .as_ref() + .map_or(1., |z| z.get()) + .min(viewport_zoom); let viewport_zoom = ScaleFactor::new(viewport_zoom); self.viewport_zoom = viewport_zoom; @@ -1355,7 +1359,12 @@ impl IOCompositor { rv } - fn draw_png(&self, framebuffer_ids: Vec, texture_ids: Vec, width: usize, height: usize) -> png::Image { + fn draw_png(&self, + framebuffer_ids: Vec, + texture_ids: Vec, + width: usize, + height: usize) + -> png::Image { let mut pixels = gl::read_pixels(0, 0, width as gl::GLsizei, height as gl::GLsizei, @@ -1489,7 +1498,7 @@ fn find_layer_with_pipeline_and_layer_id_for_layer(layer: Rc CompositorEventListener for IOCompositor where Window: WindowMethods { - fn handle_event(&mut self, msg: WindowEvent) -> bool { + fn handle_events(&mut self, messages: Vec) -> bool { // Check for new messages coming from the other tasks in the system. loop { match self.port.try_recv_compositor_msg() { @@ -1509,8 +1518,10 @@ impl CompositorEventListener for IOCompositor where Window: Wind return false; } - // Handle the message coming from the windowing system. - self.handle_window_message(msg); + // Handle any messages coming from the windowing system. + for message in messages.into_iter() { + self.handle_window_message(message); + } // If a pinch-zoom happened recently, ask for tiles at the new resolution if self.zoom_action && precise_time_s() - self.zoom_time > 0.3 { diff --git a/components/compositing/compositor_layer.rs b/components/compositing/compositor_layer.rs index 36e78aef207..0a37340c4f9 100644 --- a/components/compositing/compositor_layer.rs +++ b/components/compositing/compositor_layer.rs @@ -87,7 +87,8 @@ pub trait CompositorLayer { /// Destroys tiles for this layer and all descendent layers, sending the buffers back to the /// painter to be destroyed or reused. - fn clear_all_tiles(&self, compositor: &IOCompositor) where Window: WindowMethods; + fn clear_all_tiles(&self, compositor: &IOCompositor) + where Window: WindowMethods; /// Removes the root layer (and any children) for a given pipeline from the /// compositor. Buffers that the compositor is holding are returned to the diff --git a/components/compositing/compositor_task.rs b/components/compositing/compositor_task.rs index 10a49fa3928..904e69da83b 100644 --- a/components/compositing/compositor_task.rs +++ b/components/compositing/compositor_task.rs @@ -254,7 +254,7 @@ impl CompositorTask { } pub trait CompositorEventListener { - fn handle_event(&mut self, event: WindowEvent) -> bool; + fn handle_events(&mut self, events: Vec) -> bool; fn repaint_synchronously(&mut self); fn shutdown(&mut self); fn pinch_zoom_level(&self) -> f32; diff --git a/components/compositing/headless.rs b/components/compositing/headless.rs index 37aca5d1883..2f9aa30e744 100644 --- a/components/compositing/headless.rs +++ b/components/compositing/headless.rs @@ -66,7 +66,7 @@ impl NullCompositor { } impl CompositorEventListener for NullCompositor { - fn handle_event(&mut self, _: WindowEvent) -> bool { + fn handle_events(&mut self, _: Vec) -> bool { match self.port.recv_compositor_msg() { Msg::Exit(chan) => { debug!("shutting down the constellation"); diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index 4bfdf0fe2a9..bffe3c401f1 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -45,12 +45,11 @@ pub use constellation::Constellation; pub mod compositor_task; mod compositor_layer; -mod scrolling; - mod compositor; mod headless; +mod scrolling; pub mod pipeline; pub mod constellation; - pub mod windowing; + diff --git a/components/servo/lib.rs b/components/servo/lib.rs index c00f36eacbf..4f254d5f682 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -75,9 +75,9 @@ pub struct Browser { /// application Servo is embedded in. Clients then create an event /// loop to pump messages between the embedding application and /// various browser components. -impl Browser { +impl Browser { pub fn new(window: Option>) -> Browser - where Window: WindowMethods + 'static { + where Window: WindowMethods + 'static { // Global configuration options, parsed from the command line. let opts = opts::get(); @@ -124,8 +124,8 @@ impl Browser { } } - pub fn handle_event(&mut self, event: WindowEvent) -> bool { - self.compositor.handle_event(event) + pub fn handle_events(&mut self, events: Vec) -> bool { + self.compositor.handle_events(events) } pub fn repaint_synchronously(&mut self) { diff --git a/components/servo/main.rs b/components/servo/main.rs index bee05978b42..ef12ef2171a 100644 --- a/components/servo/main.rs +++ b/components/servo/main.rs @@ -64,17 +64,14 @@ fn main() { maybe_register_glutin_resize_handler(&window, &mut browser); - browser.browser.handle_event(WindowEvent::InitializeCompositing); + browser.browser.handle_events(vec![WindowEvent::InitializeCompositing]); // Feed events from the window to the browser until the browser // says to stop. loop { let should_continue = match window { - None => browser.browser.handle_event(WindowEvent::Idle), - Some(ref window) => { - let event = window.wait_events(); - browser.browser.handle_event(event) - } + None => browser.browser.handle_events(Vec::new()), + Some(ref window) => browser.browser.handle_events(window.wait_events()), }; if !should_continue { break @@ -123,7 +120,7 @@ impl app::NestedEventLoopListener for BrowserWrapper { WindowEvent::Resize(..) => true, _ => false, }; - if !self.browser.handle_event(event) { + if !self.browser.handle_events(vec![event]) { return false } if is_resize { diff --git a/ports/cef/browser.rs b/ports/cef/browser.rs index 0885897c8f7..8b2ab3b2b0f 100644 --- a/ports/cef/browser.rs +++ b/ports/cef/browser.rs @@ -32,8 +32,8 @@ pub enum ServoBrowser { impl ServoBrowser { fn handle_event(&mut self, event: WindowEvent) { match *self { - ServoBrowser::OnScreen(ref mut browser) => { browser.handle_event(event); } - ServoBrowser::OffScreen(ref mut browser) => { browser.handle_event(event); } + ServoBrowser::OnScreen(ref mut browser) => { browser.handle_events(vec![event]); } + ServoBrowser::OffScreen(ref mut browser) => { browser.handle_events(vec![event]); } ServoBrowser::Invalid => {} } } diff --git a/ports/cef/window.rs b/ports/cef/window.rs index e6d51118497..06104484475 100644 --- a/ports/cef/window.rs +++ b/ports/cef/window.rs @@ -100,8 +100,8 @@ impl Window { } /// Currently unimplemented. - pub fn wait_events(&self) -> WindowEvent { - WindowEvent::Idle + pub fn wait_events(&self) -> Vec { + vec![WindowEvent::Idle] } fn cursor_type_for_cursor(&self, cursor: Cursor) -> cef_cursor_type_t { diff --git a/ports/glutin/window.rs b/ports/glutin/window.rs index fa81f3b5db4..1878389ced3 100644 --- a/ports/glutin/window.rs +++ b/ports/glutin/window.rs @@ -14,13 +14,15 @@ use layers::geometry::DevicePixel; use layers::platform::surface::NativeGraphicsMetadata; use msg::constellation_msg; use msg::constellation_msg::Key; -use NestedEventLoopListener; +use std::mem; use std::rc::Rc; use std::sync::mpsc::{channel, Sender}; use url::Url; use util::cursor::Cursor; use util::geometry::ScreenPx; +use NestedEventLoopListener; + #[cfg(feature = "window")] use compositing::windowing::{MouseWindowEvent, WindowNavigateMsg}; #[cfg(feature = "window")] @@ -259,7 +261,16 @@ impl Window { #[cfg(target_os="macos")] fn handle_next_event(&self) -> bool { let event = self.window.wait_events().next().unwrap(); - self.handle_window_event(event) + let mut close = self.handle_window_event(event); + if !close { + while let Some(event) = self.window.poll_events().next() { + if self.handle_window_event(event) { + close = true; + break + } + } + } + close } #[cfg(any(target_os="linux", target_os="android"))] @@ -283,7 +294,9 @@ impl Window { // // See https://github.com/servo/servo/issues/5780 // - match self.window.poll_events().next() { + let first_event = self.window.poll_events().next(); + + match first_event { Some(event) => { self.handle_window_event(event) } @@ -294,40 +307,27 @@ impl Window { } } - pub fn wait_events(&self) -> WindowEvent { - { - let mut event_queue = self.event_queue.borrow_mut(); - if !event_queue.is_empty() { - return event_queue.remove(0); - } - } - + pub fn wait_events(&self) -> Vec { + let mut events = mem::replace(&mut *self.event_queue.borrow_mut(), Vec::new()); let mut close_event = false; // When writing to a file then exiting, use event // polling so that we don't block on a GUI event // such as mouse click. if opts::get().output_file.is_some() { - for event in self.window.poll_events() { - close_event = self.handle_window_event(event); - if close_event { - break; - } + while let Some(event) = self.window.poll_events().next() { + close_event = self.handle_window_event(event) || close_event; } } else { close_event = self.handle_next_event(); } if close_event || self.window.is_closed() { - WindowEvent::Quit - } else { - let mut event_queue = self.event_queue.borrow_mut(); - if event_queue.is_empty() { - WindowEvent::Idle - } else { - event_queue.remove(0) - } + events.push(WindowEvent::Quit) } + + events.extend(mem::replace(&mut *self.event_queue.borrow_mut(), Vec::new()).into_iter()); + events } pub unsafe fn set_nested_event_loop_listener( @@ -634,8 +634,8 @@ impl Window { Rc::new(window) } - pub fn wait_events(&self) -> WindowEvent { - WindowEvent::Idle + pub fn wait_events(&self) -> Vec { + vec![WindowEvent::Idle] } pub unsafe fn set_nested_event_loop_listener( diff --git a/ports/gonk/src/main.rs b/ports/gonk/src/main.rs index 335fdd361b6..f8324d531fc 100644 --- a/ports/gonk/src/main.rs +++ b/ports/gonk/src/main.rs @@ -76,16 +76,16 @@ fn main() { Some(ref window) => input::run_input_loop(&window.event_send) } - browser.browser.handle_event(WindowEvent::InitializeCompositing); + browser.browser.handle_events(vec![WindowEvent::InitializeCompositing]); // Feed events from the window to the browser until the browser // says to stop. loop { let should_continue = match window { - None => browser.browser.handle_event(WindowEvent::Idle), + None => browser.browser.handle_events(vec![WindowEvent::Idle]), Some(ref window) => { - let event = window.wait_events(); - browser.browser.handle_event(event) + let events = window.wait_events(); + browser.browser.handle_events(events) } }; if !should_continue { diff --git a/ports/gonk/src/window.rs b/ports/gonk/src/window.rs index a718123e6de..c6c60088232 100644 --- a/ports/gonk/src/window.rs +++ b/ports/gonk/src/window.rs @@ -754,8 +754,8 @@ impl Window { Rc::new(window) } - pub fn wait_events(&self) -> WindowEvent { - self.event_recv.recv().unwrap() + pub fn wait_events(&self) -> Vec { + vec![self.event_recv.recv().unwrap()] } }