gfx: fix hit-testing to take into account nested stacking contexts.

I messed this up in the previous hit testing pr.
This commit is contained in:
Emilio Cobos Álvarez 2016-08-12 23:50:04 -07:00
parent 8a5e1b70b7
commit ce5f035a69
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C

View file

@ -719,7 +719,7 @@ impl StackingContext {
geometry::f32_rect_to_au_rect(overflow) geometry::f32_rect_to_au_rect(overflow)
} }
pub fn hit_test<'a>(&self, fn hit_test<'a>(&self,
traversal: &mut DisplayListTraversal<'a>, traversal: &mut DisplayListTraversal<'a>,
translated_point: &Point2D<Au>, translated_point: &Point2D<Au>,
client_point: &Point2D<Au>, client_point: &Point2D<Au>,
@ -730,17 +730,21 @@ impl StackingContext {
None => false, None => false,
}; };
let effective_point = if is_fixed { client_point } else { translated_point }; // Convert the parent translated point into stacking context local
// transform space if the stacking context isn't fixed.
// Convert the point into stacking context local transform space. //
let mut point = if self.context_type == StackingContextType::Real { // If it's fixed, we need to use the client point anyway, and if it's a
let point = *effective_point - self.bounds.origin; // pseudo-stacking context, our parent's is enough.
let mut translated_point = if is_fixed {
*client_point
} else if self.context_type == StackingContextType::Real {
let point = *translated_point - self.bounds.origin;
let inv_transform = self.transform.inverse().unwrap(); let inv_transform = self.transform.inverse().unwrap();
let frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(), let frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(),
point.y.to_f32_px())); point.y.to_f32_px()));
Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y)) Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y))
} else { } else {
*effective_point *translated_point
}; };
// Adjust the translated point to account for the scroll offset if // Adjust the translated point to account for the scroll offset if
@ -751,22 +755,23 @@ impl StackingContext {
// `Window::hit_test_query()`) by now. // `Window::hit_test_query()`) by now.
if !is_fixed && self.id != StackingContextId::root() { if !is_fixed && self.id != StackingContextId::root() {
if let Some(scroll_offset) = scroll_offsets.get(&self.id) { if let Some(scroll_offset) = scroll_offsets.get(&self.id) {
point.x -= Au::from_f32_px(scroll_offset.x); translated_point.x -= Au::from_f32_px(scroll_offset.x);
point.y -= Au::from_f32_px(scroll_offset.y); translated_point.y -= Au::from_f32_px(scroll_offset.y);
} }
} }
for child in self.children() { for child in self.children() {
while let Some(item) = traversal.advance(self) { while let Some(item) = traversal.advance(self) {
if let Some(meta) = item.hit_test(point) { if let Some(meta) = item.hit_test(translated_point) {
result.push(meta); result.push(meta);
} }
} }
child.hit_test(traversal, translated_point, client_point, scroll_offsets, result); child.hit_test(traversal, &translated_point, client_point,
scroll_offsets, result);
} }
while let Some(item) = traversal.advance(self) { while let Some(item) = traversal.advance(self) {
if let Some(meta) = item.hit_test(point) { if let Some(meta) = item.hit_test(translated_point) {
result.push(meta); result.push(meta);
} }
} }