Commit graph

1538 commits

Author SHA1 Message Date
Kovid Goyal
cb4cefee5a
misc layout code robustness fixes 2026-08-05 21:04:30 +05:30
Chance Zibolski
1b81045008 Save the layout state of every layout a tab has used to sessions
save_as_session recorded only the state of the tab's active layout, so the state
of any layout the tab had been toggled away from was lost. Toggling a splits tab
to the stack layout and saving discarded the splits tree entirely, because Stack
has no layout_state() of its own, and switching back to splits after restoring
rebuilt the tree from scratch along the default axis.

The session file also carried no last_used_layout, so _last_used_layout was None
after a restore and toggle_layout <current layout> silently did nothing, since it
delegates to last_used_layout() which returns early when unset. The key that
produced the stack layout no longer undid it.

Tab now keeps the layouts it has used, by name, and writes their state plus
last_used_layout into the existing set_layout_state JSON rather than adding new
session commands. Older versions of kitty ignore unknown keys in that dict but
abort on unknown commands, so nesting keeps session files readable by them.

Restoring the state of a layout that is not being made current must not reorder
the window list, since only the current layout determines window order, hence
apply_to_window_list. Splits.set_layout_state also has to accept state for a
layout whose tree is still empty, which is the case for a layout that has not
laid out any windows yet.

Fixes #10320
2026-08-05 07:53:47 -07:00
Kovid Goyal
e99f6044c5
Remove NUL from paths received via OSC7
NUL is anyway not legal in paths and it causes session files saved with
such paths to fail

We dont remove other control codes since they are actually legal in
paths.

Fixes #10321
2026-08-05 13:36:18 +05:30
Kovid Goyal
ed025b37af
fix specialisation not working 2026-08-05 08:17:05 +05:30
Kovid Goyal
d6712dc695
... 2026-08-05 08:05:40 +05:30
Kovid Goyal
dd2c59d255
autoformat 2026-08-05 07:16:05 +05:30
Kovid Goyal
81e7d4f1a7
Test to insure that custom shader compilation uses its cache 2026-08-05 05:33:00 +05:30
Kovid Goyal
ae347ec014
allow specialisation of custom shaders at link time 2026-08-05 05:32:59 +05:30
Kovid Goyal
98e2de1a98
move to using a pipeline definition file for custom shaders 2026-08-05 05:32:58 +05:30
Kovid Goyal
5431baa422
More work on custom shaders 2026-08-05 05:32:57 +05:30
Kovid Goyal
c99c4b1bdf
speedup slow ssh shell integration test by removing redundant entries from test matrix 2026-08-05 05:32:57 +05:30
Kovid Goyal
9d33c21131
... 2026-08-05 05:32:57 +05:30
Kovid Goyal
60c4f1c37c
... 2026-08-05 05:32:57 +05:30
Kovid Goyal
53f1b6fefb
Report Go tests properly 2026-08-05 05:32:57 +05:30
Kovid Goyal
39ae060d23
Run python test in parallel 2026-08-05 05:32:57 +05:30
Kovid Goyal
cbf3c50cf4
... 2026-08-05 05:32:57 +05:30
Kovid Goyal
16297903f6
test for compiling custom shader to glsl 2026-08-05 05:32:57 +05:30
Kovid Goyal
4b15314267
compile builtin shaders in dependency layers 2026-08-05 05:32:56 +05:30
Kovid Goyal
7f0b072f0d
autoformat 2026-08-05 05:32:56 +05:30
Kovid Goyal
104acf7d65
add tests for lock_with_file 2026-08-05 05:32:56 +05:30
Kovid Goyal
71e8d7496e
... 2026-08-05 05:32:55 +05:30
Kovid Goyal
5802d35198
Switch over to the slang based shaders 2026-08-05 05:32:54 +05:30
Kovid Goyal
dbe59e0667
... 2026-08-05 05:32:54 +05:30
Kovid Goyal
c4f1d1b9be
Delay load slangc 2026-08-05 05:32:54 +05:30
copilot-swe-agent[bot]
a31f9e52f2
Refactor kitty_tests: move __init__.py code to base.py, update all imports 2026-08-05 05:32:54 +05:30
Kovid Goyal
2a71ecdc89
Ensure slangc is correct in test env 2026-08-05 05:32:54 +05:30
Kovid Goyal
7cde77ef2c
Get freezing of slang on linux working 2026-08-05 05:32:50 +05:30
Kovid Goyal
879697e4c5
Move specialisations into compiler code
Allows for dynamic specialisations
2026-08-05 05:32:49 +05:30
Kovid Goyal
9261295448
Fix failing tests 2026-08-05 05:32:49 +05:30
copilot-swe-agent[bot]
a36b259d45
Fix parser to strip semicolons from module/import names; update tests 2026-08-05 05:32:49 +05:30
copilot-swe-agent[bot]
d8041066bf
Add slang parser corner case tests and implement test_slang_ordering 2026-08-05 05:32:49 +05:30
Kovid Goyal
dbfa720387
Work on generating build tree for slang files 2026-08-05 05:32:49 +05:30
Kovid Goyal
b3781f4fa1
Use the slangc binary instead trying to get the C++ extension working everywhere is too fragile 2026-08-05 05:32:48 +05:30
Kovid Goyal
c38b43b496
Add build test for loading slangc 2026-08-05 05:32:48 +05:30
Kovid Goyal
7f2d577a94
... 2026-08-05 05:32:48 +05:30
Francis Lavoie
86c5e13816
Wayland: do not ignore the scroll wheel after reversing direction
A high resolution wheel delivers one physical detent as several VALUE120
events, so pending_scroll_pixels accumulates fractions of a line and carries
the remainder to the next event. Detents do not reliably total 120 units, so
that carry is load bearing: it is what lets an undersized detent still scroll
a line.

