aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/compositing/compositor.rs21
-rw-r--r--components/gfx/display_list/mod.rs276
-rw-r--r--components/layout/query.rs4
-rw-r--r--components/layout_thread/lib.rs51
-rw-r--r--components/script/dom/document.rs6
-rw-r--r--components/script/dom/window.rs23
-rw-r--r--components/script_layout_interface/message.rs14
-rw-r--r--components/script_traits/lib.rs4
8 files changed, 221 insertions, 178 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index 55c183da777..52c617fb0bd 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -22,7 +22,7 @@ use net_traits::image::base::{Image, PixelFormat};
use profile_traits::time::{self, ProfilerCategory, profile};
use script_traits::{AnimationState, AnimationTickType, ConstellationControlMsg};
use script_traits::{ConstellationMsg, DevicePixel, LayoutControlMsg, LoadData, MouseButton};
-use script_traits::{MouseEventType, StackingContextScrollState};
+use script_traits::{MouseEventType, ScrollState};
use script_traits::{TouchpadPressurePhase, TouchEventType, TouchId, WindowSizeData, WindowSizeType};
use script_traits::CompositorEvent::{self, MouseMoveEvent, MouseButtonEvent, TouchEvent, TouchpadPressureEvent};
use servo_config::opts;
@@ -1368,29 +1368,26 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
fn send_viewport_rects(&self) {
- let mut stacking_context_scroll_states_per_pipeline = HashMap::new();
+ let mut scroll_states_per_pipeline = HashMap::new();
for scroll_layer_state in self.webrender_api.get_scroll_node_state() {
if scroll_layer_state.id.external_id().is_none() &&
- scroll_layer_state.id.is_root_scroll_node() {
+ !scroll_layer_state.id.is_root_scroll_node() {
continue;
}
- let stacking_context_scroll_state = StackingContextScrollState {
+ let scroll_state = ScrollState {
scroll_root_id: scroll_layer_state.id,
scroll_offset: scroll_layer_state.scroll_offset.to_untyped(),
};
- stacking_context_scroll_states_per_pipeline
- .entry(scroll_layer_state.id.pipeline_id())
- .or_insert(vec![])
- .push(stacking_context_scroll_state);
+ scroll_states_per_pipeline.entry(scroll_layer_state.id.pipeline_id())
+ .or_insert(vec![])
+ .push(scroll_state);
}
- for (pipeline_id, stacking_context_scroll_states) in
- stacking_context_scroll_states_per_pipeline {
+ for (pipeline_id, scroll_states) in scroll_states_per_pipeline {
if let Some(pipeline) = self.pipeline(pipeline_id.from_webrender()) {
- let msg = LayoutControlMsg::SetStackingContextScrollStates(
- stacking_context_scroll_states);
+ let msg = LayoutControlMsg::SetScrollStates(scroll_states);
let _ = pipeline.layout_chan.send(msg);
}
}
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index ac1db774f10..626c3f56b3d 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -47,6 +47,74 @@ pub struct DisplayList {
pub list: Vec<DisplayItem>,
}
+struct ScrollOffsetLookup<'a> {
+ parents: &'a mut HashMap<ClipId, ClipId>,
+ calculated_total_offsets: ScrollOffsetMap,
+ raw_offsets: &'a ScrollOffsetMap,
+}
+
+impl<'a> ScrollOffsetLookup<'a> {
+ fn new(parents: &'a mut HashMap<ClipId, ClipId>,
+ raw_offsets: &'a ScrollOffsetMap)
+ -> ScrollOffsetLookup<'a> {
+ ScrollOffsetLookup {
+ parents: parents,
+ calculated_total_offsets: HashMap::new(),
+ raw_offsets: raw_offsets,
+ }
+ }
+
+ fn new_for_reference_frame(&mut self,
+ clip_id: ClipId,
+ transform: &Matrix4D<f32>,
+ point: &mut Point2D<Au>)
+ -> Option<ScrollOffsetLookup> {
+ // If a transform function causes the current transformation matrix of an object
+ // to be non-invertible, the object and its content do not get displayed.
+ let inv_transform = match transform.inverse() {
+ Some(transform) => transform,
+ None => return None,
+ };
+
+ let scroll_offset = self.full_offset_for_scroll_root(&clip_id);
+ *point = Point2D::new(point.x - Au::from_f32_px(scroll_offset.x),
+ point.y - Au::from_f32_px(scroll_offset.y));
+ let frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(),
+ point.y.to_f32_px()));
+ *point = Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y));
+
+ let mut sublookup = ScrollOffsetLookup {
+ parents: &mut self.parents,
+ calculated_total_offsets: HashMap::new(),
+ raw_offsets: self.raw_offsets,
+ };
+ sublookup.calculated_total_offsets.insert(clip_id, Point2D::zero());
+ Some(sublookup)
+ }
+
+ fn add_scroll_root(&mut self, scroll_root: &ScrollRoot) {
+ self.parents.insert(scroll_root.id, scroll_root.parent_id);
+ }
+
+ fn full_offset_for_scroll_root(&mut self, id: &ClipId) -> Point2D<f32> {
+ if let Some(offset) = self.calculated_total_offsets.get(id) {
+ return *offset;
+ }
+
+ let parent_offset = if !id.is_root_scroll_node() {
+ let parent_id = *self.parents.get(id).unwrap();
+ self.full_offset_for_scroll_root(&parent_id)
+ } else {
+ Point2D::zero()
+ };
+
+ let offset = parent_offset +
+ self.raw_offsets.get(id).cloned().unwrap_or_else(Point2D::zero);
+ self.calculated_total_offsets.insert(*id, offset);
+ offset
+ }
+}
+
impl DisplayList {
/// Return the bounds of this display list based on the dimensions of the root
/// stacking context.
@@ -69,51 +137,36 @@ impl DisplayList {
self.text_index_contents(node,
&mut traversal,
client_point,
- client_point,
- scroll_offsets,
+ &mut ScrollOffsetLookup::new(&mut HashMap::new(), scroll_offsets),
&mut result);
result.pop()
}
- pub fn text_index_contents<'a>(&self,
- node: OpaqueNode,
- traversal: &mut DisplayListTraversal<'a>,
- translated_point: &Point2D<Au>,
- client_point: &Point2D<Au>,
- scroll_offsets: &ScrollOffsetMap,
- result: &mut Vec<usize>) {
+ fn text_index_contents<'a>(&self,
+ node: OpaqueNode,
+ traversal: &mut DisplayListTraversal<'a>,
+ point: &Point2D<Au>,
+ offset_lookup: &mut ScrollOffsetLookup,
+ result: &mut Vec<usize>) {
while let Some(item) = traversal.next() {
match item {
- &DisplayItem::PushStackingContext(ref stacking_context_item) => {
- let mut point = *translated_point;
- DisplayList::translate_point(&stacking_context_item.stacking_context,
- &mut point,
- client_point);
- self.text_index_contents(node,
- traversal,
- &point,
- client_point,
- scroll_offsets,
- result);
+ &DisplayItem::PushStackingContext(ref context_item) => {
+ self.text_index_stacking_context(&context_item.stacking_context,
+ item.base().scroll_root_id,
+ node,
+ traversal,
+ point,
+ offset_lookup,
+ result);
}
&DisplayItem::DefineClip(ref item) => {
- let mut point = *translated_point;
- DisplayList::scroll_root(&item.scroll_root,
- &mut point,
- scroll_offsets);
- self.text_index_contents(node,
- traversal,
- &point,
- client_point,
- scroll_offsets,
- result);
-
- },
+ offset_lookup.add_scroll_root(&item.scroll_root);
+ }
&DisplayItem::PopStackingContext(_) => return,
&DisplayItem::Text(ref text) => {
let base = item.base();
if base.metadata.node == node {
- let offset = *translated_point - text.baseline_origin;
+ let offset = *point - text.baseline_origin;
let index = text.text_run.range_index_of_advance(&text.range, offset.x);
result.push(index);
}
@@ -123,56 +176,71 @@ impl DisplayList {
}
}
+ fn text_index_stacking_context<'a>(&self,
+ stacking_context: &StackingContext,
+ clip_id: ClipId,
+ node: OpaqueNode,
+ traversal: &mut DisplayListTraversal<'a>,
+ point: &Point2D<Au>,
+ offset_lookup: &mut ScrollOffsetLookup,
+ result: &mut Vec<usize>) {
+ let mut point = *point - stacking_context.bounds.origin;
+ if stacking_context.scroll_policy == ScrollPolicy::Fixed {
+ let old_offset = offset_lookup.calculated_total_offsets.get(&clip_id).cloned();
+ offset_lookup.calculated_total_offsets.insert(clip_id, Point2D::zero());
+
+ self.text_index_contents(node, traversal, &point, offset_lookup, result);
+
+ match old_offset {
+ Some(offset) => offset_lookup.calculated_total_offsets.insert(clip_id, offset),
+ None => offset_lookup.calculated_total_offsets.remove(&clip_id),
+ };
+ } else if let Some(transform) = stacking_context.transform {
+ if let Some(ref mut sublookup) =
+ offset_lookup.new_for_reference_frame(clip_id, &transform, &mut point) {
+ self.text_index_contents(node, traversal, &point, sublookup, result);
+ }
+ } else {
+ self.text_index_contents(node, traversal, &point, offset_lookup, result);
+ }
+ }
+
// Return all nodes containing the point of interest, bottommost first, and
// respecting the `pointer-events` CSS property.
pub fn hit_test(&self,
- translated_point: &Point2D<Au>,
- client_point: &Point2D<Au>,
+ point: &Point2D<Au>,
scroll_offsets: &ScrollOffsetMap)
-> Vec<DisplayItemMetadata> {
let mut result = Vec::new();
let mut traversal = DisplayListTraversal::new(self);
self.hit_test_contents(&mut traversal,
- translated_point,
- client_point,
- scroll_offsets,
+ point,
+ &mut ScrollOffsetLookup::new(&mut HashMap::new(), scroll_offsets),
&mut result);
result
}
- pub fn hit_test_contents<'a>(&self,
- traversal: &mut DisplayListTraversal<'a>,
- translated_point: &Point2D<Au>,
- client_point: &Point2D<Au>,
- scroll_offsets: &ScrollOffsetMap,
- result: &mut Vec<DisplayItemMetadata>) {
+ fn hit_test_contents<'a>(&self,
+ traversal: &mut DisplayListTraversal<'a>,
+ point: &Point2D<Au>,
+ offset_lookup: &mut ScrollOffsetLookup,
+ result: &mut Vec<DisplayItemMetadata>) {
while let Some(item) = traversal.next() {
match item {
- &DisplayItem::PushStackingContext(ref stacking_context_item) => {
- let mut point = *translated_point;
- DisplayList::translate_point(&stacking_context_item.stacking_context,
- &mut point,
- client_point);
- self.hit_test_contents(traversal,
- &point,
- client_point,
- scroll_offsets,
- result);
+ &DisplayItem::PushStackingContext(ref context_item) => {
+ self.hit_test_stacking_context(&context_item.stacking_context,
+ item.base().scroll_root_id,
+ traversal,
+ point,
+ offset_lookup,
+ result);
}
+ &DisplayItem::PopStackingContext(_) => return,
&DisplayItem::DefineClip(ref item) => {
- let mut point = *translated_point;
- DisplayList::scroll_root(&item.scroll_root,
- &mut point,
- scroll_offsets);
- self.hit_test_contents(traversal,
- &point,
- client_point,
- scroll_offsets,
- result);
+ offset_lookup.add_scroll_root(&item.scroll_root);
}
- &DisplayItem::PopStackingContext(_) => return,
_ => {
- if let Some(meta) = item.hit_test(*translated_point) {
+ if let Some(meta) = item.hit_test(*point, offset_lookup) {
result.push(meta);
}
}
@@ -180,52 +248,33 @@ impl DisplayList {
}
}
- #[inline]
- fn translate_point<'a>(stacking_context: &StackingContext,
- translated_point: &mut Point2D<Au>,
- client_point: &Point2D<Au>) {
- // Convert the parent translated point into stacking context local transform space if the
- // stacking context isn't fixed. If it's fixed, we need to use the client point anyway.
+ fn hit_test_stacking_context<'a>(&self,
+ stacking_context: &StackingContext,
+ clip_id: ClipId,
+ traversal: &mut DisplayListTraversal<'a>,
+ point: &Point2D<Au>,
+ offset_lookup: &mut ScrollOffsetLookup,
+ result: &mut Vec<DisplayItemMetadata>) {
debug_assert!(stacking_context.context_type == StackingContextType::Real);
- let is_fixed = stacking_context.scroll_policy == ScrollPolicy::Fixed;
- *translated_point = if is_fixed {
- *client_point
- } else {
- let point = *translated_point - stacking_context.bounds.origin;
-
- match stacking_context.transform {
- Some(transform) => {
- let inv_transform = match transform.inverse() {
- Some(transform) => transform,
- None => {
- // If a transform function causes the current transformation matrix of an object
- // to be non-invertible, the object and its content do not get displayed.
- return;
- }
- };
- let frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(),
- point.y.to_f32_px()));
- Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y))
- }
- None => {
- point
- }
- }
- };
- }
- #[inline]
- fn scroll_root<'a>(scroll_root: &ScrollRoot,
- translated_point: &mut Point2D<Au>,
- scroll_offsets: &ScrollOffsetMap) {
- // Adjust the translated point to account for the scroll offset if necessary.
- //
- // We don't perform this adjustment on the root stacking context because
- // the DOM-side code has already translated the point for us (e.g. in
- // `Window::hit_test_query()`) by now.
- if let Some(scroll_offset) = scroll_offsets.get(&scroll_root.id) {
- translated_point.x -= Au::from_f32_px(scroll_offset.x);
- translated_point.y -= Au::from_f32_px(scroll_offset.y);
+ let mut point = *point - stacking_context.bounds.origin;
+ if stacking_context.scroll_policy == ScrollPolicy::Fixed {
+ let old_offset = offset_lookup.calculated_total_offsets.get(&clip_id).cloned();
+ offset_lookup.calculated_total_offsets.insert(clip_id, Point2D::zero());
+
+ self.hit_test_contents(traversal, &point, offset_lookup, result);
+
+ match old_offset {
+ Some(offset) => offset_lookup.calculated_total_offsets.insert(clip_id, offset),
+ None => offset_lookup.calculated_total_offsets.remove(&clip_id),
+ };
+ } else if let Some(transform) = stacking_context.transform {
+ if let Some(ref mut sublookup) =
+ offset_lookup.new_for_reference_frame(clip_id, &transform, &mut point) {
+ self.hit_test_contents(traversal, &point, sublookup, result);
+ }
+ } else {
+ self.hit_test_contents(traversal, &point, offset_lookup, result);
}
}
@@ -1207,11 +1256,18 @@ impl DisplayItem {
println!("{}+ {:?}", indent, self);
}
- fn hit_test(&self, point: Point2D<Au>) -> Option<DisplayItemMetadata> {
+ fn hit_test(&self,
+ point: Point2D<Au>,
+ offset_lookup: &mut ScrollOffsetLookup)
+ -> Option<DisplayItemMetadata> {
// TODO(pcwalton): Use a precise algorithm here. This will allow us to properly hit
// test elements with `border-radius`, for example.
let base_item = self.base();
+ let scroll_offset = offset_lookup.full_offset_for_scroll_root(&base_item.scroll_root_id);
+ let point = Point2D::new(point.x - Au::from_f32_px(scroll_offset.x),
+ point.y - Au::from_f32_px(scroll_offset.y));
+
if !base_item.clip.might_intersect_point(&point) {
// Clipped out.
return None;
diff --git a/components/layout/query.rs b/components/layout/query.rs
index 476a68afafe..da10696ec29 100644
--- a/components/layout/query.rs
+++ b/components/layout/query.rs
@@ -81,8 +81,8 @@ pub struct LayoutThreadData {
/// A queued response for the offset parent/rect of a node.
pub margin_style_response: MarginStyleResponse,
- /// Scroll offsets of stacking contexts. This will only be populated if WebRender is in use.
- pub stacking_context_scroll_offsets: ScrollOffsetMap,
+ /// Scroll offsets of scrolling regions.
+ pub scroll_offsets: ScrollOffsetMap,
/// Index in a text fragment. We need this do determine the insertion point.
pub text_index_response: TextIndexResponse,
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index 7a3bf5cb9ab..eed95ecb9ea 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -88,7 +88,7 @@ use script_layout_interface::rpc::{LayoutRPC, MarginStyleResponse, NodeOverflowR
use script_layout_interface::rpc::TextIndexResponse;
use script_layout_interface::wrapper_traits::LayoutNode;
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
-use script_traits::{StackingContextScrollState, UntrustedNodeAddress};
+use script_traits::{ScrollState, UntrustedNodeAddress};
use selectors::Element;
use servo_config::opts;
use servo_config::prefs::PREFS;
@@ -506,7 +506,7 @@ impl LayoutThread {
resolved_style_response: String::new(),
offset_parent_response: OffsetParentResponse::empty(),
margin_style_response: MarginStyleResponse::empty(),
- stacking_context_scroll_offsets: HashMap::new(),
+ scroll_offsets: HashMap::new(),
text_index_response: TextIndexResponse(None),
nodes_from_point_response: vec![],
})),
@@ -600,9 +600,8 @@ impl LayoutThread {
};
match request {
- Request::FromPipeline(LayoutControlMsg::SetStackingContextScrollStates(
- new_scroll_states)) => {
- self.handle_request_helper(Msg::SetStackingContextScrollStates(new_scroll_states),
+ Request::FromPipeline(LayoutControlMsg::SetScrollStates(new_scroll_states)) => {
+ self.handle_request_helper(Msg::SetScrollStates(new_scroll_states),
possibly_locked_rw_data)
},
Request::FromPipeline(LayoutControlMsg::TickAnimations) => {
@@ -653,9 +652,12 @@ impl LayoutThread {
|| self.handle_reflow(&mut data, possibly_locked_rw_data));
},
Msg::TickAnimations => self.tick_all_animations(possibly_locked_rw_data),
- Msg::SetStackingContextScrollStates(new_scroll_states) => {
- self.set_stacking_context_scroll_states(new_scroll_states,
- possibly_locked_rw_data);
+ Msg::SetScrollStates(new_scroll_states) => {
+ self.set_scroll_states(new_scroll_states, possibly_locked_rw_data);
+ }
+ Msg::UpdateScrollStateFromScript(state) => {
+ let mut rw_data = possibly_locked_rw_data.lock();
+ rw_data.scroll_offsets.insert(state.scroll_root_id, state.scroll_offset);
}
Msg::ReapStyleAndLayoutData(dead_data) => {
unsafe {
@@ -1306,19 +1308,13 @@ impl LayoutThread {
let node = unsafe { ServoLayoutNode::new(&node) };
rw_data.content_boxes_response = process_content_boxes_request(node, root_flow);
},
- ReflowQueryType::HitTestQuery(translated_point, client_point, update_cursor) => {
- let mut translated_point = Point2D::new(Au::from_f32_px(translated_point.x),
- Au::from_f32_px(translated_point.y));
-
- let client_point = Point2D::new(Au::from_f32_px(client_point.x),
- Au::from_f32_px(client_point.y));
-
+ ReflowQueryType::HitTestQuery(client_point, update_cursor) => {
+ let point = Point2D::new(Au::from_f32_px(client_point.x),
+ Au::from_f32_px(client_point.y));
let result = rw_data.display_list
.as_ref()
.expect("Tried to hit test with no display list")
- .hit_test(&mut translated_point,
- &client_point,
- &rw_data.stacking_context_scroll_offsets);
+ .hit_test(&point, &rw_data.scroll_offsets);
rw_data.hit_test_response = (result.last().cloned(), update_cursor);
},
ReflowQueryType::TextIndexQuery(node, mouse_x, mouse_y) => {
@@ -1332,7 +1328,7 @@ impl LayoutThread {
.expect("Tried to hit test with no display list")
.text_index(opaque_node,
&client_point,
- &rw_data.stacking_context_scroll_offsets));
+ &rw_data.scroll_offsets));
},
ReflowQueryType::NodeGeometryQuery(node) => {
let node = unsafe { ServoLayoutNode::new(&node) };
@@ -1368,18 +1364,14 @@ impl LayoutThread {
let node = unsafe { ServoLayoutNode::new(&node) };
rw_data.margin_style_response = process_margin_style_query(node);
},
- ReflowQueryType::NodesFromPoint(page_point, client_point) => {
- let page_point = Point2D::new(Au::from_f32_px(page_point.x),
- Au::from_f32_px(page_point.y));
+ ReflowQueryType::NodesFromPoint(client_point) => {
let client_point = Point2D::new(Au::from_f32_px(client_point.x),
Au::from_f32_px(client_point.y));
let nodes_from_point_list = {
let result = match rw_data.display_list {
None => panic!("Tried to hit test without a DisplayList"),
Some(ref display_list) => {
- display_list.hit_test(&page_point,
- &client_point,
- &rw_data.stacking_context_scroll_offsets)
+ display_list.hit_test(&client_point, &rw_data.scroll_offsets)
}
};
@@ -1395,10 +1387,9 @@ impl LayoutThread {
}
}
- fn set_stacking_context_scroll_states<'a, 'b>(
- &mut self,
- new_scroll_states: Vec<StackingContextScrollState>,
- possibly_locked_rw_data: &mut RwData<'a, 'b>) {
+ fn set_scroll_states<'a, 'b>(&mut self,
+ new_scroll_states: Vec<ScrollState>,
+ possibly_locked_rw_data: &mut RwData<'a, 'b>) {
let mut rw_data = possibly_locked_rw_data.lock();
let mut script_scroll_states = vec![];
let mut layout_scroll_states = HashMap::new();
@@ -1416,7 +1407,7 @@ impl LayoutThread {
}
let _ = self.script_chan
.send(ConstellationControlMsg::SetScrollState(self.id, script_scroll_states));
- rw_data.stacking_context_scroll_offsets = layout_scroll_states
+ rw_data.scroll_offsets = layout_scroll_states
}
fn tick_all_animations<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index bce898e6347..e44de8be727 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -1955,12 +1955,8 @@ impl Document {
}
pub fn nodes_from_point(&self, client_point: &Point2D<f32>) -> Vec<UntrustedNodeAddress> {
- let page_point =
- Point2D::new(client_point.x + self.window.PageXOffset() as f32,
- client_point.y + self.window.PageYOffset() as f32);
-
if !self.window.reflow(ReflowGoal::ForScriptQuery,
- ReflowQueryType::NodesFromPoint(page_point, *client_point),
+ ReflowQueryType::NodesFromPoint(*client_point),
ReflowReason::Query) {
return vec!();
};
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 4317d2890b7..65d1a591adc 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -75,11 +75,11 @@ use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, Lay
use script_layout_interface::rpc::{MarginStyleResponse, NodeScrollRootIdResponse};
use script_layout_interface::rpc::{ResolvedStyleResponse, TextIndexResponse};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory};
-use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, RunnableWrapper};
-use script_thread::{SendableMainThreadScriptChan, ImageCacheMsg, ScriptThread};
-use script_traits::{ConstellationControlMsg, LoadData, MozBrowserEvent, UntrustedNodeAddress};
-use script_traits::{DocumentState, TimerEvent, TimerEventId};
-use script_traits::{ScriptMsg as ConstellationMsg, TimerSchedulerMsg, WindowSizeData, WindowSizeType};
+use script_thread::{ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg, Runnable};
+use script_thread::{RunnableWrapper, ScriptThread, SendableMainThreadScriptChan};
+use script_traits::{ConstellationControlMsg, DocumentState, LoadData, MozBrowserEvent};
+use script_traits::{ScriptMsg as ConstellationMsg, ScrollState, TimerEvent, TimerEventId};
+use script_traits::{TimerSchedulerMsg, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use servo_atoms::Atom;
use servo_config::opts;
@@ -1111,6 +1111,11 @@ impl Window {
ScrollBehavior::Smooth => true
};
+ self.layout_chan.send(Msg::UpdateScrollStateFromScript(ScrollState {
+ scroll_root_id: scroll_root_id,
+ scroll_offset: Point2D::new(-x, -y),
+ })).unwrap();
+
// TODO (farodin91): Raise an event to stop the current_viewport
self.update_viewport_for_scroll(x, y);
@@ -1372,14 +1377,8 @@ impl Window {
client_point: Point2D<f32>,
update_cursor: bool)
-> Option<UntrustedNodeAddress> {
- let translated_point =
- Point2D::new(client_point.x + self.PageXOffset() as f32,
- client_point.y + self.PageYOffset() as f32);
-
if !self.reflow(ReflowGoal::ForScriptQuery,
- ReflowQueryType::HitTestQuery(translated_point,
- client_point,
- update_cursor),
+ ReflowQueryType::HitTestQuery(client_point, update_cursor),
ReflowReason::Query) {
return None
}
diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs
index 9c2f94b0dc0..038967fdd04 100644
--- a/components/script_layout_interface/message.rs
+++ b/components/script_layout_interface/message.rs
@@ -12,8 +12,8 @@ use msg::constellation_msg::PipelineId;
use net_traits::image_cache::ImageCache;
use profile_traits::mem::ReportsChan;
use rpc::LayoutRPC;
-use script_traits::{ConstellationControlMsg, LayoutControlMsg, UntrustedNodeAddress};
-use script_traits::{LayoutMsg as ConstellationMsg, StackingContextScrollState, WindowSizeData};
+use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
+use script_traits::{ScrollState, UntrustedNodeAddress, WindowSizeData};
use servo_url::ServoUrl;
use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender};
@@ -79,7 +79,11 @@ pub enum Msg {
SetFinalUrl(ServoUrl),
/// Tells layout about the new scrolling offsets of each scrollable stacking context.
- SetStackingContextScrollStates(Vec<StackingContextScrollState>),
+ SetScrollStates(Vec<ScrollState>),
+
+ /// Tells layout about a single new scrolling offset from the script. The rest will
+ /// remain untouched and layout won't forward this back to script.
+ UpdateScrollStateFromScript(ScrollState),
}
@@ -90,7 +94,7 @@ pub enum ReflowQueryType {
ContentBoxQuery(TrustedNodeAddress),
ContentBoxesQuery(TrustedNodeAddress),
NodeOverflowQuery(TrustedNodeAddress),
- HitTestQuery(Point2D<f32>, Point2D<f32>, bool),
+ HitTestQuery(Point2D<f32>, bool),
NodeScrollRootIdQuery(TrustedNodeAddress),
NodeGeometryQuery(TrustedNodeAddress),
NodeScrollGeometryQuery(TrustedNodeAddress),
@@ -98,7 +102,7 @@ pub enum ReflowQueryType {
OffsetParentQuery(TrustedNodeAddress),
MarginStyleQuery(TrustedNodeAddress),
TextIndexQuery(TrustedNodeAddress, i32, i32),
- NodesFromPoint(Point2D<f32>, Point2D<f32>),
+ NodesFromPoint(Point2D<f32>),
}
/// Information needed for a reflow.
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index 4f3cfca76a5..bfc1e63fcc8 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -122,7 +122,7 @@ pub enum LayoutControlMsg {
/// Asks layout to run another step in its animation.
TickAnimations,
/// Tells layout about the new scrolling offsets of each scrollable stacking context.
- SetStackingContextScrollStates(Vec<StackingContextScrollState>),
+ SetScrollStates(Vec<ScrollState>),
/// Requests the current load state of Web fonts. `true` is returned if fonts are still loading
/// and `false` is returned if all fonts have loaded.
GetWebFontLoadState(IpcSender<bool>),
@@ -673,7 +673,7 @@ pub enum AnimationTickType {
/// The scroll state of a stacking context.
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
-pub struct StackingContextScrollState {
+pub struct ScrollState {
/// The ID of the scroll root.
pub scroll_root_id: ClipId,
/// The scrolling offset of this stacking context.