diff options
author | bors-servo <metajack+bors@gmail.com> | 2014-12-11 10:39:59 -0700 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2014-12-11 10:39:59 -0700 |
commit | 512d55ecefac4c5f7f6fc52ad5cedb7f2664b0c9 (patch) | |
tree | 6cfd9a1433298b5c909aa09bf9b7cd4bbf0ef997 | |
parent | d67bcfa7ce7b37e7ed45a53f1daddbc6b2f2ddf2 (diff) | |
parent | 14bfa451058b3bc6d6925137240de5e172045213 (diff) | |
download | servo-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.rs | 38 |
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); } |