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 {
position: DisplayPoint,
reset: bool,
goal_column: u32,
},
Extend {
@ -2277,7 +2278,8 @@ impl Editor {
SelectPhase::BeginColumnar {
position,
goal_column,
} => self.begin_columnar_selection(position, goal_column, cx),
reset,
} => self.begin_columnar_selection(position, goal_column, reset, cx),
SelectPhase::Extend {
position,
click_count,
@ -2397,6 +2399,7 @@ impl Editor {
&mut self,
position: DisplayPoint,
goal_column: u32,
reset: bool,
cx: &mut ViewContext<Self>,
) {
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));
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();
self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail));
self.select_columns(
tail.to_display_point(&display_map),
position,
goal_column,
&display_map,
cx,
);
if !reset {
self.select_columns(
tail.to_display_point(&display_map),
position,
goal_column,
&display_map,
cx,
);
}
}
fn update_selection(

View file

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