mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Hit test against clipped layer boundaries
When finding the layer under a point, take into account clipping rectangles defined by layers that mask to bounds. This prevents clicks from being hijacked by masked layers.
This commit is contained in:
parent
66f6c3a213
commit
14bfa45105
1 changed files with 28 additions and 5 deletions
|
@ -1098,18 +1098,38 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
|
|
||||||
fn find_topmost_layer_at_point_for_layer(&self,
|
fn find_topmost_layer_at_point_for_layer(&self,
|
||||||
layer: Rc<Layer<CompositorData>>,
|
layer: Rc<Layer<CompositorData>>,
|
||||||
point: TypedPoint2D<LayerPixel, f32>)
|
point: TypedPoint2D<LayerPixel, f32>,
|
||||||
|
clip_rect: &TypedRect<LayerPixel, f32>)
|
||||||
-> Option<HitTestResult> {
|
-> Option<HitTestResult> {
|
||||||
let child_point = point - layer.bounds.borrow().origin;
|
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 clipped_layer_bounds = match clip_rect.intersection(&layer_bounds) {
|
||||||
|
Some(rect) => rect,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let clip_rect_for_children = if masks_to_bounds {
|
||||||
|
Rect(Zero::zero(), clipped_layer_bounds.size)
|
||||||
|
} else {
|
||||||
|
clipped_layer_bounds.translate(&clip_rect.origin)
|
||||||
|
};
|
||||||
|
|
||||||
|
let child_point = point - layer_bounds.origin;
|
||||||
for child in layer.children().iter().rev() {
|
for child in layer.children().iter().rev() {
|
||||||
let result = self.find_topmost_layer_at_point_for_layer(child.clone(), child_point);
|
let result = self.find_topmost_layer_at_point_for_layer(child.clone(),
|
||||||
|
child_point,
|
||||||
|
&clip_rect_for_children);
|
||||||
if result.is_some() {
|
if result.is_some() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let point = point - *layer.content_offset.borrow();
|
let point = point - *layer.content_offset.borrow();
|
||||||
if !layer.bounds.borrow().contains(&point) {
|
if !clipped_layer_bounds.contains(&point) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,7 +1140,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
point: TypedPoint2D<LayerPixel, f32>)
|
point: TypedPoint2D<LayerPixel, f32>)
|
||||||
-> Option<HitTestResult> {
|
-> Option<HitTestResult> {
|
||||||
match self.scene.root {
|
match self.scene.root {
|
||||||
Some(ref layer) => self.find_topmost_layer_at_point_for_layer(layer.clone(), point),
|
Some(ref layer) => self.find_topmost_layer_at_point_for_layer(layer.clone(),
|
||||||
|
point,
|
||||||
|
&*layer.bounds.borrow()),
|
||||||
|
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue