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, } } diff --git a/src/components/main/compositing/mod.rs b/src/components/main/compositing/mod.rs index 0d8910ba254..c6f435c78d3 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"); @@ -499,8 +506,6 @@ impl CompositorTask { *recomposite = true; } - - // When the user pinch-zooms, scale the layer do window.set_zoom_callback |magnification| { *zoom_action = true; @@ -540,6 +545,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 850ce3e09a5..0c7adb87189 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}; @@ -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; @@ -45,6 +45,7 @@ pub struct Window { scroll_callback: Option, zoom_callback: Option, navigation_callback: Option, + finished_callback: Option, drag_origin: Point2D, @@ -73,13 +74,14 @@ impl WindowMethods for Window { scroll_callback: None, zoom_callback: None, navigation_callback: None, + finished_callback: None, drag_origin: Point2D(0 as c_int, 0), 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, }; @@ -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) -> bool { glfw::poll_events(); @@ -169,6 +175,16 @@ 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 + for self.finished_callback.iter().advance |&callback| { + callback(); + } + } + self.render_state = render_state; self.update_window_title() } @@ -179,6 +195,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/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 6d1c4a30d41..cee4850cc4f 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. Returns whether the window should close. pub fn check_loop(@mut self) -> bool; 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 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