- Skip user tab_title_template for synthetic tabs (tab_id < 0) so custom
templates referencing layout_name no longer produce '? +' during drags
- Always append the '+' drop indicator to tab_bar_data (not only during
window drags), making it a persistent clickable new-tab button
- Handle click on the '+' tab (tab_id == -1) in the tab bar mouse handler
by calling new_tab() on left-button release
When a USB HID device (keyboard/mouse) is disconnected, X11 fires an
XI_HierarchyChanged event, which triggers read_xi_scroll_devices().
That function calls XIGetProperty() on devices from XIQueryDevice().
There is a race condition: if a device is removed between these calls,
X11 generates an XI_BadDevice error. Without a custom error handler, the
default X11 handler calls exit(), killing kitty.
Fix: wrap the device query loop in read_xi_scroll_devices() with
_glfwGrabErrorHandlerX11() / _glfwReleaseErrorHandlerX11() so that any
XI_BadDevice error is captured by kitty's own handler rather than the
default fatal one.
Fixes#9723Fixes#9724
Appends a synthetic TabBarData(tab_id=-1, title='+') to tab_bar_data
while a window drag is active. The existing tab highlight machinery
(_set_drag_target_tab / mark_tab_bar_dirty) handles hover highlighting
with no extra state. Dropping on it falls through the existing new-tab
branch in on_window_drop (tab_for_id(-1) returns None). Mark tab bar
dirty at drag start so the indicator appears immediately, and again
after set_window_being_dragged() on drop so it clears right away.
splits.py: insert_window_next_to called split_and_add on self.pairs_root
instead of on the pair found by pair_for_window. split_and_add only handles
direct children, so nested dest windows fell to 'else: self.two = pair',
silently replacing an entire subtree. Lost windows were re-added by
do_layout, producing phantom panes.
tabs.py: on_window_drop returned early (window not found) before calling
_clear_force_show_title_bars, leaving the drag overlay stuck on screen.
quadrant=5: title bar hover — full window overlay + title bar highlight
quadrant=6: body hover (non-Splits) — full window overlay only
quadrant=1-4: Splits body hover — directional half-window overlay
Previously quadrant=5 was used for all full-window cases, causing
is_drag_target=True to fire on body hover which incorrectly lit up
the title bar highlight whenever hovering any window body.
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#9713Fixes#9715
This ensures that Ctrl+H behaves like Backspace and correctly clears
the pre-edit state, preventing uncommitted characters from remaining
on the screen when using IMEs like the Japanese one on macOS.