aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/window.rs
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2016-06-08 18:46:02 -0700
committerPatrick Walton <pcwalton@mimiga.net>2016-06-10 18:43:04 -0700
commit041cfe6d0a07882819ae35380c286e7fe09c1013 (patch)
tree464033c42b2417f4f993e70840ea8a2bae03b3c9 /components/script/dom/window.rs
parentce88b8ed30feff9c7d3f067041fe5d781e012351 (diff)
downloadservo-041cfe6d0a07882819ae35380c286e7fe09c1013.tar.gz
servo-041cfe6d0a07882819ae35380c286e7fe09c1013.zip
script: When using WebRender, keep the DOM-side scroll positions for
elements with `overflow: scroll` up to date, and take them into account when doing hit testing. Closes #11648.
Diffstat (limited to 'components/script/dom/window.rs')
-rw-r--r--components/script/dom/window.rs37
1 files changed, 35 insertions, 2 deletions
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 4bfbb1993d1..34f7c1acdb0 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -12,6 +12,7 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnBeforeUnloadEventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
+use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods};
use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception};
@@ -68,7 +69,7 @@ use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSourc
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::cell::Cell;
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::ffi::CString;
use std::io::{Write, stderr, stdout};
@@ -264,6 +265,9 @@ pub struct Window {
error_reporter: CSSErrorReporter,
+ /// A list of scroll offsets for each scrollable element.
+ scroll_offsets: DOMRefCell<HashMap<UntrustedNodeAddress, Point2D<f32>>>,
+
#[ignore_heap_size_of = "Defined in ipc-channel"]
panic_chan: IpcSender<PanicMsg>,
}
@@ -354,6 +358,13 @@ impl Window {
pub fn css_error_reporter(&self) -> Box<ParseErrorReporter + Send> {
self.error_reporter.clone()
}
+
+ /// Sets a new list of scroll offsets.
+ ///
+ /// This is called when layout gives us new ones and WebRender is in use.
+ pub fn set_scroll_offsets(&self, offsets: HashMap<UntrustedNodeAddress, Point2D<f32>>) {
+ *self.scroll_offsets.borrow_mut() = offsets
+ }
}
#[cfg(any(target_os = "macos", target_os = "linux"))]
@@ -1243,7 +1254,28 @@ impl Window {
self.layout_rpc.node_overflow().0.unwrap()
}
- pub fn scroll_offset_query(&self, node: TrustedNodeAddress) -> Point2D<f32> {
+ pub fn scroll_offset_query(&self, node: &Node) -> Point2D<f32> {
+ // WebRender always keeps the scroll offsets up to date and stored here in the window. So,
+ // if WR is in use, all we need to do is to check our list of scroll offsets and return the
+ // result.
+ if opts::get().use_webrender {
+ let mut node = Root::from_ref(node);
+ loop {
+ if let Some(scroll_offset) = self.scroll_offsets
+ .borrow()
+ .get(&node.to_untrusted_node_address()) {
+ return *scroll_offset
+ }
+ node = match node.GetParentNode() {
+ Some(node) => node,
+ None => break,
+ }
+ }
+ let offset = self.current_viewport.get().origin;
+ return Point2D::new(offset.x.to_f32_px(), offset.y.to_f32_px())
+ }
+
+ let node = node.to_trusted_node_address();
if !self.reflow(ReflowGoal::ForScriptQuery,
ReflowQueryType::NodeLayerIdQuery(node),
ReflowReason::Query) {
@@ -1642,6 +1674,7 @@ impl Window {
webdriver_script_chan: DOMRefCell::new(None),
ignore_further_async_events: Arc::new(AtomicBool::new(false)),
error_reporter: error_reporter,
+ scroll_offsets: DOMRefCell::new(HashMap::new()),
panic_chan: panic_chan,
};