mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 05:35:31 +00:00
servo: Merge #12841 - Fix hit testing to take into account nested stacking contexts #12777 (from emilio:hit-test); r=pcwalton
<!-- Please describe your changes on the following line: --> Fixes #12833. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #12833 (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes OR <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 9b4713f5366aa43ac0db6a8f1d96f33b2f527978
This commit is contained in:
parent
f910293bda
commit
4b5727104d
@ -719,7 +719,7 @@ impl StackingContext {
|
||||
geometry::f32_rect_to_au_rect(overflow)
|
||||
}
|
||||
|
||||
pub fn hit_test<'a>(&self,
|
||||
fn hit_test<'a>(&self,
|
||||
traversal: &mut DisplayListTraversal<'a>,
|
||||
translated_point: &Point2D<Au>,
|
||||
client_point: &Point2D<Au>,
|
||||
@ -730,17 +730,21 @@ impl StackingContext {
|
||||
None => false,
|
||||
};
|
||||
|
||||
let effective_point = if is_fixed { client_point } else { translated_point };
|
||||
|
||||
// Convert the point into stacking context local transform space.
|
||||
let mut point = if self.context_type == StackingContextType::Real {
|
||||
let point = *effective_point - self.bounds.origin;
|
||||
// Convert the parent translated point into stacking context local
|
||||
// transform space if the stacking context isn't fixed.
|
||||
//
|
||||
// If it's fixed, we need to use the client point anyway, and if it's a
|
||||
// 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 frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(),
|
||||
point.y.to_f32_px()));
|
||||
Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y))
|
||||
} else {
|
||||
*effective_point
|
||||
*translated_point
|
||||
};
|
||||
|
||||
// Adjust the translated point to account for the scroll offset if
|
||||
@ -751,22 +755,23 @@ impl StackingContext {
|
||||
// `Window::hit_test_query()`) by now.
|
||||
if !is_fixed && self.id != StackingContextId::root() {
|
||||
if let Some(scroll_offset) = scroll_offsets.get(&self.id) {
|
||||
point.x -= Au::from_f32_px(scroll_offset.x);
|
||||
point.y -= Au::from_f32_px(scroll_offset.y);
|
||||
translated_point.x -= Au::from_f32_px(scroll_offset.x);
|
||||
translated_point.y -= Au::from_f32_px(scroll_offset.y);
|
||||
}
|
||||
}
|
||||
|
||||
for child in self.children() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if let Some(meta) = item.hit_test(point) {
|
||||
if let Some(meta) = item.hit_test(translated_point) {
|
||||
result.push(meta);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user