1599 Commits

Author SHA1 Message Date
Jeffrey C. Ollie
bd4d1950ce OSC: remove unused code 2025-05-29 11:37:07 -05:00
Jeffrey C. Ollie
479fa9f809 OSC: use std.SegmentedList instead of custom data structure 2025-05-29 11:37:07 -05:00
Jeffrey C. Ollie
397a8b13e0 OSC: more tests 2025-05-29 11:37:07 -05:00
Jeffrey C. Ollie
1288296fdc OSC: add a datastructure to prevent some (most?) allocations 2025-05-29 11:37:06 -05:00
Jeffrey C. Ollie
5bb7492955 OSC: convert OSC 110, 111, and 112 and add more tests 2025-05-29 11:37:06 -05:00
Jeffrey C. Ollie
5ec1c15ecf OSC: add more tests 2025-05-29 11:37:06 -05:00
Jeffrey C. Ollie
9c1abf487e OSC: start adding structure to allow multiple color operations per OSC 2025-05-29 11:37:06 -05:00
Qwerasd
6f7e9d5bea code style: use @splat where possible
As of Zig 0.14.0, `@splat` can be used for array types, which eliminates
a lot of redundant syntax and makes things generally cleaner.

I've explicitly avoided applying this change in the renderer files for
now since it would just create rebasing conflicts in my renderer rework
branch which I'll be PR-ing pretty soon.
2025-05-27 21:55:28 -06:00
Jonatan Borkowski
21c97aa9d6 add support for buffer switching with CSI ? 47 h/l 2025-05-27 11:48:14 -07:00
Qwerasd
ecdac8c8c1 terminal: rework selection logic in core surface
This logic is cleaner and produces better behavior when selecting by
dragging the mouse outside the bounds of the surface, previously when
doing this on the left side of the surface selections would include the
first cell of the next row, this is no longer the case.

This introduces methods on PageList.Pin which move a pin left or right
while wrapping to the prev/next row, or clamping to the ends of the row.
These need unit tests.
2025-05-27 09:38:36 -07:00
Qwerasd
1ce6544945 Wrap comment at 80 cols 2025-05-27 09:38:36 -07:00
Qwerasd
2384bd69cc style: use decl literals
This commit changes a LOT of areas of the code to use decl literals
instead of redundantly referring to the type.

These changes were mostly driven by some regex searches and then manual
adjustment on a case-by-case basis.

I almost certainly missed quite a few places where decl literals could
be used, but this is a good first step in converting things, and other
instances can be addressed when they're discovered.

