Wayland: Improve first click detection (#11371)

Fernando Tagawa created

Release Notes:

- N/A

This changes the first click detection in Wayland by requiring first
click after the keyboard loses focus, and after a `wl_pointer` enters a
window that has keyboard focus

Change summary

crates/gpui/src/platform/linux/wayland/client.rs | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

Detailed changes

crates/gpui/src/platform/linux/wayland/client.rs 🔗

@@ -807,6 +807,7 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientStatePtr {
             } => {
                 state.serial = serial;
                 state.keyboard_focused_window = get_window(&mut state, &surface.id());
+                state.enter_token = Some(());
 
                 if let Some(window) = state.keyboard_focused_window.clone() {
                     drop(state);
@@ -819,6 +820,7 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientStatePtr {
                 state.serial = serial;
                 let keyboard_focused_window = get_window(&mut state, &surface.id());
                 state.keyboard_focused_window = None;
+                state.enter_token.take();
 
                 if let Some(window) = keyboard_focused_window {
                     drop(state);
@@ -973,8 +975,10 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientStatePtr {
                 state.mouse_location = Some(point(px(surface_x as f32), px(surface_y as f32)));
 
                 if let Some(window) = get_window(&mut state, &surface.id()) {
-                    state.enter_token = Some(());
                     state.mouse_focused_window = Some(window.clone());
+                    if state.enter_token.is_some() {
+                        state.enter_token = None;
+                    }
                     if let Some(style) = state.cursor_style {
                         if let Some(cursor_shape_device) = &state.cursor_shape_device {
                             cursor_shape_device.set_shape(serial, style.to_shape());
@@ -990,7 +994,6 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientStatePtr {
             }
             wl_pointer::Event::Leave { surface, .. } => {
                 if let Some(focused_window) = state.mouse_focused_window.clone() {
-                    state.enter_token.take();
                     let input = PlatformInput::MouseExited(MouseExitEvent {
                         position: state.mouse_location.unwrap(),
                         pressed_button: state.button_pressed,
@@ -1016,6 +1019,13 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientStatePtr {
                 state.mouse_location = Some(point(px(surface_x as f32), px(surface_y as f32)));
 
                 if let Some(window) = state.mouse_focused_window.clone() {
+                    if state
+                        .keyboard_focused_window
+                        .as_ref()
+                        .map_or(false, |keyboard_window| window.ptr_eq(&keyboard_window))
+                    {
+                        state.enter_token = None;
+                    }
                     let input = PlatformInput::MouseMove(MouseMoveEvent {
                         position: state.mouse_location.unwrap(),
                         pressed_button: state.button_pressed,