It breaks down when the scroll direction changes, because the residual then
has the wrong sign and the first detent of the new direction is spent
cancelling it rather than scrolling. Measured on a Logitech MX Master 3 under
GNOME/Wayland, against a terminal program that had requested mouse events,
47% of detents that reversed direction scrolled nothing, against 2% of
detents continuing in the same direction.

Discard the residual when the direction changes, and leave the carry alone
otherwise, so scrolling in a single direction is unaffected.

The accumulator state also moves from Screen to OSWindow, since scroll events
are delivered to an OS Window rather than to a particular terminal window.
2026-08-02 15:47:31 -04:00
Kovid Goyal
75bd9d7979
Improve fade style for vertical tab bar 2026-08-02 21:54:56 +05:30
Kovid Goyal
70bdd4e96e
Fix quadratic algorithms in previous PR 2026-08-02 21:14:03 +05:30
Chance Zibolski
e7d8d17755 Vertical tabs: test wrapping combined with the line limit
Wrapping and tab_title_max_lines already compose, since wrapping runs before the
line limit is applied. Cover the combinations that were only checked by hand:
explicit newlines wrapped independently of each other, a wrap width wider than
the tab bar being clamped to it, and wrapped tabs packing by the lines they use
until the overflow ellipsis takes over.
2026-08-01 09:18:15 -07:00
Chance Zibolski
51ebfe4912 Vertical tabs: add tab_title_wrap to wrap long titles
A tab title too wide for the sidebar could only be truncated, which is wasteful
now that a title may use several lines. Add tab_title_wrap, accepting no (the
default, truncate as before), yes to wrap at the width of the tab bar, or a
number to wrap at that many cells.

Wrapping happens on grapheme boundaries so a line break can never land inside a
multi-codepoint grapheme, and SGR escapes are treated as zero width so colors
from tab_title_template neither consume cells nor get split in half. Wrapping is
bounded by tab_title_max_lines, and when a title needs more lines than it is
allowed the last line it gets is truncated with an ellipsis, which also makes
dropped lines visible for titles containing explicit newlines.

Only vertical tab bars are affected, since wrapping requires more than one row.
2026-08-01 09:18:15 -07:00
Chance Zibolski
4ccb98058b Vertical tabs: fill the tab background for the full width of the tab bar
Each line of a vertical tab was only painted as far as its text reached, so the
tab background ended mid row and the sidebar showed a ragged right edge. This
was already the case for single line titles, but multi-line titles make it
obvious, since the lines of one title rarely have the same length.

Paint the tab's full width before drawing the title over it, so every line a tab
occupies is filled in that tab's colors.
2026-08-01 09:18:15 -07:00
Chance Zibolski
26032a4802 Vertical tabs: support multi-line tab titles
Newlines in tab_title_template were drawn as a linefeed without a carriage
return, so each line started where the previous one ended, staircasing to the
right. Titles also collided with the tab below them after two lines, because
update_vertical assumed a fixed two line stride per tab.

Set LNM on the tab bar screen so a newline returns to the start of the next
line, measure how many lines each title actually occupies, and pack tabs at
cumulative offsets.

The blank line between tabs is preserved: one is inserted between tabs while
there is room, and dropped automatically once the tabs need the space, as
before. Previously this fell out of every tab reserving two lines, which is no
longer true now that a tab occupies only as many lines as its title needs.

The number of lines a title may use is limited by the new tab_title_max_lines
option, defaulting to 1 so existing configurations render as before. Lines
beyond the limit are dropped rather than bleeding into the next tab, and a title
is never allowed to use more lines than remain below it, since drawing past the
last line would scroll the tab bar and lose the tabs already drawn.

Only vertical tab bars are affected; horizontal tab bars share a single row.
2026-08-01 09:17:55 -07:00
Kovid Goyal
5cd6072570
Function to get memory used by processes rooted at pid 2026-07-29 13:25:51 +05:30
Tim Culverhouse
365f1a6b37
terminal: add visibility reports
Allow terminal applications to detect when their view is not observable so they can avoid unnecessary rendering work.

