From 6ab28c8e347449fa6f286f4bb3007f88ddd846d6 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Thu, 11 Jul 2013 15:34:07 -0600 Subject: [PATCH] Add finished callback to windowing, and implement exit after load. --- src/components/main/compositing/mod.rs | 25 +++++++++++++------ .../main/platform/common/glfw_windowing.rs | 12 ++++++++- src/components/main/servo.rc | 2 +- src/components/main/windowing.rs | 5 ++++ 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/components/main/compositing/mod.rs b/src/components/main/compositing/mod.rs index 3033afbb56d..f506190e279 100644 --- a/src/components/main/compositing/mod.rs +++ b/src/components/main/compositing/mod.rs @@ -15,6 +15,7 @@ use servo_msg::compositor_msg::{ReadyState, ScriptListener}; use servo_msg::constellation_msg::{CompositorAck, ConstellationChan}; use servo_msg::constellation_msg; use gfx::render_task::{RenderChan, ReRenderMsg}; +use gfx::opts::Opts; use azure::azure_hl::{DataSourceSurface, DrawTarget, SourceSurfaceMethods, current_gl_context}; use azure::azure::AzGLContext; @@ -162,17 +163,20 @@ impl ImageData for AzureDrawTargetImageData { } pub struct CompositorTask { + opts: Opts, port: Port, profiler_chan: ProfilerChan, shutdown_chan: SharedChan<()>, } impl CompositorTask { - pub fn new(port: Port, + pub fn new(opts: Opts, + port: Port, profiler_chan: ProfilerChan, shutdown_chan: Chan<()>) -> CompositorTask { CompositorTask { + opts: opts, port: port, profiler_chan: profiler_chan, shutdown_chan: SharedChan::new(shutdown_chan), @@ -180,13 +184,16 @@ impl CompositorTask { } /// Starts the compositor, which listens for messages on the specified port. - pub fn create(port: Port, - profiler_chan: ProfilerChan, - shutdown_chan: Chan<()>) { + pub fn create(opts: Opts, + port: Port, + profiler_chan: ProfilerChan, + shutdown_chan: Chan<()>) { let port = Cell::new(port); let shutdown_chan = Cell::new(shutdown_chan); + let opts = Cell::new(opts); do on_osmain { - let compositor_task = CompositorTask::new(port.take(), + let compositor_task = CompositorTask::new(opts.take(), + port.take(), profiler_chan.clone(), shutdown_chan.take()); debug!("preparing to enter main loop"); @@ -501,8 +508,6 @@ impl CompositorTask { *recomposite = true; } - - // When the user pinch-zooms, scale the layer do window.set_zoom_callback |magnification| { *zoom_action = true; @@ -542,6 +547,12 @@ impl CompositorTask { *recomposite = true; } + if self.opts.exit_after_load { + do window.set_finished_callback || { + *done = true; + } + } + // Enter the main event loop. while !*done { // Check for new messages coming from the rendering task. diff --git a/src/components/main/platform/common/glfw_windowing.rs b/src/components/main/platform/common/glfw_windowing.rs index f756ad02513..14345015a54 100644 --- a/src/components/main/platform/common/glfw_windowing.rs +++ b/src/components/main/platform/common/glfw_windowing.rs @@ -4,7 +4,7 @@ //! A windowing implementation using GLFW. -use windowing::{ApplicationMethods, LoadUrlCallback, MouseCallback}; +use windowing::{ApplicationMethods, LoadUrlCallback, MouseCallback, FinishedCallback}; use windowing::{ResizeCallback, ScrollCallback, WindowMethods, WindowMouseEvent, WindowClickEvent}; use windowing::{WindowMouseDownEvent, WindowMouseUpEvent, ZoomCallback, Forward, Back, NavigationCallback}; @@ -45,6 +45,7 @@ pub struct Window { scroll_callback: Option, zoom_callback: Option, navigation_callback: Option, + finished_callback: Option, drag_origin: Point2D, @@ -73,6 +74,7 @@ impl WindowMethods for Window { scroll_callback: None, zoom_callback: None, navigation_callback: None, + finished_callback: None, drag_origin: Point2D(0 as c_int, 0), @@ -153,6 +155,10 @@ impl WindowMethods for Window { self.navigation_callback = Some(new_navigation_callback) } + pub fn set_finished_callback(&mut self, new_finished_callback: FinishedCallback) { + self.finished_callback = Some(new_finished_callback) + } + /// Spins the event loop. pub fn check_loop(@mut self) { glfw::poll_events(); @@ -171,7 +177,11 @@ impl WindowMethods for Window { if self.ready_state == FinishedLoading && self.render_state == RenderingRenderState && render_state == IdleRenderState { + // page loaded + for self.finished_callback.iter().advance |&callback| { + callback(); + } } self.render_state = render_state; diff --git a/src/components/main/servo.rc b/src/components/main/servo.rc index 9841b096134..a009790daad 100755 --- a/src/components/main/servo.rc +++ b/src/components/main/servo.rc @@ -118,7 +118,7 @@ fn run(opts: &Opts) { // Create the compositor. let (compositor_port, compositor_chan) = comm::stream(); let compositor_chan = CompositorChan::new(compositor_chan); - CompositorTask::create(compositor_port, profiler_chan.clone(), shutdown_chan); + CompositorTask::create(opts.clone(), compositor_port, profiler_chan.clone(), shutdown_chan); // Create a Servo instance. diff --git a/src/components/main/windowing.rs b/src/components/main/windowing.rs index 1edd0114de1..05ceee4d327 100644 --- a/src/components/main/windowing.rs +++ b/src/components/main/windowing.rs @@ -37,6 +37,9 @@ pub type ZoomCallback = @fn(f32); /// Type of the function that is called when the user clicks backspace or shift-backspace pub type NavigationCallback = @fn(WindowNavigateMsg); +/// Type of the function that is called when the rendering is finished +pub type FinishedCallback = @fn(); + /// Methods for an abstract Application. pub trait ApplicationMethods { fn new() -> Self; @@ -62,6 +65,8 @@ pub trait WindowMethods { pub fn set_zoom_callback(&mut self, new_zoom_callback: ZoomCallback); /// Registers a callback to run when the user presses backspace or shift-backspace. pub fn set_navigation_callback(&mut self, new_navigation_callback: NavigationCallback); + /// Registers a callback to run when rendering is finished. + pub fn set_finished_callback(&mut self, new_finish_callback: FinishedCallback); /// Spins the event loop. pub fn check_loop(@mut self);