Commit Graph

942 Commits

Author SHA1 Message Date
Leah Amelia Chen
c6e7e9e4e2 config: add drag-handle 2026-08-09 16:09:00 +08:00
Mitchell Hashimoto
77537c8065 macos: handled untrusted OSC8 hyperlinks more carefully
OSC8 hyperlinks previously executed directly via the NSWorkspace opener
so a malicious application can just do whatever it wanted and trick the
user into opening something through Launch Services.

This PR notifies apprt of OSC8 hyperlinks so they can be handled
specially. In this PR, I added macOS-specific handling of OSC8 through a
variety of improvements:

  - Preview text is sanitized, so invisible Unicode characters now show.
  - Questionable-looking URLs require confirmation to open, but a user
    can confirm to open.
  - Very questionable or definitely unsafe URLs are blocked with an 
    alert that only allows the user to copy the link. The alert also
    notifies the user why.
2026-08-05 10:22:28 -07:00
Mitchell Hashimoto
a00d155e9c config: limit command translations to GTK
Fixes #13614

Only translate the shared default commands when building the GTK runtime. 
macOS now use the source strings until we do broader localization.
2026-08-04 15:23:09 -07:00
Mitchell Hashimoto
363e6e6b42 i18n: translation support for command palete (#11641)
Most obvious next step in translating Ghostty is the command palette.
Added support for i18n.N_ (https://docs.gtk.org/glib/i18n.html#macros).
Made a Latvian translation for the command palette to test. Codex did
bulk of the translations but I verified them.
2026-08-04 06:43:38 -07:00
Lauri Tirkkonen
85083d23cd config: clarify cursor-click-to-move's relation to shell-integration
the original wording is a bit confusing; I thought cursor-click-to-move
required shell-integration to be enabled, and was confused when the
mouse was still moving my cursor in fish even with
shell-integration=none.
2026-08-04 20:59:52 +09:00
Ēriks Remess
df23bef0e9 i18n: translation support for command palete and Latvian translation for it 2026-08-04 11:04:29 +03:00
Chris Marchesi
15c50c1db1 crash: do not use global state
This removes use of global state from the crash reporting functionality
(everything in src/crash).

This particularly ensures that there are no races on the system
environment during the execution of the initialization thread that would
possibly cause crashes, particularly in any (albeit unsupported) 3rd
party integrations of libghostty-internal.

Ultimately, this pushes any coupling of I/O and environment to places
that would more correctly interface with global state, such as the
same-thread global.init, and the crash report CLI.

Note that similar de-coupling actions have been taken on XDG and home
directory functionality, pushing their coupling points up the stack in a
similar way.
2026-08-02 20:24:30 -07:00
Lukas
a7cfa6fc23 config: update scrollbar doc per current implementation 2026-08-02 14:45:55 +02:00
Mitchell Hashimoto
74f45b3219 config: update info about global keybinds on Linux (#13492) 2026-07-28 06:10:42 -07:00
Leah Amelia Chen
d71695550d config: update info about global keybinds on Linux 2026-07-28 13:26:08 +08:00
Mitchell Hashimoto
1092204df1 config: support unlimited scrollback limits 2026-07-26 20:13:45 -07:00
Mitchell Hashimoto
65c48213b6 config: expose scrollback line limit 2026-07-26 20:13:45 -07:00
Chris Marchesi
e8525c0fd9 Update to Zig 0.16.0
This commit represents the majority of the work necessary to upgrade
Ghostty to use Zig 0.16.0.

Key parts:

* In addition to its previous responsibilities, the global state now
  houses state for global I/O implementations and the process
  environment. It is now also utilized in the main application along
  with the C library. Where necessary, global state is isolated from key
  parts of the implementation (e.g., in libghostty subsystems), and it's
  expected that this list will grow.

* We currently manage our own C translation layer where necessary. In
  these cases, cImport has been removed in favor of the new external
  translate-c package. Due to fixes that have needed be made to properly
  translate the dependencies that were swapped out, as mentioned, we
  have had to backport fixes from the current translate-c package (and
  the upstream Arocc dependency). We will host this ourselves until Zig
  0.17.0 is released with these fixes.

* Where necessary (only a small number of cases), some stdlib code from
  0.15.2 (and even from 0.17.0) has been taken, adopted, and vendored in
  lib/compat.

Co-authored-by: Leah Amelia Chen <hi@pluie.me>
2026-07-21 12:35:05 -07:00
Leah Amelia Chen
2da02f4d28 config: update background-blur to reflect growing adoption
`ext-background-effect-v1` is finally seeing major adoption throughout
KWin, Mutter, cosmic-comp, Niri, etc. and we should update our comments
on that.
2026-07-20 00:34:56 +08:00
Mitchell Hashimoto
0fb89f4ffe terminal: configure scrollback compression
Idle compression was always enabled on supported renderer-backed
surfaces and the default logical scrollback limit remained sized for
fully resident history.

Add a default-on scrollback-compression option and make renderer
scheduling honor it across config reloads. Existing compressed pages
remain encoded when the option is disabled, while reenabling it starts a
fresh idle pass.

Raise the default logical scrollback limit from 10 MB to 50 MB and
document typical physical-memory savings, content-dependent behavior,
and retained virtual address usage.
2026-07-09 09:47:13 -07:00
Mitchell Hashimoto
95685afd26 terminal: compress offscreen scrollback history
Compression previously stopped whenever the viewport left the active
area, leaving all scrollback resident while a user viewed history.

Traverse complete historical pages through a metadata-only iterator
which skips the contiguous visible range. Restart incremental traversal
after every viewport movement so pages become eligible once they leave
view, while visible pages remain resident for immediate redraw.

Add a PageList-only drain mode for tests and benchmarks, and update
scrollback documentation to describe the offscreen eligibility rule.
2026-07-09 09:47:13 -07:00
Mitchell Hashimoto
461562ca4f terminal: enable idle scrollback compression
Scrollback compression was available only through explicit PageList
calls, so normal renderer-backed surfaces never reclaimed cold history.

Debounce renderer wakeups with a one-shot timer and run bounded
compression steps only when the terminal lock is immediately available.
Timer state is isolated in the renderer and becomes idle once PageList
reports that the pass is complete.

Keep inspector reads representation-preserving by decoding compressed
pages into temporary copies. Update the scrollback configuration and
benchmark documentation to describe the production behavior and its
memory accounting.
2026-07-09 09:47:13 -07:00
Mitchell Hashimoto
2970e9a2a8 lib-vt: many more color utility APIs
Embedders that render theme editors, palette pickers, or custom
settings UI need to use the same color semantics as Ghostty.

This moves the shared parsing paths into terminal/color and exposes them
through libghostty-vt. Config color and palette parsing now delegate to
the same helpers, so CLI/config behavior and the C ABI stay in lockstep.

From C:

    GhosttyColorRgb rgb;
    ghostty_color_parse("ForestGreen", 11, &rgb);

    uint8_t index;
    ghostty_color_parse_palette_entry(
        "0x10=#282c34", 12, &index, &rgb);

    const GhosttyColorX11Entry* names =
        ghostty_color_x11_names();

The exported color API is:

    ghostty_color_parse
    ghostty_color_parse_x11
    ghostty_color_parse_palette_entry
    ghostty_color_palette_default
    ghostty_color_palette_generate
    ghostty_color_luminance
    ghostty_color_perceived_luminance
    ghostty_color_contrast
    ghostty_color_x11_names
    ghostty_color_x11_name_count

The X11 name table is parsed once at comptime into null-terminated
entries in rgb.txt order. The existing case-insensitive map keeps the
same behavior for RGB.parse and +list-colors, while bindings can walk a
static table without allocations.
2026-07-05 13:11:11 -07:00
Jeffrey C. Ollie
e5b65a2ce3 config: add gtk-horizontal-tab-scroll option (#12659)
I've implemented a GTK toggle (gtk-horizontal-tab-scroll) for the
2-finger tab swiping introduced in #10575.

This resolves the issue presented in #11566. Simply put, this allows
users to decide whether or not they want to use horizontal tab scrolling
or just have the events passed through. Passing through the horizontal
scroll events allows programs like Neovim to use them for horizontal
scrolling.

This PR was largely generated by Claude Code and fully reviewed/refined
by me.
2026-06-27 01:58:13 -05:00
masterflitzer
a181c386ca config: fix missing space in docs
fixes #12873

comment/docs only change:
switched space and tab in default value of `selection-word-chars`
so there is no space at the value boundary
needed because markdown trims spaces at the beginning & end
of a code snippet
2026-05-31 18:23:29 +02:00
Mitchell Hashimoto
cc48312c08 libghostty: selection word/line/output/all helpers 2026-05-24 13:42:20 -07:00
Jeffrey C. Ollie
b5f5ca0789 Add "available since" 2026-05-17 21:12:51 -05:00
Lukas
13ca032b1d config: clear command-palette-entry like keybind
After #1368, `command-palette-entry=` will no longer clear the entries like the documentation says. Since i couldn't find an existing issue or discussion about this, I assume no one is actually using it. So I put 1.4.0 here, lemme know if you want to change it to 1.3.2.

> I basically copied the `keybind` parsing code and doc.
2026-05-14 19:43:08 +02:00
00jciv00
5ea45919d7 config: add gtk-horizontal-tab-scroll option
Add a boolean config option to enable/disable two-finger horizontal
touchpad scrolling for switching tabs. Defaults to true to preserve
existing behavior.

When tab scrolling is disabled or the scroll source is not a touchpad,
forward horizontal scroll events to the terminal so applications like
neovim can handle them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 11:46:56 -04:00
Andrei Lebedev
12ac19939c feat: add middle-click action configuration 2026-04-27 01:27:22 +10:00
Enzo William
14c06312d5 feat: add default GTK keybinds for move_tab
Reassign jump_to_prompt from Ctrl+Shift+PageUp/PageDown to
Ctrl+Shift+Arrow Up/Down on GTK, freeing the idiomatic Linux
keybinds (Ctrl+Shift+PageUp/PageDown) for move_tab.

This matches the tab-moving keybinds used by Firefox, GNOME Terminal,
and VSCode. The new jump_to_prompt binding mirrors the macOS pattern
(Cmd+Shift+Arrow Up/Down).

Closes #4998

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 13:53:37 -03:00
Mitchell Hashimoto
69452b5c6f Sync middle-click paste with copy-on-select (#12443)
Implements the behavior from #9788.

Today, middle-click paste always reads from the selection clipboard (or
the
system clipboard on platforms without a selection clipboard). With this
change
it follows `copy-on-select`:

- `true`: selection clipboard (unchanged)
- `clipboard`: system clipboard
- `false`: selection clipboard (also unchanged, preserves traditional
X11
  middle-click behavior)

The idea is symmetry: if `copy-on-select = clipboard` writes selections
to the
system clipboard, middle-click should come back from there too.

Also updated the config doc comment, which previously claimed
middle-click
"will always use the selection clipboard".

### Testing

`zig build test` passes locally (macOS, Zig 0.15.2).

Built and runtime-tested via the fork's CI:
https://github.com/007hacky007/ghostty/actions/runs/24707475544 - I'm
running the resulting binary daily and the three `copy-on-select` modes
behave as described above.
2026-04-25 09:39:12 -07:00
Lukas
7c91cef28d config: use Config to check key binding instead of App
Previously `ghostty_app_key_is_binding` (unlike Surface) is just using `config.keybind` to check whether a KeyEvent is in the set or not.

After this, I can add unit tests for keybinding more easily, with dummy configs.
2026-04-24 18:26:56 +02:00
007hacky007
50e8ebaf60 surface: sync middle-click paste source with copy-on-select
Middle-click paste previously always read from the selection clipboard
(falling back to the standard clipboard on platforms without one).

Now the paste source follows copy-on-select:
- copy-on-select = true: paste from selection clipboard (unchanged)
- copy-on-select = clipboard: paste from system clipboard
- copy-on-select = false: paste from selection clipboard (unchanged)

Fixes ghostty-org/ghostty#9788.
2026-04-20 19:56:45 +02:00
Alessandro De Blasis
909e733120 windows: handle backslash paths in config value parsing
CommaSplitter treats backslash as an escape character, which breaks
Windows paths like C:\Users\foo since \U is not a valid escape. On
Windows, treat backslash as a literal character outside of quoted
strings. Inside quotes, escape sequences still work as before.

The platform behavior is controlled by a single comptime constant
(escape_outside_quotes) so the logic lives in one place. Escape-specific
tests are skipped on Windows with SkipZigTest, and Windows-specific
tests are added separately.

Also fix Theme.parseCLI to not mistake the colon in a Windows drive
letter (C:\...) for a light/dark theme pair separator.

Note: other places in the config parsing also use colon as a delimiter
without accounting for Windows drive letters (command.zig prefix
parsing, keybind parsing). Those are tracked separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:30:14 +01:00
Mitchell Hashimoto
f60587ffcc renderer/size: move PaddingBalance enum out of Config
Previously WindowPaddingBalance was defined inside Config.zig, which
meant tests for renderer sizing had to pull in the full config
dependency. Move the enum into renderer/size.zig as PaddingBalance
and re-export it from Config so the public API is unchanged. This
lets size.zig tests run without depending on Config.
2026-03-23 09:14:46 -07:00
Mitchell Hashimoto
8bd3a493be libghostty: add resolved bg_color and fg_color to cells API
Fixes #11705

Add bg_color and fg_color options to GhosttyRenderStateRowCellsData
that resolve the final RGB color for a cell, flattening the multiple
possible sources. For background, this handles content-tag bg_color_rgb,
content-tag bg_color_palette (looked up in the palette), and the
style bg_color. For foreground, this resolves palette indices through
the palette; bold color handling is not applied and is left to the
caller.

Both return GHOSTTY_INVALID_VALUE when no explicit color is set, in
which case the caller should fall back to whatever default color it
wants (e.g. the terminal background/foreground).
2026-03-21 20:30:01 -07:00
Leah Amelia Chen
600f59ae31 gtk: implement quick-terminal-screen for Linux/Wayland (#11117) 2026-03-16 06:30:02 +00:00
Jaeseok Lee
86d9a04ece config: add equal option to window-padding-balance
Change `window-padding-balance` from `bool` to an enum with three
values:

- `false` - no balancing (default, unchanged)
- `true` - balance with vshift that caps top padding and shifts excess
  to bottom (existing behavior, unchanged)
- `equal` - balance whitespace equally on all four sides

This gives users who prefer truly equal padding a way to opt in without
changing the default behavior.
2026-03-15 13:50:21 +09:00
Mitchell Hashimoto
ab269e2c79 config: add progress-style option (#11289)
Adds progress-style config to control OSC 9;4 progress bar visibility.
Defaults to true, set false to hide.

Fixes #11241

AI Disclosure: Claude Code (Opus 4.6) used for codebase exploration,
code review, and testing assistance. All code written and reviewed by
hand.
2026-03-11 20:46:59 -07:00
Michal Olechowski
84d48d1c6a config: add progress-style option
Add option to disable OSC 9;4 ConEmu progress bars via config.

Fixes #11241
2026-03-12 01:33:25 +01:00
Paul Oliver
82a805296c docs: fix backtick rendering in selection-word-chars default value
The default value contains a literal backtick which broke inline code
rendering on the website. Use double backtick delimiters to properly
contain it.
2026-03-11 21:15:20 +13:00
Steve Hulet
f9862cd4e2 GTK does support scrollbars 2026-03-10 16:14:18 -07:00
Mitchell Hashimoto
04d5efc8eb config: working-directory expands ~/ prefix
Fixes #11336

Introduce a proper WorkingDirectory tagged union type with home, inherit,
and path variants. The field is now an optional (?WorkingDirectory) where
null represents "use platform default" which is resolved during Config.finalize
to .inherit (CLI) or .home (desktop launcher).
2026-03-10 14:33:40 -07:00
Mitchell Hashimoto
aaad43c235 macos: make paste_from_clipboard performable on macos
Fixes #10751
2026-03-10 10:25:14 -07:00
Mitchell Hashimoto
d9039eb85a config: don't double load app support path on macOS
Fixes #11323
2026-03-10 09:23:51 -07:00
Jeffrey C. Ollie
f8f431ba67 docs: update bell-features docs for macOS
PR #11154 didn't fully update the docs regarding `bell-features=audio`
on macOS.
2026-03-09 16:47:07 -05:00
Mitchell Hashimoto
25fa58143e macos: add macos-applescript config 2026-03-06 15:04:20 -08:00
Jeffrey C. Ollie
002a6cc765 gtk: use simpler method for passing overrides around
As discussed in Discord, this commit drops the `ConfigOverride` object
in favor of a simpler method of passing the overrides around. Completely
avoiding changes to the core wasn't possible but it's very minimal now.
2026-03-04 14:04:07 -06:00
Jeffrey C. Ollie
6961c2265e gtk: +new-window now respects --working-directory and -e
Fixes: #8862
Fixes: #10716

This adds the machinery to pass configuration settings received over
DBus down to the GObject Surface so that that configuration information
can be used to override some settings from the current "live" config
when creating a new window. Currently it's only possible to override
`--working-directory` and `--command`. `-e` on the `ghostty +new-window`
CLI works as well.

Adding more overridable settings is possible, but being able to fully
override any possible setting would better be served with a major
revamp of how Ghostty handles configs, which I is way out of scope at
the moment.
2026-03-04 14:04:06 -06:00
Alaa Ali
b215291914 macos: implement audio bell support with bell-audio-path
Extends the macOS bell implementation to support the `audio` bell
feature by playing a user-specified audio file via NSSound.

Previously, macOS only supported the `system` feature (NSSound.beep()).
This change adds support for:
- `audio` bell feature: plays the file at `bell-audio-path` using
  NSSound, respecting the `bell-audio-volume` setting
- Adds `cval()` to the `Path` type so it can be returned via the C API

Also removes the "(GTK only)" restriction from `bell-audio-path` and
`bell-audio-volume` documentation, as these options now work on macOS.

Example config:
  bell-features = audio
  bell-audio-path = /System/Library/Sounds/Glass.aiff
  bell-audio-volume = 0.8
2026-03-03 23:00:50 +01:00
Mitchell Hashimoto
bb646926f8 config: respect cursor-click-to-move for OSC133 click to move
When cursor-click-to-move is set to false, disable all prompt
click-to-move mechanisms including shell-native methods such as OSC 133
cl= (arrow key synthesis) and click_events. 

I forgot to port this config over when we did the OSC133 stuff.

Also update the config documentation to accurately describe the current
behavior.

Fixes #11138
2026-03-02 20:15:49 -08:00
Jake Guthmiller
6da660a9a5 gtk: implement quick-terminal-screen for Wayland
Implement the quick-terminal-screen config option on Linux/Wayland so
users can pin the quick terminal to a specific monitor instead of
always following the mouse cursor.

Use the kde_output_order_v1 protocol to identify the compositor's
primary monitor by connector name (e.g. "DP-1"). When the protocol is
unavailable, fall back to the first monitor in the GDK list.

- Add resolveQuickTerminalMonitor() to map config values to a
  gdk.Monitor: .mouse returns null (compositor decides), .main and
  .macos-menu-bar match by connector name via the protocol
- Call layer_shell.setMonitor() in both initQuickTerminal and
  syncQuickTerminal so config reloads take effect
- Update enteredMonitor to size the window using the configured
  monitor rather than whichever monitor was entered
- Update config documentation to reflect Linux support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:23:08 -06:00
Mitchell Hashimoto
c78d9cba9e config: disable palette-generate by default
Following the discussion at #10852, I believe this is the right default.
I'm willing to continue to revisit this decisions, but Ghostty 1.3 is
around the corner and I don't think such a change like this should be
pushed into it.

I think palette generation is best left as a _theme author_ tool. A
Ghostty color theme could include `palette-generate=true` if it wants
to customize the 256-color palette more easily. Of course, end users can
as well anytime.

Another part of my reasoning is that TUI programs who want this behavior
can already achieve it themselves by mixing dark/light theme detection
via CSI 996 (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)
with OSC 4/10/11 color query and change sequences, both of which are
decently supported in the terminal ecosystem and fully supported in
Ghostty.

I'm also open to considering some kind of new sequence to make this
easier for TUIs (probably a mode) where they can opt-in to palette
generation plus "harmonius" palettes (see `palette-harmonius`) and
Ghostty does it on demand then. I think that'd solve the legacy vs new
TUI argument where legacy programs can continue to make assumptions
about the palette and new programs can opt-in to a more dynamic palette
without having to do a lot of work themselves.
2026-02-27 11:32:15 -08:00
Kat
d5f621044d Update language config option's documentation.
Follow-up to #10976.
2026-02-27 11:08:19 +11:00