From 21d6751c487fb36ebd6887b4e6de630e726fdad6 Mon Sep 17 00:00:00 2001 From: Julia Date: Tue, 23 Jan 2024 12:44:23 -0500 Subject: [PATCH] Make `was_top_layer_under_active_drag` more closely match logic of `was_top_layer` Co-Authored-By: Max Brunsfeld --- crates/gpui/src/window.rs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index a02c50cb5a..687cd556a2 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -877,14 +877,27 @@ impl<'a> WindowContext<'a> { pub(crate) fn was_top_layer_under_active_drag( &self, point: &Point, - level: &StackingOrder, + layer: &StackingOrder, ) -> bool { - for (opaque_level, _, bounds) in self.window.rendered_frame.depth_map.iter() { - if level >= opaque_level { - break; + // Precondition: the depth map is ordered from topmost to bottomost. + + for (opaque_layer, _, bounds) in self.window.rendered_frame.depth_map.iter() { + if layer >= opaque_layer { + // The queried layer is either above or is the same as the this opaque layer. + // Anything after this point is guaranteed to be below the queried layer. + return true; } - if opaque_level + if !bounds.contains(point) { + // This opaque layer is above the queried layer but it doesn't contain + // the given position, so we can ignore it even if it's above. + continue; + } + + // All normal content is rendered with a base z-index of 0, we know that if the root of this opaque layer + // equals `ACTIVE_DRAG_Z_INDEX` then it must be the drag layer and we can ignore it as we are + // looking to see if the queried layer was the topmost underneath the drag layer. + if opaque_layer .first() .map(|c| c.z_index == ACTIVE_DRAG_Z_INDEX) .unwrap_or(false) @@ -892,10 +905,21 @@ impl<'a> WindowContext<'a> { continue; } - if bounds.contains(point) { + // At this point, we've established that this opaque layer is on top of the queried layer + // and contains the position: + // - If the opaque layer is an extension of the queried layer, we don't want + // to consider the opaque layer to be on top and so we ignore it. + // - Else, we will bail early and say that the queried layer wasn't the top one. + let opaque_layer_is_extension_of_queried_layer = opaque_layer.len() >= layer.len() + && opaque_layer + .iter() + .zip(layer.iter()) + .all(|(a, b)| a.z_index == b.z_index); + if !opaque_layer_is_extension_of_queried_layer { return false; } } + true }