Trigger columnar selection behavior on middle mouse down (#12005)

fixes https://github.com/zed-industries/zed/issues/11990

Release Notes:

- Changed middle mouse down to trigger a columnar selection, creating a
rectangle of multi cursors over a dragged region.
([#11990](https://github.com/zed-industries/zed/issues/11990))
This commit is contained in:
Mikayla Maki 2024-05-17 17:57:00 -07:00 committed by GitHub
parent 1f611a9c90
commit 410c46a551
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 66 additions and 26 deletions

View file

@ -302,6 +302,7 @@ pub enum SelectPhase {
}, },
BeginColumnar { BeginColumnar {
position: DisplayPoint, position: DisplayPoint,
reset: bool,
goal_column: u32, goal_column: u32,
}, },
Extend { Extend {
@ -2277,7 +2278,8 @@ impl Editor {
SelectPhase::BeginColumnar { SelectPhase::BeginColumnar {
position, position,
goal_column, goal_column,
} => self.begin_columnar_selection(position, goal_column, cx), reset,
} => self.begin_columnar_selection(position, goal_column, reset, cx),
SelectPhase::Extend { SelectPhase::Extend {
position, position,
click_count, click_count,
@ -2397,6 +2399,7 @@ impl Editor {
&mut self, &mut self,
position: DisplayPoint, position: DisplayPoint,
goal_column: u32, goal_column: u32,
reset: bool,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) { ) {
if !self.focus_handle.is_focused(cx) { if !self.focus_handle.is_focused(cx) {
@ -2404,16 +2407,33 @@ impl Editor {
} }
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
if reset {
let pointer_position = display_map
.buffer_snapshot
.anchor_before(position.to_point(&display_map));
self.change_selections(Some(Autoscroll::newest()), cx, |s| {
s.clear_disjoint();
s.set_pending_anchor_range(
pointer_position..pointer_position,
SelectMode::Character,
);
});
}
let tail = self.selections.newest::<Point>(cx).tail(); let tail = self.selections.newest::<Point>(cx).tail();
self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail)); self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail));
self.select_columns( if !reset {
tail.to_display_point(&display_map), self.select_columns(
position, tail.to_display_point(&display_map),
goal_column, position,
&display_map, goal_column,
cx, &display_map,
); cx,
);
}
} }
fn update_selection( fn update_selection(

View file

@ -477,6 +477,7 @@ impl EditorElement {
editor.select( editor.select(
SelectPhase::BeginColumnar { SelectPhase::BeginColumnar {
position, position,
reset: false,
goal_column: point_for_position.exact_unclipped.column(), goal_column: point_for_position.exact_unclipped.column(),
}, },
cx, cx,
@ -530,7 +531,6 @@ impl EditorElement {
cx.stop_propagation(); cx.stop_propagation();
} }
#[cfg(target_os = "linux")]
fn mouse_middle_down( fn mouse_middle_down(
editor: &mut Editor, editor: &mut Editor,
event: &MouseDownEvent, event: &MouseDownEvent,
@ -538,25 +538,22 @@ impl EditorElement {
text_hitbox: &Hitbox, text_hitbox: &Hitbox,
cx: &mut ViewContext<Editor>, cx: &mut ViewContext<Editor>,
) { ) {
if !text_hitbox.is_hovered(cx) || editor.read_only(cx) { if cx.default_prevented() {
return; return;
} }
if let Some(item) = cx.read_from_primary() { let point_for_position =
let point_for_position = position_map.point_for_position(text_hitbox.bounds, event.position);
position_map.point_for_position(text_hitbox.bounds, event.position); let position = point_for_position.previous_valid;
let position = point_for_position.previous_valid;
editor.select( editor.select(
SelectPhase::Begin { SelectPhase::BeginColumnar {
position, position,
add: false, reset: true,
click_count: 1, goal_column: point_for_position.exact_unclipped.column(),
}, },
cx, cx,
); );
editor.insert(item.text(), cx);
}
} }
fn mouse_up( fn mouse_up(
@ -586,6 +583,28 @@ impl EditorElement {
cx.stop_propagation(); cx.stop_propagation();
} else if end_selection { } else if end_selection {
cx.stop_propagation(); cx.stop_propagation();
} else if cfg!(target_os = "linux") && event.button == MouseButton::Middle {
if !text_hitbox.is_hovered(cx) || editor.read_only(cx) {
return;
}
#[cfg(target_os = "linux")]
if let Some(item) = cx.read_from_clipboard() {
let point_for_position =
position_map.point_for_position(text_hitbox.bounds, event.position);
let position = point_for_position.previous_valid;
editor.select(
SelectPhase::Begin {
position,
add: false,
click_count: 1,
},
cx,
);
editor.insert(item.text(), cx);
}
cx.stop_propagation()
} }
} }
@ -3241,7 +3260,6 @@ impl EditorElement {
MouseButton::Right => editor.update(cx, |editor, cx| { MouseButton::Right => editor.update(cx, |editor, cx| {
Self::mouse_right_down(editor, event, &position_map, &text_hitbox, cx); Self::mouse_right_down(editor, event, &position_map, &text_hitbox, cx);
}), }),
#[cfg(target_os = "linux")]
MouseButton::Middle => editor.update(cx, |editor, cx| { MouseButton::Middle => editor.update(cx, |editor, cx| {
Self::mouse_middle_down(editor, event, &position_map, &text_hitbox, cx); Self::mouse_middle_down(editor, event, &position_map, &text_hitbox, cx);
}), }),
@ -3273,7 +3291,9 @@ impl EditorElement {
move |event: &MouseMoveEvent, phase, cx| { move |event: &MouseMoveEvent, phase, cx| {
if phase == DispatchPhase::Bubble { if phase == DispatchPhase::Bubble {
editor.update(cx, |editor, cx| { editor.update(cx, |editor, cx| {
if event.pressed_button == Some(MouseButton::Left) { if event.pressed_button == Some(MouseButton::Left)
|| event.pressed_button == Some(MouseButton::Middle)
{
Self::mouse_dragged( Self::mouse_dragged(
editor, editor,
event, event,