From f363c09f4125f539b25874a0bd4724944a6a7320 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Thu, 27 Jun 2013 20:33:56 -0600 Subject: [PATCH 1/4] Add detection for page loads. --- .../main/platform/common/glfw_windowing.rs | 13 +++++++++++-- src/components/msg/compositor_msg.rs | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/main/platform/common/glfw_windowing.rs b/src/components/main/platform/common/glfw_windowing.rs index 6f9c509f245..f756ad02513 100644 --- a/src/components/main/platform/common/glfw_windowing.rs +++ b/src/components/main/platform/common/glfw_windowing.rs @@ -13,7 +13,7 @@ use std::libc::c_int; use geom::point::Point2D; use geom::size::Size2D; use servo_msg::compositor_msg::{IdleRenderState, RenderState, RenderingRenderState}; -use servo_msg::compositor_msg::{FinishedLoading, Loading, PerformingLayout, ReadyState}; +use servo_msg::compositor_msg::{FinishedLoading, Blank, Loading, PerformingLayout, ReadyState}; use glfw; @@ -79,7 +79,7 @@ impl WindowMethods for Window { mouse_down_button: @mut 0, mouse_down_point: @mut Point2D(0 as c_int, 0), - ready_state: FinishedLoading, + ready_state: Blank, render_state: IdleRenderState, throbber_frame: 0, }; @@ -168,6 +168,12 @@ impl WindowMethods for Window { /// Sets the render state. pub fn set_render_state(@mut self, render_state: RenderState) { + if self.ready_state == FinishedLoading && + self.render_state == RenderingRenderState && + render_state == IdleRenderState { + // page loaded + } + self.render_state = render_state; self.update_window_title() } @@ -178,6 +184,9 @@ impl Window { fn update_window_title(&self) { let throbber = THROBBER[self.throbber_frame]; match self.ready_state { + Blank => { + self.glfw_window.set_title(fmt!("blank — Servo")); + } Loading => { self.glfw_window.set_title(fmt!("%c Loading — Servo", throbber)) } diff --git a/src/components/msg/compositor_msg.rs b/src/components/msg/compositor_msg.rs index 49d98e383f2..2f1d88f33fb 100644 --- a/src/components/msg/compositor_msg.rs +++ b/src/components/msg/compositor_msg.rs @@ -40,7 +40,10 @@ pub enum RenderState { RenderingRenderState, } +#[deriving(Eq)] pub enum ReadyState { + /// Informs the compositor that nothing has been done yet. Used for setting status + Blank, /// Informs the compositor that a page is loading. Used for setting status Loading, /// Informs the compositor that a page is performing layout. Used for setting status From 2f0a79216596d20240a4c761dd7dc3d3a5e4ba37 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Thu, 11 Jul 2013 15:32:48 -0600 Subject: [PATCH 2/4] Add exit_after_load flag to options, and make them cloneable. --- src/components/gfx/opts.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/gfx/opts.rs b/src/components/gfx/opts.rs index d3671939c42..cba8d517587 100644 --- a/src/components/gfx/opts.rs +++ b/src/components/gfx/opts.rs @@ -12,12 +12,14 @@ use std::float; use std::result; use std::uint; +#[deriving(Clone)] pub struct Opts { urls: ~[~str], render_backend: BackendType, n_render_threads: uint, tile_size: uint, profiler_period: Option, + exit_after_load: bool, } #[allow(non_implicitly_copyable_typarams)] @@ -32,6 +34,7 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts { getopts::optopt("s"), // size of tiles getopts::optopt("t"), // threads to render with getopts::optflagopt("p"), // profiler flag and output interval + getopts::optflag("x"), // exit after load flag ]; let opt_match = match getopts::getopts(args, opts) { @@ -85,11 +88,14 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts { None => None, }; + let exit_after_load = getopts::opt_present(&opt_match, "x"); + Opts { urls: urls, render_backend: render_backend, n_render_threads: n_render_threads, tile_size: tile_size, profiler_period: profiler_period, + exit_after_load: exit_after_load, } } From eda76452587efa393766afd9f31ba7cd7861f2cf Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Thu, 11 Jul 2013 15:33:48 -0600 Subject: [PATCH 3/4] Update rust-azure pointer to get cloneable BackendType. --- src/support/azure/rust-azure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/support/azure/rust-azure b/src/support/azure/rust-azure index ba24db51b38..ae7c99be106 160000 --- a/src/support/azure/rust-azure +++ b/src/support/azure/rust-azure @@ -1 +1 @@ -Subproject commit ba24db51b38c9875e1356f7bc08c13a683071710 +Subproject commit ae7c99be106e5767b0384f16887579d55e222e71 From 6ab28c8e347449fa6f286f4bb3007f88ddd846d6 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Thu, 11 Jul 2013 15:34:07 -0600 Subject: [PATCH 4/4] 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);