66 Commits

Author SHA1 Message Date
Mark Stuart
852fc4a662 Add equalize action and equalize_on_close option to Splits layout
Adds an `equalize` layout action that redistributes split sizes so each
window receives a proportional share of space along each axis.

Also adds an `equalize_on_close` layout option that automatically
equalizes splits whenever a window is closed, keeping the remaining
windows balanced without requiring an explicit key binding.

These two features compose well. For example, to keep splits balanced
at all times - equalizing on every open and close:

    enabled_layouts splits:equalize_on_close=true
    map ctrl+' combine : launch --location=hsplit --cwd=current : layout_action equalize
    map ctrl+/ combine : launch --location=vsplit --cwd=current : layout_action equalize

A standalone key binding for manual rebalancing is also supported:

    map ctrl+shift+e layout_action equalize
2026-05-29 20:02:42 +01:00
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
Kovid Goyal
3d369f8632 Cleanup handling of drag_overlay_mode 2026-03-28 13:26:56 +05:30
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
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
ad560715a6 Track border rect orientation explicitly 2026-03-02 21:34:48 +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
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
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
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
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
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
bdf3b9300e Make creation of window_id_map generic 2025-08-04 16:28:06 +05:30
Kovid Goyal
16e659c477 DRYer 2025-08-04 16:16:55 +05:30
Kovid Goyal
e6f35571a5 Implement full serialization/unserialization for layouts
Need to go over all the non-split layouts and see if they need
any TLC
2025-08-04 15:51:46 +05:30
Kovid Goyal
c4ed1d3b69 Implement unserialization for splits layout
Also cleanup the serialization code.
2025-08-02 12:12:40 +05:30
Kovid Goyal
d548a6fcf4 rename typing module to avoid conflicts with stdlib typing 2025-04-28 09:20:10 +05:30
Kovid Goyal
244f4597dc launch: Decouple source and dest windows from active window
Fixes #8295
2025-02-07 13:40:44 +05:30
Kovid Goyal
da1626090a Update codebase to Python 3.10 using pyupgrade 2025-02-03 10:56:50 +05:30
Kovid Goyal
9d48fa9126 hints/unicode_input kittens: Do not lose keypresses that are sent very rapidly via an automation tool immediately after the kitten is launched
We now buffer the key events until the kitten tells us it is ready.
Without this the key presses are delivered to the underlying window
as the kitten's overlay window was not being focused until the kitten
set the ready message.

Fixes #7089
2024-12-12 13:11:12 +05:30
Kovid Goyal
62fbda8c9b When re-attaching a detached tab preserve internal layout state such as biases and orientations
Fixes #8106
2024-12-06 19:54:10 +05:30
Kovid Goyal
681048f1ca launch command: A new --bias option to adjust the size of newly created windows declaratively
Still need to implement it for the Grid layout.
Fixes #7634
2024-07-20 12:37:18 +05:30
Kovid Goyal
04735eb072 ... 2024-07-15 22:21:21 +05:30
Johannes Wüller
7c8660a694 Extend placement_stragegy options
placement_strategy previously only accepted 'center' and 'top-left', but
others are potentially useful too. I personally like 'bottom-left'. The
new set of accepted values mirrors the window_logo_position option.
2024-05-08 16:33:04 +02:00
Kovid Goyal
2a5ba519f5 Fix #6923 2023-12-17 10:50:18 +05:30
Kovid Goyal
fccd776732 Fix overlay windows not inheriting the per-window padding and margin settings of their parents
Fixes #6063
2023-03-01 21:45:17 +05:30
Kovid Goyal
7fe5d7b58f Replace isort with ruff 2023-01-09 16:47:42 +05:30
Kovid Goyal
2e8ef66496 Another mypy update another round of spurious errors 2022-11-08 17:17:40 +05:30
Kovid Goyal
c40ef01445 Fix resizing window that is extra tall/wide because of left-over cells not working reliably
Fixes #4913
2022-04-08 15:41:53 +05:30
Kovid Goyal
ab8a4c6b9f Make per cell bias calculation overridable more easily 2022-04-08 14:52:53 +05:30
Kovid Goyal
6dc1617429 Avoid flicker when starting kittens such as the hints kitten
Fixes #4674
2022-03-23 15:55:11 +05:30
Kovid Goyal
ba1b3c3c2d Fix mypy failures 2022-03-12 08:28:43 +05:30
pagedown
ba0f61d752 Refactor: More f-string for kitty 2022-01-29 20:17:46 +08:00
Kovid Goyal
4494ddd8ff mypy: Turn on return value checks
Its a shame GvR is married to "return None"
https://github.com/python/mypy/issues/7511
2021-10-26 22:39:14 +05:30
Kovid Goyal
4fd76b09d9 kitty @ ls: Also report layout options 2021-10-21 13:44:06 +05:30
Kovid Goyal
6546c1da9b run pyupgrade to upgrade the codebase to python3.6 2021-10-21 12:43:55 +05:30