From 569a7234fd607033d94ee0699b1370677cd09695 Mon Sep 17 00:00:00 2001 From: Daniel Zhu Date: Mon, 25 Mar 2024 10:52:18 -0700 Subject: [PATCH] Handle first click on Zed window (#9553) Fixes #4336 --- crates/collab/src/tests/integration_tests.rs | 2 ++ crates/gpui/src/app/test_context.rs | 1 + crates/gpui/src/interactive.rs | 3 ++ .../gpui/src/platform/linux/wayland/client.rs | 1 + crates/gpui/src/platform/linux/x11/client.rs | 1 + crates/gpui/src/platform/mac/events.rs | 1 + crates/gpui/src/platform/mac/window.rs | 31 +++++++++++++------ crates/gpui/src/platform/windows/window.rs | 2 ++ crates/project_panel/src/project_panel.rs | 2 +- 9 files changed, 33 insertions(+), 11 deletions(-) diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index c92d83f2c5..4877336326 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -5891,6 +5891,7 @@ async fn test_right_click_menu_behind_collab_panel(cx: &mut TestAppContext) { position: new_tab_button_bounds.center(), modifiers: Modifiers::default(), click_count: 1, + first_mouse: false, }); // regression test that the right click menu for tabs does not open. @@ -5902,6 +5903,7 @@ async fn test_right_click_menu_behind_collab_panel(cx: &mut TestAppContext) { position: tab_bounds.center(), modifiers: Modifiers::default(), click_count: 1, + first_mouse: false, }); assert!(cx.debug_bounds("MENU_ITEM-Close").is_some()); } diff --git a/crates/gpui/src/app/test_context.rs b/crates/gpui/src/app/test_context.rs index 7a4255c69b..0b0ee3b200 100644 --- a/crates/gpui/src/app/test_context.rs +++ b/crates/gpui/src/app/test_context.rs @@ -665,6 +665,7 @@ impl VisualTestContext { modifiers, button: MouseButton::Left, click_count: 1, + first_mouse: false, }); self.simulate_event(MouseUpEvent { position, diff --git a/crates/gpui/src/interactive.rs b/crates/gpui/src/interactive.rs index 85b8f871be..c7b946b439 100644 --- a/crates/gpui/src/interactive.rs +++ b/crates/gpui/src/interactive.rs @@ -100,6 +100,9 @@ pub struct MouseDownEvent { /// The number of times the button has been clicked. pub click_count: usize, + + /// Whether this is the first, focusing click. + pub first_mouse: bool, } impl Sealed for MouseDownEvent {} diff --git a/crates/gpui/src/platform/linux/wayland/client.rs b/crates/gpui/src/platform/linux/wayland/client.rs index eb1b01360a..c3fbe3ea25 100644 --- a/crates/gpui/src/platform/linux/wayland/client.rs +++ b/crates/gpui/src/platform/linux/wayland/client.rs @@ -933,6 +933,7 @@ impl Dispatch for WaylandClientState { position: state.mouse_location, modifiers: state.modifiers, click_count: state.click_state.current_count, + first_mouse: false, }), ); } diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index d3288a3c3e..5e552ebeda 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/crates/gpui/src/platform/linux/x11/client.rs @@ -218,6 +218,7 @@ impl X11Client { position, modifiers, click_count: 1, + first_mouse: false, })); } else if event.detail >= 4 && event.detail <= 5 { // https://stackoverflow.com/questions/15510472/scrollwheel-event-in-x11 diff --git a/crates/gpui/src/platform/mac/events.rs b/crates/gpui/src/platform/mac/events.rs index d8bc18bd63..9319dd039d 100644 --- a/crates/gpui/src/platform/mac/events.rs +++ b/crates/gpui/src/platform/mac/events.rs @@ -131,6 +131,7 @@ impl PlatformInput { ), modifiers: read_modifiers(native_event), click_count: native_event.clickCount() as usize, + first_mouse: false, }) }) } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 77cfd55654..ec23835896 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -350,6 +350,8 @@ struct MacWindowState { input_during_keydown: Option>, previous_keydown_inserted_text: Option, external_files_dragged: bool, + // Whether the next left-mouse click is also the focusing click. + first_mouse: bool, minimized: bool, } @@ -607,6 +609,7 @@ impl MacWindow { input_during_keydown: None, previous_keydown_inserted_text: None, external_files_dragged: false, + first_mouse: false, minimized: false, }))); @@ -1262,7 +1265,6 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) { let weak_window_state = Arc::downgrade(&window_state); let mut lock = window_state.as_ref().lock(); let is_active = unsafe { lock.native_window.isKeyWindow() == YES }; - let window_height = lock.content_size().height; let event = unsafe { PlatformInput::from_native(native_event, Some(window_height)) }; @@ -1287,6 +1289,20 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) { }; } + // Handles focusing click. + PlatformInput::MouseDown( + event @ MouseDownEvent { + button: MouseButton::Left, + .. + }, + ) if (lock.first_mouse) => { + *event = MouseDownEvent { + first_mouse: true, + ..*event + }; + lock.first_mouse = false; + } + // Because we map a ctrl-left_down to a right_down -> right_up let's ignore // the ctrl-left_up to avoid having a mismatch in button down/up events if the // user is still holding ctrl when releasing the left mouse button @@ -1745,15 +1761,10 @@ extern "C" fn view_did_change_effective_appearance(this: &Object, _: Sel) { } extern "C" fn accepts_first_mouse(this: &Object, _: Sel, _: id) -> BOOL { - unsafe { - let state = get_window_state(this); - let lock = state.as_ref().lock(); - if lock.kind == WindowKind::PopUp { - YES - } else { - NO - } - } + let window_state = unsafe { get_window_state(this) }; + let mut lock = window_state.as_ref().lock(); + lock.first_mouse = true; + YES } extern "C" fn dragging_entered(this: &Object, _: Sel, dragging_info: id) -> NSDragOperation { diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index b2cb7c330c..a8c77b91f7 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -594,6 +594,7 @@ impl WindowsWindowInner { position: logical_point(x, y, scale_factor), modifiers: self.current_modifiers(), click_count: 1, + first_mouse: false, }; if callback(PlatformInput::MouseDown(event)).default_prevented { return Some(0); @@ -1009,6 +1010,7 @@ impl WindowsWindowInner { position: logical_point(cursor_point.x as f32, cursor_point.y as f32, scale_factor), modifiers: self.current_modifiers(), click_count: 1, + first_mouse: false, }; if callback(PlatformInput::MouseDown(event)).default_prevented { return Some(0); diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 15b5db4cca..631842f9a7 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1450,7 +1450,7 @@ impl ProjectPanel { .ml_1(), ) .on_click(cx.listener(move |this, event: &gpui::ClickEvent, cx| { - if event.down.button == MouseButton::Right { + if event.down.button == MouseButton::Right || event.down.first_mouse { return; } if !show_editor {