Automatically reset cursor style when hit test changes (cherry-pick #9289) (#9322)
gcp-cherry-pick-bot[bot]
,
Antonio Scandurra
, and
Nathan Sobo
created
Cherry-picked Automatically reset cursor style when hit test changes
(#9289)
Release Notes:
- N/A
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Change summary
crates/gpui/src/window.rs | 38 ++++++++++++++++-------------
crates/gpui/src/window/element_cx.rs | 2
crates/workspace/src/pane_group.rs | 4 ---
3 files changed, 22 insertions(+), 22 deletions(-)
Detailed changes
@@ -956,12 +956,6 @@ impl<'a> WindowContext<'a> {
self.window.next_frame.focus = self.window.focus;
self.window.next_frame.window_active = self.window.active.get();
- // Set the cursor only if we're the active window.
- if self.is_window_active() {
- let cursor_style = self.compute_cursor_style().unwrap_or(CursorStyle::Arrow);
- self.platform.set_cursor_style(cursor_style);
- }
-
// Register requested input handler with the platform window.
if let Some(input_handler) = self.window.next_frame.input_handlers.pop() {
self.window
@@ -1017,6 +1011,8 @@ impl<'a> WindowContext<'a> {
.clone()
.retain(&(), |listener| listener(&event, self));
}
+
+ self.reset_cursor_style();
self.window.refreshing = false;
self.window.draw_phase = DrawPhase::None;
self.window.needs_present.set(true);
@@ -1031,16 +1027,20 @@ impl<'a> WindowContext<'a> {
profiling::finish_frame!();
}
- fn compute_cursor_style(&mut self) -> Option<CursorStyle> {
- // TODO: maybe we should have a HashMap keyed by HitboxId.
- let request = self
- .window
- .next_frame
- .cursor_styles
- .iter()
- .rev()
- .find(|request| request.hitbox_id.is_hovered(self))?;
- Some(request.style)
+ fn reset_cursor_style(&self) {
+ // Set the cursor only if we're the active window.
+ if self.is_window_active() {
+ let style = self
+ .window
+ .rendered_frame
+ .cursor_styles
+ .iter()
+ .rev()
+ .find(|request| request.hitbox_id.is_hovered(self))
+ .map(|request| request.style)
+ .unwrap_or(CursorStyle::Arrow);
+ self.platform.set_cursor_style(style);
+ }
}
/// Dispatch a given keystroke as though the user had typed it.
@@ -1175,7 +1175,11 @@ impl<'a> WindowContext<'a> {
}
fn dispatch_mouse_event(&mut self, event: &dyn Any) {
- self.window.mouse_hit_test = self.window.rendered_frame.hit_test(self.mouse_position());
+ let hit_test = self.window.rendered_frame.hit_test(self.mouse_position());
+ if hit_test != self.window.mouse_hit_test {
+ self.window.mouse_hit_test = hit_test;
+ self.reset_cursor_style();
+ }
let mut mouse_listeners = mem::take(&mut self.window.rendered_frame.mouse_listeners);
self.with_element_context(|cx| {
@@ -79,7 +79,7 @@ impl Hitbox {
}
}
-#[derive(Default)]
+#[derive(Default, Eq, PartialEq)]
pub(crate) struct HitTest(SmallVec<[HitboxId; 8]>);
pub(crate) struct DeferredDraw {
@@ -941,8 +941,6 @@ mod element {
let flexes = self.flexes.clone();
let child_bounds = child.bounds;
let axis = self.axis;
- let handle_hitbox = handle.hitbox.clone();
- let was_hovered = handle_hitbox.is_hovered(cx);
move |e: &MouseMoveEvent, phase, cx| {
let dragged_handle = dragged_handle.borrow();
if phase.bubble() {
@@ -957,8 +955,6 @@ mod element {
workspace.clone(),
cx,
)
- } else if was_hovered != handle_hitbox.is_hovered(cx) {
- cx.refresh();
}
}
}