Fix text selection via click-and-drag in unfocused splits

The regression was introduced by commit b277a016b which added an early
`return` in handle_button_event that prevented kitty's internal text
selection from starting on focus-transfer clicks to unfocused splits.

Changes:
- In handle_button_event: replace the early return with a local
  suppress_child_forwarding flag that prevents PRESS from being forwarded
  to child processes in mouse-tracking mode, while still allowing
  dispatch_mouse_event to run (which starts text selection)
- In mouse_event's active_drag_in_window release path: clear
  suppress_left_mouse_release to prevent stale flags after drags

Fixes #9713
Fixes #9715
This commit is contained in:
copilot-swe-agent[bot] 2026-03-20 02:21:50 +00:00 committed by Kovid Goyal
parent ef7b456ce7
commit 7c79e2fc9e
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C

View file

@ -839,13 +839,16 @@ HANDLER(handle_button_event) {
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 and suppress
// the matching release to avoid release-without-press reports.
// 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;
return;
suppress_child_forwarding = true;
}
}
@ -856,7 +859,7 @@ HANDLER(handle_button_event) {
if (!set_mouse_position(w, &a, &b)) return;
id_type wid = w->id;
if (!dispatch_mouse_event(w, button, is_release ? -1 : 1, modifiers, screen->modes.mouse_tracking_mode != 0)) {
if (screen->modes.mouse_tracking_mode != 0) {
if (!suppress_child_forwarding && 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); }
}
@ -1211,6 +1214,10 @@ 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;