Intersect content mask with hitbox bounds only during hit test (#10554)

This fixes a bug that caused the editor to be rendered incorrectly when
its bounds extended outside the content mask. This is because the editor
uses the returned `Hitbox` bounds to determine the origin of its
elements.

With this commit, we will now store a new `content_mask` field within
the `Hitbox` struct which is captured when the hitbox is inserted. Then,
the content mask is applied on the fly when performing a hit test to
determine whether the hitbox is actually hovered.

Release Notes:

- N/A
This commit is contained in:
Antonio Scandurra 2024-04-15 15:09:15 +02:00 committed by GitHub
parent db48c75231
commit 200e36311c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -66,11 +66,13 @@ impl HitboxId {
/// See [ElementContext::insert_hitbox] for more details.
#[derive(Clone, Debug, Deref)]
pub struct Hitbox {
/// A unique identifier for the hitbox
/// A unique identifier for the hitbox.
pub id: HitboxId,
/// The bounds of the hitbox
/// The bounds of the hitbox.
#[deref]
pub bounds: Bounds<Pixels>,
/// The content mask when the hitbox was inserted.
pub content_mask: ContentMask<Pixels>,
/// Whether the hitbox occludes other hitboxes inserted prior.
pub opaque: bool,
}
@ -201,7 +203,8 @@ impl Frame {
pub(crate) fn hit_test(&self, position: Point<Pixels>) -> HitTest {
let mut hit_test = HitTest::default();
for hitbox in self.hitboxes.iter().rev() {
if hitbox.bounds.contains(&position) {
let bounds = hitbox.bounds.intersect(&hitbox.content_mask.bounds);
if bounds.contains(&position) {
hit_test.0.push(hitbox.id);
if hitbox.opaque {
break;
@ -1404,7 +1407,8 @@ impl<'a> ElementContext<'a> {
window.next_hitbox_id.0 += 1;
let hitbox = Hitbox {
id,
bounds: bounds.intersect(&content_mask.bounds),
bounds,
content_mask,
opaque,
};
window.next_frame.hitboxes.push(hitbox.clone());