diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index b8c152ae40..9dd41fa25d 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -126,6 +126,7 @@ const MAX_LINE_LEN: usize = 1024; const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10; const MAX_SELECTION_HISTORY_LEN: usize = 1024; const COPILOT_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(75); +pub(crate) const CURSORS_VISIBLE_FOR: Duration = Duration::from_millis(2000); #[doc(hidden)] pub const CODE_ACTIONS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(250); #[doc(hidden)] @@ -369,7 +370,7 @@ pub struct Editor { collaboration_hub: Option>, blink_manager: Model, show_cursor_names: bool, - hovered_cursor: Option, + hovered_cursors: HashMap>, pub show_local_selections: bool, mode: EditorMode, show_gutter: bool, @@ -463,6 +464,7 @@ enum SelectionHistoryMode { Redoing, } +#[derive(Clone, PartialEq, Eq, Hash)] struct HoveredCursor { replica_id: u16, selection_id: usize, @@ -1440,7 +1442,7 @@ impl Editor { gutter_width: Default::default(), style: None, show_cursor_names: false, - hovered_cursor: Default::default(), + hovered_cursors: Default::default(), editor_actions: Default::default(), show_copilot_suggestions: mode == EditorMode::Full, _subscriptions: vec![ @@ -3741,7 +3743,7 @@ impl Editor { self.show_cursor_names = true; cx.notify(); cx.spawn(|this, mut cx| async move { - cx.background_executor().timer(Duration::from_secs(3)).await; + cx.background_executor().timer(CURSORS_VISIBLE_FOR).await; this.update(&mut cx, |this, cx| { this.show_cursor_names = false; cx.notify() diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index dadcc62842..65d2e06d35 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -17,8 +17,8 @@ use crate::{ mouse_context_menu, scroll::scroll_amount::ScrollAmount, CursorShape, DisplayPoint, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, - HalfPageDown, HalfPageUp, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, SelectPhase, - Selection, SoftWrap, ToPoint, MAX_LINE_LEN, + HalfPageDown, HalfPageUp, HoveredCursor, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, + Point, SelectPhase, Selection, SoftWrap, ToPoint, CURSORS_VISIBLE_FOR, MAX_LINE_LEN, }; use anyhow::Result; use collections::{BTreeMap, HashMap}; @@ -612,13 +612,24 @@ impl EditorElement { .anchor_at(range.end.to_point(&snapshot.display_snapshot), Bias::Right); let Some(selection) = snapshot.remote_selections_in_range(&range, hub, cx).next() else { - editor.hovered_cursor.take(); return; }; - editor.hovered_cursor.replace(crate::HoveredCursor { + let key = crate::HoveredCursor { replica_id: selection.replica_id, selection_id: selection.selection.id, - }); + }; + editor.hovered_cursors.insert( + key.clone(), + cx.spawn(|editor, mut cx| async move { + cx.background_executor().timer(CURSORS_VISIBLE_FOR).await; + editor + .update(&mut cx, |editor, cx| { + editor.hovered_cursors.remove(&key); + cx.notify(); + }) + .ok(); + }), + ); cx.notify() } @@ -1986,7 +1997,9 @@ impl EditorElement { if Some(selection.peer_id) == editor.leader_peer_id { continue; } - let is_shown = editor.show_cursor_names || editor.hovered_cursor.as_ref().is_some_and(|c| c.replica_id == selection.replica_id && c.selection_id == selection.selection.id); + let key = HoveredCursor{replica_id: selection.replica_id, selection_id: selection.selection.id}; + + let is_shown = editor.show_cursor_names || editor.hovered_cursors.contains_key(&key); remote_selections .entry(selection.replica_id)