Auto merge of #10225 - jmr0:visibility_api, r=jdm

Implement non-visible pipeline and iframe visibility methods

This addresses #9566 and a good part of #9751, specifically:

* Pipeline has a notion of visibility
* IFrame setVisible/getVisible interface with IFrame's pipeline visibility
* IFrame mozbrowservisibilitychange responds to changes in visibility
* Pipeline visibility is used to limit animations (requestAnimationFrame does not tick animations when hidden) and to increase timer intervals (currently set to a minimum of 1 second while hidden)

Absent for now are any changes to the Document API and general implementation of the Page Visibility API, since the more interesting parts require knowledge of whether the user agent is minimized, OS screen locked, etc.

cc @paulrouget @jdm

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10225)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-06-16 08:53:56 -05:00 committed by GitHub
commit d620ab71c4
14 changed files with 382 additions and 24 deletions

View file

@ -290,6 +290,9 @@ struct PipelineDetails {
/// Whether there are animation callbacks
animation_callbacks_running: bool,
/// Whether this pipeline is visible
visible: bool,
}
impl PipelineDetails {
@ -299,6 +302,7 @@ impl PipelineDetails {
current_epoch: Epoch(0),
animations_running: false,
animation_callbacks_running: false,
visible: true,
}
}
}
@ -760,6 +764,13 @@ impl<Window: WindowMethods> IOCompositor<Window> {
reports_chan.send(reports);
}
(Msg::PipelineVisibilityChanged(pipeline_id, visible), ShutdownState::NotShuttingDown) => {
self.pipeline_details(pipeline_id).visible = visible;
if visible {
self.process_animations();
}
}
(Msg::PipelineExited(pipeline_id, sender), _) => {
debug!("Compositor got pipeline exited: {:?}", pipeline_id);
self.pending_subpages.remove(&pipeline_id);
@ -795,13 +806,16 @@ impl<Window: WindowMethods> IOCompositor<Window> {
animation_state: AnimationState) {
match animation_state {
AnimationState::AnimationsPresent => {
let visible = self.pipeline_details(pipeline_id).visible;
self.pipeline_details(pipeline_id).animations_running = true;
self.composite_if_necessary(CompositingReason::Animation);
if visible {
self.composite_if_necessary(CompositingReason::Animation);
}
}
AnimationState::AnimationCallbacksPresent => {
if !self.pipeline_details(pipeline_id).animation_callbacks_running {
self.pipeline_details(pipeline_id).animation_callbacks_running =
true;
let visible = self.pipeline_details(pipeline_id).visible;
self.pipeline_details(pipeline_id).animation_callbacks_running = true;
if visible {
self.tick_animations_for_pipeline(pipeline_id);
}
}
@ -1712,9 +1726,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
fn process_animations(&mut self) {
let mut pipeline_ids = vec![];
for (pipeline_id, pipeline_details) in &self.pipeline_details {
if pipeline_details.animations_running ||
pipeline_details.animation_callbacks_running {
pipeline_ids.push(*pipeline_id);
if (pipeline_details.animations_running ||
pipeline_details.animation_callbacks_running) &&
pipeline_details.visible {
pipeline_ids.push(*pipeline_id);
}
}
for pipeline_id in &pipeline_ids {

View file

@ -183,6 +183,8 @@ pub enum Msg {
ResizeTo(Size2D<u32>),
/// Get scroll offset of a layer
GetScrollOffset(PipelineId, LayerId, IpcSender<Point2D<f32>>),
/// Pipeline visibility changed
PipelineVisibilityChanged(PipelineId, bool),
/// A pipeline was shut down.
// This message acts as a synchronization point between the constellation,
// when it shuts down a pipeline, to the compositor; when the compositor
@ -223,6 +225,7 @@ impl Debug for Msg {
Msg::GetClientWindow(..) => write!(f, "GetClientWindow"),
Msg::MoveTo(..) => write!(f, "MoveTo"),
Msg::ResizeTo(..) => write!(f, "ResizeTo"),
Msg::PipelineVisibilityChanged(..) => write!(f, "PipelineVisibilityChanged"),
Msg::PipelineExited(..) => write!(f, "PipelineExited"),
Msg::GetScrollOffset(..) => write!(f, "GetScrollOffset"),
}