diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-06-16 08:53:56 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-16 08:53:56 -0500 |
commit | d620ab71c41431c3fb040162f554faefb9abfbd7 (patch) | |
tree | 902c90598821bee9998194bb14f65c7b3e9bbab9 /components/script/timers.rs | |
parent | ff67f80f36106cba4a89c48d8c8d59c9880856c7 (diff) | |
parent | 2bff131535987da0330737f78fb23291593db30d (diff) | |
download | servo-d620ab71c41431c3fb040162f554faefb9abfbd7.tar.gz servo-d620ab71c41431c3fb040162f554faefb9abfbd7.zip |
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 -->
Diffstat (limited to 'components/script/timers.rs')
-rw-r--r-- | components/script/timers.rs | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/components/script/timers.rs b/components/script/timers.rs index 504dbb8aaaf..989382e80fe 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -22,6 +22,7 @@ use std::cmp::{self, Ord, Ordering}; use std::collections::HashMap; use std::default::Default; use std::rc::Rc; +use util::prefs::get_pref; #[derive(JSTraceable, PartialEq, Eq, Copy, Clone, HeapSizeOf, Hash, PartialOrd, Ord, Debug)] pub struct OneshotTimerHandle(i32); @@ -212,6 +213,15 @@ impl OneshotTimers { } } + pub fn slow_down(&self) { + let duration = get_pref("js.timers.minimum_duration").as_u64().unwrap_or(1000); + self.js_timers.set_min_duration(MsDuration::new(duration)); + } + + pub fn speed_up(&self) { + self.js_timers.remove_min_duration(); + } + pub fn suspend(&self) { assert!(self.suspended_since.get().is_none()); @@ -290,6 +300,8 @@ pub struct JsTimers { active_timers: DOMRefCell<HashMap<JsTimerHandle, JsTimerEntry>>, /// The nesting level of the currently executing timer task or 0. nesting_level: Cell<u32>, + /// Used to introduce a minimum delay in event intervals + min_duration: Cell<Option<MsDuration>>, } #[derive(JSTraceable, HeapSizeOf)] @@ -344,6 +356,7 @@ impl JsTimers { next_timer_handle: Cell::new(JsTimerHandle(1)), active_timers: DOMRefCell::new(HashMap::new()), nesting_level: Cell::new(0), + min_duration: Cell::new(None), } } @@ -407,6 +420,24 @@ impl JsTimers { } } + pub fn set_min_duration(&self, duration: MsDuration) { + self.min_duration.set(Some(duration)); + } + + pub fn remove_min_duration(&self) { + self.min_duration.set(None); + } + + // see step 13 of https://html.spec.whatwg.org/multipage/#timer-initialisation-steps + fn user_agent_pad(&self, current_duration: MsDuration) -> MsDuration { + match self.min_duration.get() { + Some(min_duration) => { + cmp::max(min_duration, current_duration) + }, + None => current_duration + } + } + // see https://html.spec.whatwg.org/multipage/#timer-initialisation-steps fn initialize_and_schedule(&self, global: GlobalRef, mut task: JsTimerTask) { let handle = task.handle; @@ -415,13 +446,12 @@ impl JsTimers { // step 6 let nesting_level = self.nesting_level.get(); - // step 7 - let duration = clamp_duration(nesting_level, task.duration); - + // step 7, 13 + let duration = self.user_agent_pad(clamp_duration(nesting_level, task.duration)); // step 8, 9 task.nesting_level = nesting_level + 1; - // essentially step 11-14 + // essentially step 11, 12, and 14 let callback = OneshotTimerCallback::JsTimer(task); let oneshot_handle = global.schedule_callback(callback, duration); |