From b277a016bec0d6583720d4f17720474f79eca9bb Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Wed, 4 Mar 2026 13:35:55 -0600 Subject: [PATCH] mouse suppress split focus-transfer clicks Treat left clicks that only transfer split focus as focus-only events. Suppress forwarding the left press and matching release to the child so applications do not see release-without-press sequences. Amp-Thread-ID: https://ampcode.com/threads/T-019cba50-5f2e-763b-ab5f-aa8c96a45747 Co-authored-by: Amp --- kitty/mouse.c | 13 ++++++++++++- kitty/state.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/kitty/mouse.c b/kitty/mouse.c index 3a7e3921d..76821d00f 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -832,10 +832,21 @@ 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 && is_release && osw->suppress_left_mouse_release) { + osw->suppress_left_mouse_release = false; + return; + } + if (handle_scrollbar_mouse(w, button, is_release ? RELEASE : PRESS, modifiers)) return; - if (window_idx != t->active_window && !is_release) { + 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 and suppress + // the matching release to avoid release-without-press reports. + osw->suppress_left_mouse_release = true; + return; + } } Screen *screen = w->render_data.screen; diff --git a/kitty/state.h b/kitty/state.h index 0fa8a69d8..71e986c38 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -329,6 +329,7 @@ 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;