From de5458cfe0f419324a7258647b887c0eb8db5c71 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 3 Nov 2023 21:40:28 -0600 Subject: [PATCH] Update tooltip code a bit This fixes a tiny UX bug where the tooltip would appear to move if you hovered over an element, then moved your mouse out and back within 500ms. The fix is to retain the task, so we can drop it to cancel it when the mouse leaves. Also changes the time we construct the tooltip to the time it first shows. --- crates/gpui2/src/app.rs | 1 + crates/gpui2/src/interactive.rs | 64 ++++++++++++++-------------- crates/ui2/src/components/tooltip.rs | 2 - 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 9e454dc652..bc9101fa0c 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -899,6 +899,7 @@ pub(crate) struct AnyDrag { pub cursor_offset: Point, } +#[derive(Clone)] pub(crate) struct AnyTooltip { pub view: AnyView, pub cursor_offset: Point, diff --git a/crates/gpui2/src/interactive.rs b/crates/gpui2/src/interactive.rs index dd09ad512b..da208b3813 100644 --- a/crates/gpui2/src/interactive.rs +++ b/crates/gpui2/src/interactive.rs @@ -2,7 +2,7 @@ use crate::{ div, point, px, Action, AnyDrag, AnyTooltip, AnyView, AppContext, BorrowWindow, Bounds, Component, DispatchContext, DispatchPhase, Div, Element, ElementId, FocusHandle, KeyMatch, Keystroke, Modifiers, Overflow, Pixels, Point, Render, SharedString, Size, Style, - StyleRefinement, View, ViewContext, + StyleRefinement, Task, View, ViewContext, }; use collections::HashMap; use derive_more::{Deref, DerefMut}; @@ -627,50 +627,48 @@ pub trait ElementInteraction: 'static { let active_tooltip = element_state.active_tooltip.clone(); let pending_mouse_down = element_state.pending_mouse_down.clone(); - cx.on_mouse_event(move |view_state, event: &MouseMoveEvent, phase, cx| { + cx.on_mouse_event(move |_, event: &MouseMoveEvent, phase, cx| { if phase != DispatchPhase::Bubble { return; } let is_hovered = bounds.contains_point(&event.position) && pending_mouse_down.lock().is_none(); - let mut tooltip_lock = active_tooltip.lock(); - - if is_hovered { - if tooltip_lock.is_none() { - *tooltip_lock = Some(ActiveTooltip { - view: tooltip_builder(view_state, cx), - visible: false, - coordinates: event.position, - }); + if !is_hovered { + active_tooltip.lock().take(); + return; + } + if active_tooltip.lock().is_none() { + let task = cx.spawn({ let active_tooltip = active_tooltip.clone(); - cx.spawn(move |view, mut cx| async move { - cx.background_executor().timer(TOOLTIP_DELAY).await; + let tooltip_builder = tooltip_builder.clone(); - view.update(&mut cx, |_, cx| { - if let Some(active_tooltip) = active_tooltip.lock().as_mut() { - active_tooltip.visible = true; - active_tooltip.coordinates = - cx.mouse_position() + TOOLTIP_OFFSET; - } + move |view, mut cx| async move { + cx.background_executor().timer(TOOLTIP_DELAY).await; + view.update(&mut cx, move |view_state, cx| { + active_tooltip.lock().replace(ActiveTooltip { + waiting: None, + tooltip: Some(AnyTooltip { + view: tooltip_builder(view_state, cx), + cursor_offset: cx.mouse_position() + TOOLTIP_OFFSET, + }), + }); cx.notify(); }) - .ok() - }) - .detach(); - } - } else { - tooltip_lock.take(); + .ok(); + } + }); + active_tooltip.lock().replace(ActiveTooltip { + waiting: Some(task), + tooltip: None, + }); } }); if let Some(active_tooltip) = element_state.active_tooltip.lock().as_ref() { - if active_tooltip.visible { - cx.active_tooltip = Some(AnyTooltip { - view: active_tooltip.view.clone(), - cursor_offset: active_tooltip.coordinates, - }); + if active_tooltip.tooltip.is_some() { + cx.active_tooltip = active_tooltip.tooltip.clone() } } } @@ -866,9 +864,9 @@ pub struct InteractiveElementState { } struct ActiveTooltip { - view: AnyView, - visible: bool, - coordinates: Point, + #[allow(unused)] // used to drop the task + waiting: Option>, + tooltip: Option, } impl InteractiveElementState { diff --git a/crates/ui2/src/components/tooltip.rs b/crates/ui2/src/components/tooltip.rs index 0bc00a9be1..c05214eea4 100644 --- a/crates/ui2/src/components/tooltip.rs +++ b/crates/ui2/src/components/tooltip.rs @@ -1,5 +1,3 @@ -use std::time::Duration; - use gpui2::{div, px, Div, ParentElement, Render, SharedString, Styled, ViewContext}; use theme2::ActiveTheme;