Commit Graph

529 Commits (7cc8ea7efb2a8648d3931e162d53c02f36222c4e)

Author SHA1 Message Date
Mitchell Hashimoto 2452026ff3
terminal: kitty limits only if kitty graphics being built 2025-11-14 15:53:00 -08:00
Mitchell Hashimoto 580f9f057b
convert t.screen to t.screens.active 2025-11-14 15:40:31 -08:00
Mitchell Hashimoto 3aff5f0aff
ScreenSet 2025-11-14 15:08:10 -08:00
Mitchell Hashimoto 368f4f565a
terminal: Screen opts is a structure 2025-11-14 14:10:37 -08:00
Mitchell Hashimoto 3d58dc51c9
terminal: keypad variation sequences should respect VS16
This fixes the VS16 issues found in this test:
https://ucs-detect.readthedocs.io/sw_results/ghostty.html#ghostty
This is also a more robust way to handle VS15/16 in general. 

This commit also changes our propeties to be a packed struct which
reduces its size from 4 bytes to 1 and likewise drops our unicode table
size 4x.
2025-11-06 07:05:57 -08:00
Mitchell Hashimoto 631c58a302
unicode: update uucode, force emoji modifiers width 2 as standalone
This updates uucode. As part of this, the wcwidth implementation was
updated (in uucode) to make emoji modifiers width ZERO. But if they're
standalone, we want them as width 2.

