diff options
Diffstat (limited to 'components/layout')
-rw-r--r-- | components/layout/layout_thread.rs | 21 | ||||
-rw-r--r-- | components/layout/query.rs | 46 |
2 files changed, 39 insertions, 28 deletions
diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index a361e42fb15..1a8bdfb4a19 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -22,7 +22,7 @@ use euclid::size::Size2D; use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow_ref::{self, FlowRef}; use fnv::FnvHasher; -use gfx::display_list::{ClippingRegion, DisplayList, LayerInfo}; +use gfx::display_list::{ClippingRegion, DisplayItemMetadata, DisplayList, LayerInfo}; use gfx::display_list::{OpaqueNode, StackingContext, StackingContextId, StackingContextType}; use gfx::font; use gfx::font_cache_thread::FontCacheThread; @@ -114,6 +114,9 @@ pub struct LayoutThreadData { /// A queued response for the client {top, left, width, height} of a node in pixels. pub client_rect_response: Rect<i32>, + /// A queued response for the node at a given point + pub hit_test_response: (Option<DisplayItemMetadata>, bool), + /// A queued response for the resolved style property of an element. pub resolved_style_response: Option<String>, @@ -458,6 +461,7 @@ impl LayoutThread { content_box_response: Rect::zero(), content_boxes_response: Vec::new(), client_rect_response: Rect::zero(), + hit_test_response: (None, false), resolved_style_response: None, offset_parent_response: OffsetParentResponse::empty(), margin_style_response: MarginStyleResponse::empty(), @@ -977,6 +981,9 @@ impl LayoutThread { ReflowQueryType::ContentBoxesQuery(_) => { rw_data.content_boxes_response = Vec::new(); }, + ReflowQueryType::HitTestQuery(_, _) => { + rw_data.hit_test_response = (None, false); + }, ReflowQueryType::NodeGeometryQuery(_) => { rw_data.client_rect_response = Rect::zero(); }, @@ -1119,6 +1126,18 @@ impl LayoutThread { let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.content_boxes_response = process_content_boxes_request(node, &mut root_flow); }, + ReflowQueryType::HitTestQuery(point, update_cursor) => { + let point = Point2D::new(Au::from_f32_px(point.x), Au::from_f32_px(point.y)); + let result = match rw_data.display_list { + None => panic!("Tried to hit test with no display list"), + Some(ref dl) => dl.hit_test(point), + }; + rw_data.hit_test_response = if result.len() > 0 { + (Some(result[0]), update_cursor) + } else { + (None, update_cursor) + }; + }, ReflowQueryType::NodeGeometryQuery(node) => { let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.client_rect_response = process_node_geometry_request(node, &mut root_flow); diff --git a/components/layout/query.rs b/components/layout/query.rs index df45301106a..039de56f5c4 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -51,6 +51,25 @@ impl LayoutRPC for LayoutRPCImpl { ContentBoxesResponse(rw_data.content_boxes_response.clone()) } + /// Requests the node containing the point of interest. + fn hit_test(&self) -> HitTestResponse { + let &LayoutRPCImpl(ref rw_data) = self; + let rw_data = rw_data.lock().unwrap(); + let &(ref result, update_cursor) = &rw_data.hit_test_response; + if update_cursor { + // Compute the new cursor. + let cursor = match *result { + None => Cursor::DefaultCursor, + Some(dim) => dim.pointing.unwrap(), + }; + let ConstellationChan(ref constellation_chan) = rw_data.constellation_chan; + constellation_chan.send(ConstellationMsg::SetCursor(cursor)).unwrap(); + } + HitTestResponse { + node_address: result.map(|dim| dim.node.to_untrusted_node_address()), + } + } + fn node_geometry(&self) -> NodeGeometryResponse { let &LayoutRPCImpl(ref rw_data) = self; let rw_data = rw_data.lock().unwrap(); @@ -66,33 +85,6 @@ impl LayoutRPC for LayoutRPCImpl { ResolvedStyleResponse(rw_data.resolved_style_response.clone()) } - /// Requests the node containing the point of interest. - fn hit_test(&self, point: Point2D<f32>, update_cursor: bool) -> Result<HitTestResponse, ()> { - let point = Point2D::new(Au::from_f32_px(point.x), Au::from_f32_px(point.y)); - let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock().unwrap(); - let display_list = rw_data.display_list.as_ref().expect("Tried to hit test without a DisplayList!"); - - let result = display_list.hit_test(point); - - if update_cursor { - let cursor = if !result.is_empty() { - result[0].pointing.unwrap() - } else { - Cursor::DefaultCursor - }; - - let ConstellationChan(ref constellation_chan) = rw_data.constellation_chan; - constellation_chan.send(ConstellationMsg::SetCursor(cursor)).unwrap(); - }; - - if !result.is_empty() { - Ok(HitTestResponse(result[0].node.to_untrusted_node_address())) - } else { - Err(()) - } - } - fn offset_parent(&self) -> OffsetParentResponse { let &LayoutRPCImpl(ref rw_data) = self; let rw_data = rw_data.lock().unwrap(); |