I tested GLFW+Metal and building the framework on macOS and tested a GTK
build on Linux, so I'm 99% sure I didn't introduce any syntax errors or
other problems with this. (fingers crossed)
2025-05-26 21:50:14 -06:00
Qwerasd
25a708ed98 terminal/style: compare packed styles directly, no cast needed
Woohoo, Zig 0.14!
2025-05-25 22:53:50 -06:00
Mitchell Hashimoto
2d29fe0494 bench: add --mode=gen-osc to generate synthetic OSC sequences (#7359)
cc @qwerasd205 

This commit adds a few new mode flags to the `bench-stream` program to
generator synthetic OSC sequences. The new modes are `gen-osc`,
`gen-osc-valid`, and `gen-osc-invalid`. The `gen-osc` mode generates
equal parts valid and invalid OSC sequences, while the suffixed variants
are for generating only valid or invalid sequences, respectively.

This commit also fixes our build system to actually be able to build the
benchmarks. It turns out we were just rebuilding the main Ghostty binary
for `-Demit-bench`. And, our benchmarks didn't run under Zig 0.14, which
is now fixed.

An important new design I'm working towards in this commit is to split
out synthetic data generation to a dedicated package in
`src/bench/synth` although I'm tempted to move it to `src/synth` since
it may be useful outside of benchmarks.

The synth package is a work-in-progress, but it contains a hint of
what's to come. I ultimately want to able to generate all kinds of
synthetic data with a lot of knobs to control dimensionality (e.g. in
the case of OSC sequences: valid/invalid, length, operation types,
etc.).
2025-05-15 20:19:37 -07:00
Qwerasd
ed207514e9 typo 2025-05-15 11:59:17 -06:00
Qwerasd
709b0214a0 fix(renderer): Don't force images to grid/cell sizes
This problem was introduced by f091a69 (PR #6675).

I've gone ahead and overhauled the placement positioning logic as well;
it was doing a lot of expensive calls before, I've significantly reduced
that.

Clipping partially off-screen images is now handled entirely by the
renderer, rather than while preparing the placement, and as such the
grid position passed to the image shader is now signed.
2025-05-15 11:41:12 -06:00
Mitchell Hashimoto
a74e352726 bench: add --mode=gen-osc to generate synthetic OSC sequences
This commit adds a few new mode flags to the `bench-stream` program
to generator synthetic OSC sequences. The new modes are `gen-osc`,
`gen-osc-valid`, and `gen-osc-invalid`. The `gen-osc` mode generates
equal parts valid and invalid OSC sequences, while the suffixed variants
are for generating only valid or invalid sequences, respectively.

This commit also fixes our build system to actually be able to build the
benchmarks. It turns out we were just rebuilding the main Ghostty binary
for `-Demit-bench`. And, our benchmarks didn't run under Zig 0.14, which
is now fixed.

An important new design I'm working towards in this commit is to split
out synthetic data generation to a dedicated package in
`src/bench/synth` although I'm tempted to move it to `src/synth` since
it may be useful outside of benchmarks.

The synth package is a work-in-progress, but it contains a hint of
what's to come. I ultimately want to able to generate all kinds of
synthetic data with a lot of knobs to control dimensionality (e.g. in
the case of OSC sequences: valid/invalid, length, operation types,
etc.).
2025-05-14 12:26:31 -07:00
Mitchell Hashimoto
ecda5ec327 macos: do not send UTF-8 PUA codepoints to key events
Fixes #7337

AppKit encodes functional keys as PUA codepoints. We don't want to send
that down as valid text encoding for a key event because KKP uses that
in particular to change the encoding with associated text.

I think there may be a more specific solution to this by only doing this
within the KKP encoding part of KeyEncoder but that was filled with edge
cases and I didn't want to risk breaking anything else.
2025-05-12 11:42:05 -07:00
Tim Culverhouse
2c1ade763f terminal(dcs): convert all xtgettcap queries to upper
XTGETTCAP queries are a semicolon-delimited list of hex encoded terminfo
capability names. Ghostty encodes a map using upper case hex encodings,
meaning when an application uses a lower case encoding the capability is
not found. To fix, we convert the entire list we receive in the query to
upper case prior to processing further.

Fixes: #7229
2025-04-29 18:42:16 -05:00
Mitchell Hashimoto
da6b478fbe terminal: clear correct row on index operation in certain edge cases
Fixes #7066

This fixes an issue where under certain conditions (expanded below), we
would not clear the correct row, leading to the screen having duplicate
data.

This was triggered by a page state of the following:

```
      +----------+ = PAGE 0
  ... :          :
 4305 |1ABCD00000|
 4306 |2EFGH00000|
      :^         : = PIN 0
     +-------------+ ACTIVE
 4307 |3IJKL00000| | 0
      +----------+ :
      +----------+ : = PAGE 1
    0 |          | | 1
    1 |          | | 2
      +----------+ :
     +-------------+
```

Namely, the cursor had to NOT be on the last row of the first page,
but somewhere on the first page. Then, when an `index` (LF) operation
was performed the result would look like this:

```
      +----------+ = PAGE 0
  ... :          :
 4305 |1ABCD00000|
 4306 |2EFGH00000|
     +-------------+ ACTIVE
 4307 |3IJKL00000| | 0
      :^         : : = PIN 0
      +----------+ :
      +----------+ : = PAGE 1
    0 |3IJKL00000| | 1
    1 |          | | 2
      +----------+ :
     +-------------+
```

The `3IJKL` line was duplicated. What was happening here is that we
performed the index operation correctly but failed to clear the cursor
line as expected.

This is because we were always clearing the first row in the page
instead of the row of the cursor.

Test added.
2025-04-14 15:54:00 -07:00
Qwerasd
b64f49a0d7 fix(kittygfx): accept commands with no control data
This sort of command is treated as valid by Kitty so we should too. In
fact, it occurs with the example `send-png` script provided in the docs
for the protocol.
2025-04-07 13:31:51 -06:00
Mitchell Hashimoto
4d0bf303c6 ci: zig fmt check
This adds a CI test to ensure that all Zig files are properly formatted.
This avoids unrelated diff noise in future PRs.
2025-03-18 13:58:49 -07:00
Mitchell Hashimoto
1f6b1d75eb Fix aspect ratio when rendering images with kitty protocol (#6675)
Fixes https://github.com/ghostty-org/ghostty/issues/6673

<img width="914" alt="image"
src="https://github.com/user-attachments/assets/010a1304-0d46-46ec-9a82-87a8d8fbea1b"
/>
2025-03-13 09:50:19 -07:00
Mitchell Hashimoto
43467690f3 test 2025-03-12 10:04:17 -07:00
Mitchell Hashimoto
0f4d2bb237 Lots of 0.14 changes 2025-03-12 09:55:52 -07:00
Bryan Lee
2f814b37e8 Add unit tests for kitty image aspect ratio calculation 2025-03-12 22:44:17 +08:00
Bryan Lee
f091a69790 Fix aspect ratio when rendering images with kitty protocol 2025-03-12 15:06:06 +08:00
Mitchell Hashimoto
7e2286eb8c Zig 0.14 2025-03-11 14:39:04 -07:00
Jon Parise
b0b2de01f5 terminal: remove redundant assertIntegrity from clearPrompt
clearCells() always asserts its page's integrity after finishing its
work (via a `defer`). We don't need to re-assert the page's integrity
immediately thereafter.
2025-03-08 16:36:14 -05:00
Jeffrey C. Ollie
f4f36a9a98 kitty: delete stray log line 2025-02-24 11:05:37 -06:00
Mitchell Hashimoto
71ae51b4b3 kitty images: add delete by range operations (#5957)
Fixes #5937

Implement [deleting Kitty image
ranges](https://sw.kovidgoyal.net/kitty/graphics-protocol/#deleting-images).
2025-02-24 07:14:11 -08:00
Jeffrey C. Ollie
995959dce4 kitty images: add delete by range operations
Fixes #5937

Implement [deleting Kitty image ranges](https://sw.kovidgoyal.net/kitty/graphics-protocol/#deleting-images).
2025-02-23 12:57:24 -06:00
Mitchell Hashimoto
22c506b03e terminal: increase CSI max params to 24 to accept Kakoune sequence
See #5930

Kakoune sends a real SGR sequence with 17 parameters. Our previous max
was 16 so we through away the entire sequence. This commit increases the
max rather than fundamentally addressing limitations.

Practically, it took us this long to witness a real world sequence that
exceeded our previous limit. We may need to revisit this in the future,
but this is an easy fix for now.

In the future, as the comment states in this diff, we should probably
look into a rare slow path where we heap allocate to accept up to some
larger size (but still would need a cap to avoid DoS). For now,
increasing to 24 slightly increases our memory usage but shouldn't
result in any real world issues.
2025-02-22 20:43:44 -08:00
Mitchell Hashimoto
7dac9e02b3 terminal: reflow the saved cursor if we have one
Fixes #5718

When a terminal is resized with text reflow (i.e. soft-wrapped text), the cursor
is generally reflowed with it.

For example, imagine a terminal window 5-columns wide and you type the
following without pressing enter. The cursor is on the X.

```
OOOOO
OOX
```

If you resize the window now to 8 or more columns, this happens, as expected:

```
OOOOOOOX
```

As expected, the cursor remains on the "X". This behaves like any other text
input...

Terminals also provide an escape sequence to
[save the cursor (ESC 7 aka DECSC)](https://ghostty.org/docs/vt/esc/decsc).
This includes, amongst other things, the cursor position. The cursor can be
restored with [DECRC](https://ghostty.org/docs/vt/esc/decrc).

The behavior of the position of the _saved cursor_ in the context of text
reflow is unspecified and varies wildly between terminals Ghostty does this
right now (as do many other terminals):

```
OOOOOOOO
   X
```

This commit changes the behavior so that we reflow the saved cursor.
2025-02-12 10:34:31 -08:00
Qwerasd
b624cfe262 fix(terminal): avoid Screen.reset causing use of undefined
Fully reset the kitty image storage instead of using the delete handler,
previously this caused a memory corruption / likely segfault due to use
of undefined, since the delete handler tries to clear the tracked pins
for placements, which it gets from the terminal, for which `undefined`
was passed in before.
2025-02-11 14:20:47 -05:00
Qwerasd
dd8c795ec6 test(terminal/screen): cursorSetHyperlink OOM handling edge case
Tests handling introduced in 09c76d95 which ensures sufficient space for
the cursor hyperlink uri in the string alloc when adjusting capacity.
2025-02-10 15:52:40 -05:00
Qwerasd
a1b682d0da fix(terminal): properly lookup hyperlinks when cloning rows across pages
Before this we were doing bad things with the memory, looking at
`PageEntry`s for links not actually in the page we were reading the
strings from.
2025-02-10 15:52:40 -05:00
Qwerasd
e540a79032 test(terminal/screen): OOM handling in adjustCapacity
Adds tests for the adjustCapacity changes from 09c76d95

Fixes a small oversight in that change as well (resetting cursor style).
2025-02-10 14:21:42 -05:00
Qwerasd
1c524238c8 test(terminal/osc): fix command longer than buffer test
Ensure that the state is invalidated properly, this previously wasn't
the case but was fixed in 03fd9a97
2025-02-10 13:27:26 -05:00
Qwerasd
03fd9a970b fix(terminal): properly invalidate over-sized OSCs
The `self.complete = false` here is important so we don't accidentally
dispatch, for example, a hyperlink command with an empty URI.
2025-02-10 11:49:05 -05:00
Qwerasd
09c76d95c7 fix(terminal): handle errors in Screen.adjustCapacity
Previously assumed adjusted capacities would always fit the cursor style
and hyperlink, this is not necessarily the case and led to memory
corruption in scenarios with large hyperlinks.
2025-02-10 00:17:08 -05:00
Lee Marlow
71d0481da8 Remove if check that was left in after change to exhaustive switch
This came out of cmd+triple-click fix in PR #5373
2025-01-29 11:38:35 -07:00
Daniel Patterson
4b8010a6f4 Change ifs to exhaustive switches 2025-01-26 15:22:23 +00:00
Daniel Patterson
645b4b0031 Fix cmd+triple click not selecting full output 2025-01-25 23:37:46 +00:00
Qwerasd
5cf7575967 fix(PageList): when cloning, explicitly set cols
Otherwise pages may have the wrong width if they were resized down with
a fast path that just chanes the size without adjusting capacity at all.
2025-01-13 13:50:29 -08:00
Mitchell Hashimoto
7aed08be40 terminal: keep track of colon vs semicolon state in CSI params
Fixes #5022

The CSI SGR sequence (CSI m) is unique in that its the only CSI sequence
that allows colons as delimiters between some parameters, and the colon
vs. semicolon changes the semantics of the parameters.

Previously, Ghostty assumed that an SGR sequence was either all colons
or all semicolons, and would change its behavior based on the first
delimiter it encountered.

This is incorrect. It is perfectly valid for an SGR sequence to have
both colons and semicolons as delimiters. For example, Kakoune sends
the following:

    ;4:3;38;2;175;175;215;58:2::190:80:70m

This is equivalent to:

  - unset (0)
  - curly underline (4:3)
  - foreground color (38;2;175;175;215)
  - underline color (58:2::190:80:70)

This commit changes the behavior of Ghostty to track the delimiter per
parameter, rather than per sequence. It also updates the SGR parser to
be more robust and handle the various edge cases that can occur. Tests
were added for the new cases.
2025-01-13 12:47:07 -08:00
Damien Mehala
fc99c99b74 code review 2025-01-11 22:19:42 +01:00
Damien Mehala
95fc1d64c8 parse ConEmu OSC9;5 2025-01-11 17:24:13 +01:00
Mitchell Hashimoto
7ae94e145d terminal: ConEmu OSC9 parsing is more robust and correct
Related to #4485

This commit matches ConEmu's parsing logic[^1] more faithfully. For any
substate that requires a progress, ConEmu parses so long as there is a
number and then just ignores the rest.

For substates that don't require a progress, ConEmu literally ignores
everything after the state.

Tests cover both.

[^1]: 740b09c363/src/ConEmuCD/ConAnsiImpl.cpp (L2264)
2025-01-06 15:41:44 -08:00
Damien Mehala
ead241f38c Merge branch 'main' into dmehala/conemu-osc9 2025-01-05 21:58:45 +01:00