131 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 20185fc317 Fix display corruption when maximizing horizontal split with window_padding_width >= 4 (issue #9946)
Agent-Logs-Url: https://github.com/kovidgoyal/kitty/sessions/3b0c9eab-24ba-4934-a941-be477477cee4

Co-authored-by: kovidgoyal <1308621+kovidgoyal@users.noreply.github.com>
2026-05-01 15:04:46 +00:00
Kovid Goyal fcb260bdfa Sort imports 2026-04-19 21:53:09 +05:30
Kovid Goyal 04fcac72ec Update minimum python to 3.11 from 3.10
3.10 is failing in CI and I cant be arsed to figure out why. It's anyway
a few months from EOL
2026-04-19 21:41:58 +05:30
copilot-swe-agent[bot] 96d10e51a0 Fix drag resize direction bugs and add comprehensive tests
Agent-Logs-Url: https://github.com/kovidgoyal/kitty/sessions/12198e55-3901-439b-9fba-9b5f5b470416

Co-authored-by: kovidgoyal <1308621+kovidgoyal@users.noreply.github.com>
2026-04-01 03:48:49 +00:00
copilot-swe-agent[bot] c3a111fbd2 Fix inverted border drag direction in splits layout
Agent-Logs-Url: https://github.com/kovidgoyal/kitty/sessions/10200944-3143-4347-880c-f4d5b96749f5

Co-authored-by: kovidgoyal <1308621+kovidgoyal@users.noreply.github.com>
2026-03-31 16:28:19 +00:00
Kovid Goyal 3d369f8632 Cleanup handling of drag_overlay_mode 2026-03-28 13:26:56 +05:30
mcrmck 6c37c1c391 Fix mypy: annotate drag_overlay_mode with full union type in Vertical and Tall
Bare literal assignments (drag_overlay_mode = 'axis_y') cause mypy to
narrow-infer the type as Literal['axis_y'] on the parent class, making
the subclass override (Horizontal = 'axis_x', Fat = 'axis_x') an
incompatible assignment. Fix by explicitly annotating Vertical and Tall
with the full union type from the base class, so the declared type stays
wide and subclasses can freely assign any valid mode.

Also removes unused ClassVar/Literal imports from splits.py.
2026-03-27 02:25:35 -04:00
mcrmck d1b8df6975 Fix mypy error: remove narrowing ClassVar[Literal] annotations from layout subclasses
Horizontal extends Vertical, and Fat extends Tall. Declaring
drag_overlay_mode with a narrower Literal type in the subclass
conflicts with the parent's declared type, causing mypy error
"Incompatible types in assignment". Since the base Layout class already
declares the full union type, subclasses only need a bare assignment.

Also removes now-unused ClassVar and Literal imports from vertical.py,
tall.py, and grid.py.
2026-03-27 02:17:59 -04:00
mcrmck a368a90e37 Add directional drag-and-drop inserts for Vertical, Horizontal, Tall, Fat, Grid
Previously, body drops in all non-Splits layouts showed a full-window overlay
and performed a positional swap. This adds proper top/bottom or left/right
half-window overlays and true before/after insertion for the five layouts
Kovid identified.

Architecture:

- New `drag_overlay_mode` ClassVar on Layout ('full'|'axis_y'|'axis_x'|'free')
  controls both overlay display and valid direction axis. Layout subclasses set
  one line; tabs.py and boss.py dispatch on this attribute instead of hasattr.

- New `insert_window_group_next_to(target_group_id, after)` on WindowList
  performs a positional insert (not swap) by popping the active group and
  inserting it before or after the target.

- New base `insert_window_next_to` on Layout uses insert_window_group_next_to
  for axis_x/axis_y layouts and falls back to swap for 'full' (Stack).
  Splits overrides this with its existing tree-based implementation.

- `_insert_window_in_direction` in boss.py collapses from a 7-line hasattr
  branch to a single layout.insert_window_next_to() call.

Direction constraints:
  Vertical, Tall, Grid -> top/bottom (axis_y)
  Horizontal, Fat      -> left/right (axis_x)
  Splits               -> 4-way free (unchanged)
  Stack                -> full-window swap (unchanged)
2026-03-27 02:08:41 -04:00
mcrmck 5c0a4accb3 Fix two bugs: splits layout corruption and overlay stuck on early drop exit
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.
2026-03-20 01:34:01 -04:00
mcrmck 462f7025fb Merge upstream/master into feat-draggable-window-title-bars
Resolves conflict in kitty/tabs.py by keeping both force_show_title_bars
and renaming_in_window fields.
2026-03-17 22:40:28 -04:00
copilot-swe-agent[bot] 551acca0e4 Implement maximize layout action for splits layout
Fixes #9629
Fixes #9630
2026-03-09 15:27:54 +05:30
mcrmck 59c963c481 Add draggable window title bars
Implements drag-to-reorder for window title bars, following up on the
merged window title bar feature (#9450) and the design discussion in #9619.

- Drag a title bar and drop on another title bar to swap positions
- Drop on a window body quadrant (left/right/top/bottom) to insert as
  a directional split; Splits layout uses insert_window_next_to(), other
  layouts fall back to move_window_to_group()
- Drop on a tab bar tab to move the window into that tab
- Drop on another OS window to move into its active tab
- Drop outside kitty to detach into a new OS window
- Tab bar highlights the hovered tab during a window drag, mirroring
  how the destination window title bar is highlighted
- toggle_window_title_bars action temporarily force-shows title bars
  for drag-to-reorder when they are normally hidden, auto-hiding after
  the drag completes
- window_title_bar_drag_threshold option (default 5px) controls how far
  the mouse must move before a drag is initiated; 0 disables dragging

MIME type follows the same convention as tab dragging:
application/net.kovidgoyal.kitty-window-{PID}

Ref: #9619
2026-03-08 20:56:38 -04:00
Kovid Goyal e1a14551fa Cleanup previous PR 2026-03-05 09:25:10 +05:30
Kovid Goyal b66703ec85 Merge branch 'pane-title-bar' of https://github.com/mcrmck/kitty 2026-03-05 08:31:50 +05:30
mcrmck f2ae5d0028 Add window_title_bar_min_windows option, simplify window_title_bar
- Add window_title_bar_min_windows (0=never, 1=always, 2+=threshold)
  similar to tab_bar_min_tabs, to control when title bars appear
- Remove 'none' choice from window_title_bar so it purely controls
  position (top/bottom); disabling is now via min_windows 0
- Only hide title bar for truly empty template strings, not
  whitespace-only, so users can have intentionally blank bars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:14:54 -05:00
mcrmck dd26469cb3 Rework window title bar architecture per review feedback
- Eliminate double set_geometry() call: removed _apply_window_title_bars()
  which post-processed geometry causing expensive SIGWINCH to children
- Move title bar screen ownership to Window objects instead of central
  manager, with show_title_bar flag set during layout before do_layout()
- Window.set_geometry() now handles title bar geometry internally:
  self.geometry stays at layout-computed value (borders/padding correct),
  only C-side render data diverges via adjusted top/bottom
- Hide title bar for 1-row windows (ynum <= 1)
- Hide title bar when template evaluates to empty/whitespace
- Optimize C render loop: merge title bar GPU prep and draw into existing
  per-window loops, use trd pointer and is_visible=false, use
  num_visible_windows > 1 guard. Eliminates separate iteration passes.
- Simplify WindowTitleBarManager to thin coordinator

Note on C-side GPU prep placement: the suggested patch placed
send_cell_data_to_gpu for title bars inside the is_active_window branch
only. This caused a segfault (NULL deref in gleRunVertexSubmitImmediate)
because inactive windows' title bars had valid screen/geometry but no
GPU data uploaded, yet draw_cells was called for all visible title bars.
Moved to the per-window visibility block alongside the main window's
send_cell_data_to_gpu call so all visible title bars get GPU data
prepared. The draw loop matches the suggested patch exactly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 20:17:38 -05:00
Kovid Goyal 0930535642 Remove debug prints 2026-03-03 13:34:13 +05:30
Kovid Goyal ad560715a6 Track border rect orientation explicitly 2026-03-02 21:34:48 +05:30
Kovid Goyal e09e707dc6 Generalize leading edge special case 2026-03-02 19:28:04 +05:30
Kovid Goyal ba8a8a0980 More work on splits drag resize 2026-03-02 16:43:21 +05:30
Kovid Goyal c3d26f1cf0 Splits layout: cleanup resize drag handling 2026-03-02 16:17:04 +05:30
Kovid Goyal a222df75cb Cleanup splits drag resize handling 2026-03-02 12:37:28 +05:30
Kovid Goyal bc7523fe32 Merge branch 'fix/splits-layout-variable-shadowing' of https://github.com/noomz/kitty 2026-03-02 12:29:06 +05:30
Siriwat Uamganmsup d5e45cf8d3 Splits layout: Fix variable shadowing in layout_pair causing corrupted pane positions
The for loops iterating over edge_border() results in layout_pair() used
top, bottom, left, right as loop variable names, which shadowed the
function's local variables tracking current layout position. This caused
sibling panes to be positioned at incorrect offsets when splitting a pane
that was itself a nested Pair (e.g. splitting the left pane horizontally
would cause the right pane to shift down half the screen).

Rename loop variables to etop, ebottom, eleft, eright to avoid shadowing.
2026-03-02 13:53:59 +07:00
Kovid Goyal 69b9993804 Fix border directionality in grid layout 2026-03-02 11:28:52 +05:30
Kovid Goyal 4264889e9a Fix border marking in tall/fat layout 2026-03-02 11:22:23 +05:30
Kovid Goyal 68d1a336fe Fix edge detection for borders in vert/horz layouts 2026-03-02 11:04:09 +05:30
mcrmck cc32af250b Rename pane → window title bar per reviewer feedback
- Rename all options from pane_title_* to window_title_*
- Use foreground/background instead of fg/bg in color option names
- Change color options to to_color_or_none defaulting to None,
  falling back to corresponding tab bar colors
- Add bell_symbol, activity_symbol, progress_percent template vars
  using existing bell_on_tab and tab_activity_symbol options
- Add custom script support via window_title_bar.py in config dir
  (draw_window_title function exposed as {custom} in templates)
- Update C structs, Python references, and regenerate config files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-01 23:53:28 -05:00
mcrmck ab3a8ca56a Add pane title bar feature for window splits
Add an optional title bar that displays above or below each window pane
when multiple windows are visible in a tab. This is similar to tmux's
pane-border-format or Terminator's pane title bars.

New configuration options:
- pane_title_bar: none/top/bottom (default: none)
- pane_title_template: f-string template (same syntax as tab_title_template)
- active_pane_title_template: override for active pane
- pane_title_bar_active_fg/bg: colors for active pane title
- pane_title_bar_inactive_fg/bg: colors for inactive pane titles
- pane_title_bar_align: left/center/right text alignment

The title bars are rendered using virtual Screen objects registered with
the GPU, following the same model as the tab bar. Title bars are
automatically hidden when only a single window is visible.

Ref: https://github.com/kovidgoyal/kitty/discussions/9448

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-01 23:52:24 -05:00
Kovid Goyal 3281a8d634 DRYer 2026-03-02 08:45:34 +05:30
Kovid Goyal 6b54c201e5 Track window ids on border rects
More robust. Splits layout still needs work.
2026-03-02 08:31:36 +05:30
Kovid Goyal 2d1d340d41 Work on drag resize for splits layout 2026-02-28 07:37:49 +05:30
copilot-swe-agent[bot] 0ad9a15491 Implement drag resize target selection for splits layout
Fixes #9563
2026-02-26 21:57:43 +05:30
Kovid Goyal 09fcb7cef0 Implement resizing semantics based on layout
Still need to do splits layout but all others should be OK
2026-02-26 20:55:43 +05:30
Kovid Goyal ccc0ce5ceb Do drag resize by dragging window borders 2026-02-26 17:36:41 +05:30
Kovid Goyal 852db16fc9 Cleanup mouse.c 2026-02-26 14:53:10 +05:30
Kovid Goyal 609f6ed960 Cleanup tracking of drag resize in Boss 2026-02-26 14:17:26 +05:30
mcrmck 02194b6965 Add mouse drag resize for window splits
Enable Ctrl+left-click-drag to resize window splits. Detects which
windows border the click position using neighbor information from the
layout, then resizes in cell-sized increments as the mouse moves.
Shows a move cursor during the drag operation.

Closes kovidgoyal/kitty#5959

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:22:00 -05:00
Kovid Goyal df17142ea4 Fix #9355 2026-01-06 08:37:24 +05:30
Kovid Goyal e49d940621 kitten @ ls: Also output the neighbors for every window 2025-11-16 21:01:55 +05:30
Kovid Goyal f06f85a9e0 Cleanup previous PR 2025-10-15 09:12:32 +05:30
Jackie Li 6db3441e29 respect draw_window_borders_for_single_window=yes in lgd.draw_minimal_borders 2025-10-14 19:23:35 +01:00
Kovid Goyal 9740861ec5 Splits layout: Fix corrupted layout in some circs
Basically one function was adding a window id instead of a group id
to the pairs. Fixes #9059
2025-10-02 10:43:36 +05:30
Kovid Goyal f925327755 Fix de-serialization of some layouts
Forgot that JSON converts dict keys to strings. Sigh.
2025-08-20 08:10:29 +05:30
Kovid Goyal f91a0f6986 When saving session add option to save the foreground process running in the shell so that it is also restarted
Useful if user builds up session to save by running programs via
the shell.

Note that the serialization format for session files has changed
slightly, becoming more robust and allowing us to add more types
of saved data in the future, without overloading user_vars and thus
risking name conflicts.
2025-08-16 16:50:45 +05:30
Kovid Goyal 3fbdeedfa7 Also make deserialization robust against bools 2025-08-15 12:09:01 +05:30
Kovid Goyal a8de8e45b0 Fix serialization of mirrored option 2025-08-15 12:04:24 +05:30
Kovid Goyal d52f2e7981 Rewrite rendering pipeline
This was needed to fix various corner cases when doing blending of colors
in linear space. The new architecture has the same performance as the
old in the common case of opaque rendering with no UI layers or images.

In the case of only positive z-index images there is a performance
decrease as the OS Window is now rendered to a offscreen texture and
then blitted to screen. However, in the future when we move to Vulkan or
I can figure out how to get Wayland to accept buffers with colors in
linear space, this performance penalty can be removed. The performance
penalty was not significant on my system but this is highly GPU
dependent. Modern GPUs are supposedly optimised for rendering to
offscreen buffers, so we will see. The awrit project might be a good
test case.

Now either we have 1-shot rendering for the case of opaque with only ext
or all the various pieces are rendered in successive draw calls into an
offscreen buffer that is blitted to the output buffer after all drawing
is done.

Fixes #8869
2025-08-11 00:47:02 +05:30
Kovid Goyal 97f1d7f436 Implement session command to set layout state 2025-08-06 20:43:12 +05:30