mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
parent
4f625d3ab6
commit
a61989e82b
2 changed files with 26 additions and 16 deletions
|
@ -242,7 +242,9 @@ enum ShutdownState {
|
|||
}
|
||||
|
||||
struct HitTestResult {
|
||||
/// The topmost layer containing the requested point
|
||||
layer: Rc<Layer<CompositorData>>,
|
||||
/// The point in client coordinates of the innermost window or frame containing `layer`
|
||||
point: TypedPoint2D<LayerPixel, f32>,
|
||||
}
|
||||
|
||||
|
@ -1934,45 +1936,53 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
|
||||
fn find_topmost_layer_at_point_for_layer(&self,
|
||||
layer: Rc<Layer<CompositorData>>,
|
||||
point: TypedPoint2D<LayerPixel, f32>,
|
||||
clip_rect: &TypedRect<LayerPixel, f32>)
|
||||
point_in_parent_layer: TypedPoint2D<LayerPixel, f32>,
|
||||
clip_rect_in_parent_layer: &TypedRect<LayerPixel, f32>)
|
||||
-> Option<HitTestResult> {
|
||||
let layer_bounds = *layer.bounds.borrow();
|
||||
let masks_to_bounds = *layer.masks_to_bounds.borrow();
|
||||
if layer_bounds.is_empty() && masks_to_bounds {
|
||||
return None;
|
||||
}
|
||||
let scroll_offset = layer.extra_data.borrow().scroll_offset;
|
||||
|
||||
let clipped_layer_bounds = match clip_rect.intersection(&layer_bounds) {
|
||||
// Total offset from parent coordinates to this layer's coordinates.
|
||||
// FIXME: This offset is incorrect for fixed-position layers.
|
||||
let layer_offset = scroll_offset + layer_bounds.origin;
|
||||
|
||||
let clipped_layer_bounds = match clip_rect_in_parent_layer.intersection(&layer_bounds) {
|
||||
Some(rect) => rect,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let clip_rect_for_children = if masks_to_bounds {
|
||||
Rect::new(Point2D::zero(), clipped_layer_bounds.size)
|
||||
&clipped_layer_bounds
|
||||
} else {
|
||||
clipped_layer_bounds.translate(&clip_rect.origin)
|
||||
};
|
||||
clip_rect_in_parent_layer
|
||||
}.translate(&-layer_offset);
|
||||
|
||||
let child_point = point - layer_bounds.origin;
|
||||
let child_point = point_in_parent_layer - layer_offset;
|
||||
for child in layer.children().iter().rev() {
|
||||
// Translate the clip rect into the child's coordinate system.
|
||||
let clip_rect_for_child =
|
||||
clip_rect_for_children.translate(&-*child.content_offset.borrow());
|
||||
let result = self.find_topmost_layer_at_point_for_layer(child.clone(),
|
||||
child_point,
|
||||
&clip_rect_for_child);
|
||||
if result.is_some() {
|
||||
return result;
|
||||
&clip_rect_for_children);
|
||||
if let Some(mut result) = result {
|
||||
// Return the point in layer coordinates of the topmost frame containing the point.
|
||||
let pipeline_id = layer.extra_data.borrow().pipeline_id;
|
||||
let child_pipeline_id = result.layer.extra_data.borrow().pipeline_id;
|
||||
if pipeline_id == child_pipeline_id {
|
||||
result.point = result.point + layer_offset;
|
||||
}
|
||||
return Some(result);
|
||||
}
|
||||
}
|
||||
|
||||
let point = point - *layer.content_offset.borrow();
|
||||
if !clipped_layer_bounds.contains(&point) {
|
||||
if !clipped_layer_bounds.contains(&point_in_parent_layer) {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(HitTestResult { layer: layer, point: point });
|
||||
return Some(HitTestResult { layer: layer, point: point_in_parent_layer });
|
||||
}
|
||||
|
||||
fn find_topmost_layer_at_point(&self,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue