editor: Add delay for selection drag to prevent accidental drag over attempt for new selection (#32586)
- Add `300ms` delay for it to consider it as selection drag instead of an attempt to make a new selection. - Add cursor icon while dragging the selection. This is same as what chromium does: https://chromium.googlesource.com/chromium/blink/+/master/Source/core/input/EventHandler.cpp#142 Release Notes: - Fixed issue where you accidentally end up dragging the selection where intent was to make a new one instead. To drag selection now, you need to hold just a little longer before dragging.
This commit is contained in:
parent
04223f304b
commit
13ee78c0b4
2 changed files with 57 additions and 16 deletions
|
@ -912,6 +912,7 @@ enum SelectionDragState {
|
||||||
ReadyToDrag {
|
ReadyToDrag {
|
||||||
selection: Selection<Anchor>,
|
selection: Selection<Anchor>,
|
||||||
click_position: gpui::Point<Pixels>,
|
click_position: gpui::Point<Pixels>,
|
||||||
|
mouse_down_time: Instant,
|
||||||
},
|
},
|
||||||
/// State when the mouse is dragging the selection in the editor.
|
/// State when the mouse is dragging the selection in the editor.
|
||||||
Dragging {
|
Dragging {
|
||||||
|
|
|
@ -75,7 +75,7 @@ use std::{
|
||||||
ops::{Deref, Range},
|
ops::{Deref, Range},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use sum_tree::Bias;
|
use sum_tree::Bias;
|
||||||
use text::{BufferId, SelectionGoal};
|
use text::{BufferId, SelectionGoal};
|
||||||
|
@ -87,6 +87,7 @@ use util::{RangeExt, ResultExt, debug_panic};
|
||||||
use workspace::{CollaboratorId, Workspace, item::Item, notifications::NotifyTaskExt};
|
use workspace::{CollaboratorId, Workspace, item::Item, notifications::NotifyTaskExt};
|
||||||
|
|
||||||
const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 7.;
|
const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 7.;
|
||||||
|
const SELECTION_DRAG_DELAY: Duration = Duration::from_millis(300);
|
||||||
|
|
||||||
/// Determines what kinds of highlights should be applied to a lines background.
|
/// Determines what kinds of highlights should be applied to a lines background.
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
|
@ -642,6 +643,7 @@ impl EditorElement {
|
||||||
editor.selection_drag_state = SelectionDragState::ReadyToDrag {
|
editor.selection_drag_state = SelectionDragState::ReadyToDrag {
|
||||||
selection: newest_anchor.clone(),
|
selection: newest_anchor.clone(),
|
||||||
click_position: event.position,
|
click_position: event.position,
|
||||||
|
mouse_down_time: Instant::now(),
|
||||||
};
|
};
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
return;
|
return;
|
||||||
|
@ -837,6 +839,7 @@ impl EditorElement {
|
||||||
SelectionDragState::ReadyToDrag {
|
SelectionDragState::ReadyToDrag {
|
||||||
selection: _,
|
selection: _,
|
||||||
ref click_position,
|
ref click_position,
|
||||||
|
mouse_down_time: _,
|
||||||
} => {
|
} => {
|
||||||
if event.position == *click_position {
|
if event.position == *click_position {
|
||||||
editor.select(
|
editor.select(
|
||||||
|
@ -851,6 +854,8 @@ impl EditorElement {
|
||||||
editor.selection_drag_state = SelectionDragState::None;
|
editor.selection_drag_state = SelectionDragState::None;
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
debug_panic!("drag state can never be in ready state after drag")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SelectionDragState::Dragging { ref selection, .. } => {
|
SelectionDragState::Dragging { ref selection, .. } => {
|
||||||
|
@ -993,8 +998,15 @@ impl EditorElement {
|
||||||
drop_cursor.start = drop_anchor;
|
drop_cursor.start = drop_anchor;
|
||||||
drop_cursor.end = drop_anchor;
|
drop_cursor.end = drop_anchor;
|
||||||
*hide_drop_cursor = !text_hitbox.is_hovered(window);
|
*hide_drop_cursor = !text_hitbox.is_hovered(window);
|
||||||
|
editor.apply_scroll_delta(scroll_delta, window, cx);
|
||||||
|
cx.notify();
|
||||||
}
|
}
|
||||||
SelectionDragState::ReadyToDrag { ref selection, .. } => {
|
SelectionDragState::ReadyToDrag {
|
||||||
|
ref selection,
|
||||||
|
ref click_position,
|
||||||
|
ref mouse_down_time,
|
||||||
|
} => {
|
||||||
|
if mouse_down_time.elapsed() >= SELECTION_DRAG_DELAY {
|
||||||
let drop_cursor = Selection {
|
let drop_cursor = Selection {
|
||||||
id: post_inc(&mut editor.selections.next_selection_id),
|
id: post_inc(&mut editor.selections.next_selection_id),
|
||||||
start: drop_anchor,
|
start: drop_anchor,
|
||||||
|
@ -1007,11 +1019,33 @@ impl EditorElement {
|
||||||
drop_cursor,
|
drop_cursor,
|
||||||
hide_drop_cursor: false,
|
hide_drop_cursor: false,
|
||||||
};
|
};
|
||||||
|
editor.apply_scroll_delta(scroll_delta, window, cx);
|
||||||
|
cx.notify();
|
||||||
|
} else {
|
||||||
|
let click_point = position_map.point_for_position(*click_position);
|
||||||
|
editor.selection_drag_state = SelectionDragState::None;
|
||||||
|
editor.select(
|
||||||
|
SelectPhase::Begin {
|
||||||
|
position: click_point.previous_valid,
|
||||||
|
add: false,
|
||||||
|
click_count: 1,
|
||||||
|
},
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
editor.select(
|
||||||
|
SelectPhase::Update {
|
||||||
|
position: point_for_position.previous_valid,
|
||||||
|
goal_column: point_for_position.exact_unclipped.column(),
|
||||||
|
scroll_delta,
|
||||||
|
},
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
editor.apply_scroll_delta(scroll_delta, window, cx);
|
|
||||||
cx.notify();
|
|
||||||
} else {
|
} else {
|
||||||
editor.select(
|
editor.select(
|
||||||
SelectPhase::Update {
|
SelectPhase::Update {
|
||||||
|
@ -5577,6 +5611,12 @@ impl EditorElement {
|
||||||
let editor = self.editor.read(cx);
|
let editor = self.editor.read(cx);
|
||||||
if editor.mouse_cursor_hidden {
|
if editor.mouse_cursor_hidden {
|
||||||
window.set_window_cursor_style(CursorStyle::None);
|
window.set_window_cursor_style(CursorStyle::None);
|
||||||
|
} else if matches!(
|
||||||
|
editor.selection_drag_state,
|
||||||
|
SelectionDragState::Dragging { .. }
|
||||||
|
) {
|
||||||
|
window
|
||||||
|
.set_cursor_style(CursorStyle::DragCopy, &layout.position_map.text_hitbox);
|
||||||
} else if editor
|
} else if editor
|
||||||
.hovered_link_state
|
.hovered_link_state
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue