editor: Dismiss drag selection when dropped outside editor (#32382)

This PR fixes two issues:

1. On macOS, using Alt to copy the selection instead of cutting it.
2. Dropping the drag selection outside the editor dismisses it.  


https://github.com/user-attachments/assets/341e21c3-3eca-4e58-9bcc-8ec1de18e999


Release Notes:

- N/A

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This commit is contained in:
CharlesChen0823 2025-06-10 18:11:59 +08:00 committed by GitHub
parent 2dad48d8d9
commit eb5f59577d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 14 deletions

View file

@ -918,6 +918,7 @@ enum SelectionDragState {
Dragging {
selection: Selection<Anchor>,
drop_cursor: Selection<Anchor>,
hide_drop_cursor: bool,
},
}

View file

@ -856,8 +856,11 @@ impl EditorElement {
SelectionDragState::Dragging { ref selection, .. } => {
let snapshot = editor.snapshot(window, cx);
let selection_display = selection.map(|anchor| anchor.to_display_point(&snapshot));
if !point_for_position.intersects_selection(&selection_display) {
let is_cut = !event.modifiers.control;
if !point_for_position.intersects_selection(&selection_display)
&& text_hitbox.is_hovered(window)
{
let is_cut = !(cfg!(target_os = "macos") && event.modifiers.alt
|| cfg!(not(target_os = "macos")) && event.modifiers.control);
editor.move_selection_on_drop(
&selection.clone(),
point_for_position.previous_valid,
@ -865,10 +868,11 @@ impl EditorElement {
window,
cx,
);
editor.selection_drag_state = SelectionDragState::None;
cx.stop_propagation();
return;
}
editor.selection_drag_state = SelectionDragState::None;
cx.stop_propagation();
cx.notify();
return;
}
_ => {}
}
@ -941,7 +945,8 @@ impl EditorElement {
return;
}
let text_bounds = position_map.text_hitbox.bounds;
let text_hitbox = &position_map.text_hitbox;
let text_bounds = text_hitbox.bounds;
let point_for_position = position_map.point_for_position(event.position);
let mut scroll_delta = gpui::Point::<f32>::default();
@ -982,10 +987,12 @@ impl EditorElement {
match editor.selection_drag_state {
SelectionDragState::Dragging {
ref mut drop_cursor,
ref mut hide_drop_cursor,
..
} => {
drop_cursor.start = drop_anchor;
drop_cursor.end = drop_anchor;
*hide_drop_cursor = !text_hitbox.is_hovered(window);
}
SelectionDragState::ReadyToDrag { ref selection, .. } => {
let drop_cursor = Selection {
@ -998,6 +1005,7 @@ impl EditorElement {
editor.selection_drag_state = SelectionDragState::Dragging {
selection: selection.clone(),
drop_cursor,
hide_drop_cursor: false,
};
}
_ => {}
@ -1251,16 +1259,18 @@ impl EditorElement {
if let SelectionDragState::Dragging {
ref selection,
ref drop_cursor,
ref hide_drop_cursor,
} = editor.selection_drag_state
{
if drop_cursor
.start
.cmp(&selection.start, &snapshot.buffer_snapshot)
.eq(&Ordering::Less)
|| drop_cursor
.end
.cmp(&selection.end, &snapshot.buffer_snapshot)
.eq(&Ordering::Greater)
if !hide_drop_cursor
&& (drop_cursor
.start
.cmp(&selection.start, &snapshot.buffer_snapshot)
.eq(&Ordering::Less)
|| drop_cursor
.end
.cmp(&selection.end, &snapshot.buffer_snapshot)
.eq(&Ordering::Greater))
{
let drag_cursor_layout = SelectionLayout::new(
drop_cursor.clone(),