Implement mode 2033 and the visibility status query, and report changes from tab, pane, window, and platform occlusion state.
2026-07-28 14:25:12 -05:00
Kovid Goyal
0816716c72
Add support for DECSTR soft screen reset escape code
Some checks are pending
CI / Linux (python=3.14 cc=clang sanitize=1) (push) Waiting to run
CI / Linux (python=3.12 cc=gcc sanitize=0) (push) Waiting to run
CI / Linux (python=3.13 cc=gcc sanitize=1) (push) Waiting to run
CI / Linux package (push) Waiting to run
CI / Bundle test (macos-latest) (push) Waiting to run
CI / Bundle test (ubuntu-latest) (push) Waiting to run
CI / macOS Brew (push) Waiting to run
CI / Test ./dev.sh and benchmark (push) Waiting to run
CodeQL / CodeQL-Build (actions, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, macos-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (go, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (python, ubuntu-latest) (push) Waiting to run
Depscan / Scan dependencies for vulnerabilities (push) Waiting to run
This escape code is largely undefined. There is no specification for how
it affects alternate screen mode, overriden colors, kitty keyboard
state, paused rendering, etc. Do what I feel is sensible in these cases.

Fixes #10263
2026-07-15 09:28:51 +05:30
Jeff Quast
efeb4aead0 Fix erroneous scroll when using X/Y offsets in images
Problem
-------

In update_dest_rect() when both num_cols and num_rows are 0
(auto-computed, ``a=T``), the first block computes num_cols with
cell_x_offset, but, then the second block mismatches num_cols, causing
it to compute width_px from num_cols and adds cell_x_offset a second
time. The returned value is large enough that it often causes scrolling,
depending on size and location of the screen.

A sample visual program:

```python
import zlib, base64, time
from functools import partial
echo = partial(print, end='', flush=True)

echo('\033[H\033[J')

base = bytes([0, 128, 0, 255]) * 640 * 576
k = zlib.compress(keyframe, 3)
echo(f'\033[8;60H\033_Ga=T,i=1,q=1,f=32,s=640,v=576,o=z,N=1;{base64.b64encode(k).decode()}\033\\')
time.sleep(1)

delta = bytes([200, 0, 0, 255]) * 32 * 512
d = zlib.compress(delta, 3)
echo(f'\033[9;67H\033_Ga=T,i=100,q=1,f=32,s=32,v=512,o=z,N=1,X=9,Y=25;{base64.b64encode(d).decode()}\033\\')

time.sleep(1)
print()
```

Solution
--------

Add 'auto_cols' and 'auto_rows' to remember the original read-only
values before exercising their auto-calculated size. 'auto_rows' isn't
technically necessary given the logic branching but it describes in code
better.

Before and After video
----------------------

A video will be attached shortly, here.
2026-07-12 18:22:40 -04:00
Sinity
b2d5a36283
Garbage collect the text cache periodically so unique cell texts do not grow memory without bound
The TextCache interns every unique multi-codepoint cell text for the
lifetime of the window with no eviction, so a stream of unique texts
(for example random combining mark sequences) grows memory without
bound, several hundred MB/hour at moderate throughput.

Mirror the existing hyperlink pool garbage collection: every 8192
newly interned entries, steal the cache contents and have the Screen
remap the index in every live cell (history buffer, main and alt line
buffers, paused rendering snapshot and overlay line), re-interning
only entries still referenced by some cell. Entries whose last
reference scrolled out of the history buffer are freed.

See #10249

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-11 20:40:02 +02:00
Kovid Goyal
89781759e4
...
Some checks are pending
CI / Linux (python=3.14 cc=clang sanitize=1) (push) Waiting to run
CI / Linux (python=3.12 cc=gcc sanitize=0) (push) Waiting to run
CI / Linux (python=3.13 cc=gcc sanitize=1) (push) Waiting to run
CI / Linux package (push) Waiting to run
CI / Bundle test (macos-latest) (push) Waiting to run
CI / Bundle test (ubuntu-latest) (push) Waiting to run
CI / macOS Brew (push) Waiting to run
CI / Test ./dev.sh and benchmark (push) Waiting to run
CodeQL / CodeQL-Build (actions, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, macos-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (go, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (python, ubuntu-latest) (push) Waiting to run
Depscan / Scan dependencies for vulnerabilities (push) Waiting to run
2026-07-04 09:23:16 +05:30
Kovid Goyal
a65b4c70a7
Migrate type checker to ty
Much faster than mypy. Matches usage of ruff from same developer.
2026-07-04 09:18:00 +05:30
Kovid Goyal
9cd2c60064
Clean previous PR
Some checks are pending
CI / Linux (python=3.13 cc=clang sanitize=1) (push) Waiting to run
CI / Linux (python=3.11 cc=gcc sanitize=0) (push) Waiting to run
CI / Linux (python=3.12 cc=gcc sanitize=1) (push) Waiting to run
CI / Linux package (push) Waiting to run
CI / Bundle test (macos-latest) (push) Waiting to run
CI / Bundle test (ubuntu-latest) (push) Waiting to run
CI / macOS Brew (push) Waiting to run
CI / Test ./dev.sh and benchmark (push) Waiting to run
CodeQL / CodeQL-Build (actions, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, macos-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (go, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (python, ubuntu-latest) (push) Waiting to run
Depscan / Scan dependencies for vulnerabilities (push) Waiting to run
2026-06-29 06:17:08 +05:30