So this also contains a change to force them as width 2 for our width
calculation. This only matters for standalone emoji modifiers, because
when they form a valid grapheme we don't use this width calculation.
2025-11-05 14:57:48 -08:00
Mitchell Hashimoto cabca0aca8
terminal: unify palette functionality into shared type DynamicPalette 2025-10-30 09:15:43 -07:00
Mitchell Hashimoto 580262c96f
terminal: add ReadonlyStream that updates terminal state (#9346)
This adds a new stream handler implementation that updates terminal
state in reaction to VT sequences, but doesn't perform any of the
actions that would require responses (e.g. queries).

This is exposed in two ways: first, as a standalone `ReadonlyStream` and
`ReadonlyHandler` type that contains all the implementation. Second, as
a convenience func on `Terminal` as `vtStream` and `vtHandler` which
return their respective types preconfigured to update the calling
terminal state.

This dramatically simplifies libghostty-vt usage from Zig (and will
eventually be exposed to C, too) since a Terminal on its own is ready to
go as a full VT parser and state machine without needing to build any
custom types!

There's a second big bonus here which is that our `stream_readonly.zig`
tests are true end-to-end tests for raw bytes to terminal state. This
will let us test a wider variety of situations more broadly. To start,
there are only a handful of tests implemented here.

**AI disclosure:** Amp wrote basically this whole thing, but I reviewed
it. https://ampcode.com/threads/T-3490efd2-1137-4112-96f6-4bf8a0141ff5
2025-10-25 14:52:33 -07:00
Mitchell Hashimoto 5ba451d073
terminal: configureCharset 2025-10-24 11:27:48 -07:00
Mitchell Hashimoto d59d754e29
Zig 0.15: zig build GTK exe 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 3770f97608
terminal: Zig 0.15, lib-vt and test-lib-vt work 2025-10-03 07:10:43 -07:00
Jacob Sandlund b01770c21c Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-23 09:36:41 -04:00
Mitchell Hashimoto 811f9f05d0
terminal: support disabling kitty graphics protocol 2025-09-21 19:40:00 -07:00
Mitchell Hashimoto bf1278deff
unicode: isolate properties, tables, and ziglyph into separate files
This makes it cleaner to add new sources of table generation and also
avoids inadvertently depending on different modules (despite Zig's lazy
analysis). 

This also fixes up terminal to only use our look up tables which avoids
bringing ziglyph in for the terminal module.
2025-09-20 15:00:55 -07:00
Jacob Sandlund 69594119c3 fix up diff from benchmarks, and add tests against ziglyph 2025-09-18 11:46:05 -04:00
Jacob Sandlund 2a3629fe21 Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-08 08:31:34 -04:00
Qwerasd fdd22ec786 fix(terminal): move cursor left if VS15 makes cell narrow
Without this change, a phantom space appears after any character with
default emoji presentation that is converted to text with VS15. The only
other terminal I know of that respects variation selectors is Kitty, and
it walks the cursor back, which feels like the best choice, since that
way the behavior is observable (no way to know if the terminal supports
variation selectors otherwise without hard-coding that info per term)
and "dumb" programs like `cat` will output things correctly, and not
gain a phantom space after any VS15'd emoji.
2025-09-06 13:46:14 -07:00
Jacob Sandlund 2af08bdbe3 trying a bunch of things to get performance to match 2025-09-06 10:42:02 -04:00
Jacob Sandlund 90832d89b3 Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-08-21 21:13:40 -04:00
Mitchell Hashimoto a57afd41ac
terminal: fix undefined memory access in unit test 2025-08-20 20:54:29 -07:00
Jacob Sandlund e84d8535f5 removing all ziglyph imports (aside from unicode/grapheme.zig) 2025-08-17 21:24:27 -04:00
moni-dz f73c90bf5d surface: add timer-based scrolling during selection 2025-06-30 09:17:20 -07:00
Mitchell Hashimoto c5e5d61438
terminal: bring alt screen behaviors much closer in line with xterm
This brings the behavior of mode 47, 1047, and 1049 much closer to
xterm's behavior. I found that our prior implementation had many
deficiencies.

For example, we weren't properly copying the cursor state back to the
primary screen from the alternate screen for modes 47 and 1047. And we
weren't saving/restoring cursor state unconditionally for mode 1049 even
if we were already in the alternate screen.

These are weird, edgy behaviors that I don't think anyone expected
(evidence by there being no bug reports about them), but they are bugs
nontheless.

Many tests added.
2025-05-29 15:43:27 -07: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
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
Mitchell Hashimoto 0f4d2bb237
Lots of 0.14 changes 2025-03-12 09:55:52 -07:00
Mitchell Hashimoto 7e2286eb8c
Zig 0.14 2025-03-11 14:39:04 -07: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
Mitchell Hashimoto e5e090deaf
test: big perf win by pausing integ checks while growing pages (#2956)
In multiple tests we create 1 or more pages by growing them 1 row at a
time, which results in an integrity check of the page for each row grown
which is just... horrible. By simply pausing integrity checks while
growing these pages (since growing them is not the point of the test) we
MASSIVELY speed up all of these tests.

Also reduced grapheme bytes during testing and made the Terminal "glitch
text" test actually assert what it intends to achieve, rather than just
blindly assuming 100 copies of the text will be the right amount -- this
lets us stop a lot earlier, making it take practically no time.
2024-12-12 16:12:22 -08:00
Qwerasd 10abeba414 test: big perf win by pausing integ checks while growing pages
In multiple tests we create 1 or more pages by growing them 1 row at a
time, which results in an integrity check of the page for each row grown
which is just... horrible. By simply pausing integrity checks while
growing these pages (since growing them is not the point of the test) we
MASSIVELY speed up all of these tests.

Also reduced grapheme bytes during testing and made the Terminal "glitch
text" test actually assert what it intends to achieve, rather than just
blindly assuming 100 copies of the text will be the right amount -- this
lets us stop a lot earlier, making it take practically no time.
2024-12-12 16:58:48 -05:00
Mitchell Hashimoto fd1201323e
unicode: emoji modifier requires emoji modifier base preceding to not break
Fixes #2941

This fixes the rendering of the text below. For those that can't see it,
it is the following in UTF-32: `0x22 0x1F3FF 0x22`.

```
"🏿"
```

`0x1F3FF` is the Fitzpatrick modifier for dark skin tone. It has the
Unicode property `Emoji_Modifier`. Emoji modifiers are defined in UTS
#51 and are only valid based on ED-13:

```
emoji_modifier_sequence := emoji_modifier_base emoji_modifier
emoji_modifier_base := \p{Emoji_Modifier_Base}
emoji_modifier := \p{Emoji_Modifier}
```

Additional quote from UTS #51:

> To have an effect on an emoji, an emoji modifier must immediately follow
> that base emoji character. Emoji presentation selectors are neither needed
> nor recommended for emoji characters when they are followed by emoji
> modifiers, and should not be used in newly generated emoji modifier
> sequences; the emoji modifier automatically implies the emoji presentation
> style.

Our precomputed grapheme break table was mistakingly not following this
rule. This commit fixes that by adding a check for that every
`Emoji_Modifier` character must be preceded by an `Emoji_Modifier_Base`.
This only has a cost during compilation (table generation). The runtime
cost is identical; the table size didn't increase since we had leftover
bits we could use.
2024-12-12 12:53:08 -08:00
Mitchell Hashimoto 212bd3d5fb
terminal: fullReset uses the new screen reset methods 2024-12-02 17:44:07 -05:00
Mitchell Hashimoto d57d1d2395
terminal: failing tracked pin test on fullReset 2024-12-02 09:39:43 -05:00
Mitchell Hashimoto 853ba9e3c7
terminal: reset should preserve desired default mode values
Fixes #2857

Some terminal modes always reset, but there are others that should be
conditional based on how the terminal's default state is configured.
Primarily from #2857 is the grapheme clustering mode (mode 2027) which
was always resetting to false but should be conditional based on the
the `grapheme-width-method` configuration.
2024-11-29 14:42:01 -08:00
Mitchell Hashimoto e20b27de84
terminal: eraseChars was checking wide char split boundary on wrong cell
Fixes #2817

The test is pretty explanatory. I also renamed `end` to `count` since I
think this poor naming was the reason for the bug. In `eraseChars`, the
`count` (nee `end`) is the number of cells to erase, not the index of
the last cell to erase.
2024-11-26 14:29:58 -08:00
Mitchell Hashimoto aed51fd0b0
terminal: PageList rename "page" to "node" everywhere
This is more correct: a pagelist is a linked list of nodes, not pages.
The nodes themselves contain pages but we were previously calling the
nodes "pages" which was confusing, especially as I plan some future
changes to the way pages are stored.
2024-11-07 13:44:39 -08:00
Rick Calixte e0c5bdc53b Terminal: Reinitialize screens on scrollback reset
When resetting the terminal screen, the memory buffer allocated for the
scrollback is now cleared by reinitializing the screen and falling back to the
current method if any of the attempts to reinitialize fail.

Closes #2464
2024-10-30 17:21:38 -04:00
Mitchell Hashimoto 39627e3221
termio: set pw input state on terminal and wake up renderer 2024-09-18 10:47:26 -07:00
Qwerasd 9669332134 terminal: cursorResetWrap should not reset wrap_continuation 2024-09-06 17:57:14 -04:00
Mitchell Hashimoto 8f47581e22
terminal: add test for wide character on right margin boundary 2024-09-06 14:28:04 -07:00
Qwerasd 057f218c9e perf(terminal): specialize `splitCellBoundary` to cursor row
+ do some abstraction leakage in `cursorResetWrap`, since they're both
used in hot functions for TUI stuff so performance is important.
2024-09-06 13:26:57 -04:00
Qwerasd 8d12044f1d Terminal: fix ECH & DCH wide char boundary cond. behavior 2024-09-06 12:35:11 -04:00
Qwerasd 04271c6a07 test(Terminal): test ECH wide char boundary conditions 2024-09-06 12:35:11 -04:00
Qwerasd 1692a82b33 test(Terminal): test DCH wide char boundary conditions 2024-09-06 12:35:11 -04:00
Mitchell Hashimoto a6031efa04
terminal: DECALN must use clearRows to clear protected memory 2024-09-05 14:35:12 -07:00
Gregory Anders df06697899 termio: send initial focus reports
When the focus reporting mode (1004) is enabled, send the current focus
state. This allows applications to track their own focus state without
first having to wait for a focus event (or query
it by sending a DECSET followed by a DECRST).

Ghostty's focus state is stored only in the renderer, where the termio
thread cannot access it. We duplicate the focus state tracking in the
Terminal struct with the addition of a new (1-bit) flag. We duplicate
the state because the renderer uses the focus state for its own purposes
(in particular, the Metal renderer uses the focus state to manage
its DisplayLink), and synchronizing access to the shared terminal state
is more cumbersome than simply tracking the focus state in the renderer
in addition to the terminal.
2024-09-04 22:13:52 -05:00
Mitchell Hashimoto 6aab430caf
terminal: disable slow safety tests in releasesafe 2024-08-31 21:14:12 -07:00
Mitchell Hashimoto 9d08ed32ee
terminal: make error sets more explicit, capture explicit errors 2024-08-31 10:31:38 -07:00
Qwerasd 3807ee34c1 terminal: handle clonePartialRowFrom errors in insert/deleteLines
Handle `clonePartialRowFrom` errors in `insertLines` and `deleteLines`
by adjusting page capacity. To do this, I've rewritten both functions
with a new way of iterating rows by moving a tracked pin up/down.

Benchmarks seem to indicate that this has no effect on performance.
2024-08-30 13:45:18 -04:00
Mitchell Hashimoto 6a2d57edfd
terminal: cursorCopy has option to not copy hyperlink 2024-08-28 09:41:57 -07:00