aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2014-12-11 10:39:59 -0700
committerbors-servo <metajack+bors@gmail.com>2014-12-11 10:39:59 -0700
commit512d55ecefac4c5f7f6fc52ad5cedb7f2664b0c9 (patch)
tree6cfd9a1433298b5c909aa09bf9b7cd4bbf0ef997
parentd67bcfa7ce7b37e7ed45a53f1daddbc6b2f2ddf2 (diff)
parent14bfa451058b3bc6d6925137240de5e172045213 (diff)
downloadservo-512d55ecefac4c5f7f6fc52ad5cedb7f2664b0c9.tar.gz
servo-512d55ecefac4c5f7f6fc52ad5cedb7f2664b0c9.zip
auto merge of #4329 : mrobinson/servo/phantom-layer, r=pcwalton
At various moments, whether due to timing or layout issues, root layers (iframes) do not have a size and location. We modify the compositor to have all root layers mask to their content boundaries whether they have a frame rect or not. Uninitialized layers have empty boundaries, so they will disappear from the page. We also have to ensure that clicks to not go to areas of layers that are masked away. This fixes issues where ads on github take over the entire viewport.
-rw-r--r--components/compositing/compositor.rs38
1 files changed, 31 insertions, 7 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index c5a11fa1605..0466b05540d 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -1098,18 +1098,38 @@ impl<Window: WindowMethods> IOCompositor<Window> {
fn find_topmost_layer_at_point_for_layer(&self,
layer: Rc<Layer<CompositorData>>,
- point: TypedPoint2D<LayerPixel, f32>)
+ point: TypedPoint2D<LayerPixel, f32>,
+ clip_rect: &TypedRect<LayerPixel, f32>)
-> 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() {
- 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() {
return result;
}
}
let point = point - *layer.content_offset.borrow();
- if !layer.bounds.borrow().contains(&point) {
+ if !clipped_layer_bounds.contains(&point) {
return None;
}
@@ -1120,7 +1140,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
point: TypedPoint2D<LayerPixel, f32>)
-> Option<HitTestResult> {
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,
}
}
@@ -1178,10 +1201,11 @@ fn create_root_layer_for_pipeline_and_rect(pipeline: &CompositionPipeline,
WantsScrollEvents,
opts::get().tile_size);
+ // All root layers mask to bounds.
+ *root_layer.masks_to_bounds.borrow_mut() = true;
+
match frame_rect {
Some(ref frame_rect) => {
- *root_layer.masks_to_bounds.borrow_mut() = true;
-
let frame_rect = frame_rect.to_untyped();
*root_layer.bounds.borrow_mut() = Rect::from_untyped(&frame_rect);
}