From 200e36311c3ccf222d7fc1d1508c7315a0089710 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 15 Apr 2024 15:09:15 +0200 Subject: [PATCH] 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 --- crates/gpui/src/window/element_cx.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/gpui/src/window/element_cx.rs b/crates/gpui/src/window/element_cx.rs index 4a334ea9dc1e38ce7b3c35148e0875823cb90e0d..15758fb357c892540c9bcebff59bdff1ec7dce75 100644 --- a/crates/gpui/src/window/element_cx.rs +++ b/crates/gpui/src/window/element_cx.rs @@ -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, + /// The content mask when the hitbox was inserted. + pub content_mask: ContentMask, /// 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) -> 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());