From e7a7362d54b2542cfd35c74ff78fe58943542604 Mon Sep 17 00:00:00 2001 From: zhaolei Date: Tue, 7 Jul 2026 15:35:48 +0800 Subject: [PATCH] Make first mouse clicks activate and pass through Allow the first mouse click on an inactive Cocoa OS window to be delivered to kitty instead of only activating the window. Make the matching kitty-internal behavior consistent by forwarding clicks that switch focus to another kitty window in the currently focused OS window. This lets the same first click both focus the target kitty window and perform the click action, including forwarding to mouse-tracking applications. --- glfw/cocoa_window.m | 2 +- kitty/mouse.c | 23 +---------------------- kitty/state.h | 1 - 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 0ac36b2b6..17d567fcc 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1016,7 +1016,7 @@ static void _glfwUpdateNotchCover(_GLFWwindow*); - (BOOL)acceptsFirstMouse:(NSEvent *)event { (void)event; - return NO; // changed by Kovid, to follow cocoa platform conventions + return YES; // follow cocoa platform conventions } - (void)mouseDown:(NSEvent *)event diff --git a/kitty/mouse.c b/kitty/mouse.c index a7a9a3d9d..f865343bd 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -870,27 +870,10 @@ HANDLER(handle_button_event) { Tab *t = osw->tabs + osw->active_tab; bool is_release = !osw->mouse_button_pressed[button]; - if (button == GLFW_MOUSE_BUTTON_LEFT && osw->suppress_left_mouse_release) { - osw->suppress_left_mouse_release = false; - if (is_release) { - zero_at_ptr(&w->drag_source.initial_left_press); - return; - } - } - if (handle_scrollbar_mouse(w, button, is_release ? RELEASE : PRESS, modifiers)) return; - bool suppress_child_forwarding = false; if (osw->is_focused && window_idx != t->active_window && !is_release) { call_boss(switch_focus_to_in_active_tab, "K", t->windows[window_idx].id); - if (button == GLFW_MOUSE_BUTTON_LEFT) { - // Treat split-focus transfer clicks as focus-only for child processes: - // suppress forwarding the left press and matching release to the child - // to avoid release-without-press reports. Still allow kitty to process - // the event internally (e.g., start text selection via click-and-drag). - osw->suppress_left_mouse_release = true; - suppress_child_forwarding = true; - } } Screen *screen = w->render_data.screen; @@ -909,7 +892,7 @@ HANDLER(handle_button_event) { } id_type wid = w->id; if (!dispatch_mouse_event(w, button, is_release ? -1 : 1, modifiers, screen->modes.mouse_tracking_mode != 0)) { - if (!suppress_child_forwarding && screen->modes.mouse_tracking_mode != 0) { + if (screen->modes.mouse_tracking_mode != 0) { int sz = encode_mouse_button(w, button, is_release ? RELEASE : PRESS, modifiers); if (sz > 0) { mouse_event_buf[sz] = 0; write_escape_code_to_child(screen, ESC_CSI, mouse_event_buf); } } @@ -1316,10 +1299,6 @@ mouse_event(const int button, int modifiers, int action) { w = window_for_id(global_state.active_drag_in_window); if (w) { end_drag(w); - // Clear any stale suppress flag that was set during a focus-transfer - // press, since the drag release bypasses handle_button_event where - // it would normally be cleared. - if (osw) osw->suppress_left_mouse_release = false; debug("handled as drag end\n"); dispatch_possible_click(w, button, modifiers); return; diff --git a/kitty/state.h b/kitty/state.h index 8f01221f2..90c86bab2 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -446,7 +446,6 @@ typedef struct OSWindow { double mouse_x, mouse_y; bool mouse_button_pressed[32]; bool has_too_few_tabs; - bool suppress_left_mouse_release; PyObject *window_title; bool disallow_title_changes, title_is_overriden; bool viewport_size_dirty, viewport_updated_at_least_once;