Commit Graph

7315 Commits

Author SHA1 Message Date
Alex
6248030426 removed boolean logic, reverted back to ctrlOrSuper call 2025-08-22 09:10:53 -07:00
Alex
6708229a7e Removed boolean logic, reverted back to ctrlOrSuper call 2025-08-22 09:09:06 -07:00
Alex Straight
14f5a879a9 fix: make regular URLs work with either ctrl or super modifiers 2025-08-22 09:09:06 -07:00
Alex Straight
93c2400bf4 fix: copy_url_to_clipboard copies full OSC8 URL instead of single character
OSC8 links were only detected when exact platform-specific modifiers were held (Cmd on macOS, Ctrl on Linux), but copy_url_to_clipboard should work with either. Additionally, OSC8 links were using selectionString() which gets visible text instead of the actual URI. Now we use osc8URI() for OSC8 links and fall back to selectionString() for regex-detected links.

Fixes #7491
2025-08-22 09:09:05 -07:00
Mitchell Hashimoto
40105e1c7e cli: add filtering hotkey to list_themes (#8082)
## Summary

Implements the theme filtering hotkey as requested in #7930. 

## Implementation

- Adds 'f' hotkey to cycle through filtering options: all, dark, and
light.
- Integrates with existing search functionality.
- Preserves CLI `--color` flag behavior for initial state.
- Updates help menu with the new hotkey. 

**NOTE**: I noticed another PR
[#8079](https://github.com/ghostty-org/ghostty/pull/8079) opened. I
started this implementation independently prior and don't want to step
on any toes. Happy to collaborate or defer to maintainers.
2025-08-21 14:01:50 -07:00
Mitchell Hashimoto
c110c0f76d gtk-ng: add a helper to reduce boilerplate in GTK IPC (#8306) 2025-08-21 13:34:53 -07:00
Mitchell Hashimoto
53c2f915d8 gtk-ng: allow XKB remaps for non-writing-system keys (#8330)
Compromise solution to #7356

XKB is naughty. It's really really naughty. I don't understand why we
didn't just kill XKB with hammers during the Wayland migration and
change it for something much better. I don't understand why we're
content with what amounts to an OS-level software key remapper that
completely jumbles information about original physical key codes in
order to fake keyboard layouts, and not just let users who really want
to remap keys use some sort of evdev or udev-based mapper program.

In a sane system like macOS, the "c" key is always the "c" key, but it's
understood to produce the Unicode character "ц" when using a Russian
layout. XKB defies sanity, and just pretends that your "c" key is
actually a "ц" key instead, and so when you ask for the keybind "Ctrl+C"
it just shrugs in apathy (#7309). And so, we took matters into our own
hands and interpreted hardware keycodes ourselves.

But then, a *lot* of people have the ingrained muscle memory of swapping
Escape with Caps Lock so that it is easier to hit. We respect that. In a
sane system, they would use a remapper that actually makes the system
think you've hit the Escape key when in reality you've hit the Caps Lock
key, so in all intents and purposes to the OS and any app developer,
these two just have their wires swapped. But not on Linux. Somehow this
and the aforementioned case should be treated by the same key transform
algorithm, which is completely diabolical.

As a result, we have to settle for a compromise that truly satisfies
neither party — by allowing XKB remaps for keys that don't really change
depending on the layout.

The Linux input stack besets all hopes and aspirations.
2025-08-21 11:45:48 -07:00
Leah Amelia Chen
534aa508d6 gtk-ng: allow XKB remaps for non-writing-system keys
Compromise solution to #7356

XKB is naughty. It's really really naughty. I don't understand why we
didn't just kill XKB with hammers during the Wayland migration and change
it for something much better. I don't understand why we're content with
what amounts to an OS-level software key remapper that completely jumbles
information about original physical key codes in order to fake keyboard
layouts, and not just let users who really want to remap keys use some
sort of evdev or udev-based mapper program.

In a sane system like macOS, the "c" key is always the "c" key, but it's
understood to produce the Unicode character "ц" when using a Russian
layout. XKB defies sanity, and just pretends that your "c" key is
actually a "ц" key instead, and so when you ask for the keybind "Ctrl+C"
it just shrugs in apathy (#7309). And so, we took matters into our own
hands and interpreted hardware keycodes ourselves.

But then, a *lot* of people have the ingrained muscle memory of swapping
Escape with Caps Lock so that it is easier to hit. We respect that.
In a sane system, they would use a remapper that actually makes the
system think you've hit the Escape key when in reality you've hit the
Caps Lock key, so in all intents and purposes to the OS and any app
developer, these two just have their wires swapped. But not on Linux.
Somehow this and the aforementioned case should be treated by the same
key transform algorithm, which is completely diabolical.

As a result, we have to settle for a compromise that truly satisfies
neither party — by allowing XKB remaps for keys that don't really change
depending on the layout.

The Linux input stack besets all hopes and aspirations.
2025-08-22 02:02:11 +08:00
Mitchell Hashimoto
d725f2346f macOS: Add macos-dock-drop-folder-behavior (new tab or window) configuration option (#8114)
This PR adds a new configuration option
`macos-dock-drop-folder-behavior` that controls whether folders dropped
onto the Ghostty dock icon open in a new tab (default) or a new window.

## Changes

### Configuration Option Added
- **Option name**: `macos-dock-drop-folder-behavior`
- **Valid values**: 
  - `tab` (default) - Opens folders in a new tab in the main window
  - `window` - Opens folders in a new window
- **Platform**: macOS only

### Files Modified

1. **`src/config/Config.zig`**
- Added `MacOSDockDropFolderBehavior` enum with `tab` and `window`
values
   - Added configuration field with default value of `.tab`
   - Added documentation explaining the option

2. **`macos/Sources/Ghostty/Package.swift`**
   - Added `MacOSDockDropFolderBehavior` enum to match the Zig enum

3. **`macos/Sources/Ghostty/Ghostty.Config.swift`**
- Added `macosDockDropFolderBehavior` computed property to access the
configuration value from Swift

4. **`macos/Sources/App/macOS/AppDelegate.swift`**
- Modified `application(_:openFile:)` method to check the configuration
- When a folder is dropped on the dock icon, it now respects the user's
preference

## Usage

Add to your Ghostty configuration file:
```
macos-dock-drop-folder-behavior = window
```

## Motivation

This feature is useful for users (like me!) who prefer window-based
workflows over tab-based workflows when opening folders via drag and
drop on macOS.
2025-08-21 10:55:04 -07:00
Jeffrey C. Ollie
dcc5aded6e gtk-ng: more complete GTK startup/shutdown in test (#8324) 2025-08-21 12:52:10 -05:00
Mitchell Hashimoto
e01ff4093a macos: have macos-dock-drop-behavior apply to all drops 2025-08-21 10:45:17 -07:00
David Keegan
f9ad061ea8 Add macos-dock-drop-folder-behavior configuration option
This adds a new configuration option that controls whether folders
dropped onto the Ghostty dock icon open in a new tab (default) or
a new window.

The option accepts two values:
- tab: Opens folders in a new tab in the main window (default)
- window: Opens folders in a new window

This is useful for users who prefer window-based workflows over
tab-based workflows when opening folders via drag and drop.
2025-08-21 10:30:26 -07:00
Nicholas Mata
5948bd3f02 Add support for 'custom' on 'macos_icon' to support a completely custom app icon 2025-08-21 10:00:15 -07:00
Mitchell Hashimoto
073a8b01d2 terminal: explicitly initialize undefined fields at runtime (#8323)
This works around the Zig issue as noted in the comment.

No new Valgrind issues found from this.
2025-08-21 07:34:21 -07:00
Jeffrey C. Ollie
36f7e018ae gtk-ng: more complete GTK startup/shutdown 2025-08-21 09:29:22 -05:00
Mitchell Hashimoto
531924e7e7 terminal: explicitly initialize undefined fields at runtime
This works around the Zig issue as noted in the comment.

No new Valgrind issues found from this.
2025-08-21 07:27:43 -07:00
Mitchell Hashimoto
2ffc61d21e gtk-ng: properly skip Zig test (#8322) 2025-08-21 07:25:30 -07:00
Jeffrey C. Ollie
2d0f930e6a gtk-ng: properly skip Zig test 2025-08-21 09:14:06 -05:00
Mitchell Hashimoto
4cc33b546c Full unit test suite passing Valgrind (#8319)
This contains the various changes necessary to get the full unit test
suite passing Valgrind, and configures CI to run this.

I disabled relatively few (less than 10) tests under Valgrind because
they're way too slow: all `verifyIntegrity` tests, because those run
anyways in debug and check their own memory health, a font test that
fills out font map, and the sprite render test. Everything else runs
as-is.

I found a number of issues, most were in the tests themselves. A couple
in actual code. A funny one was some undefined memory on tabstop resize
if you exceed the default number of tabstops. I don't know any real
world program that ever even did that (memory issue aside), and that
whole file hasn't been touched since 2022, so that was funny.

No memory leaks in actual code, but a number of leaks in tests. All
resolved.

I think we're still missing some reports because of the Zig bug:
https://github.com/ziglang/zig/issues/19148 so I'm gong to audit our
codebase after this and look for cases of that.
2025-08-21 07:04:13 -07:00
Mitchell Hashimoto
96a0b9021c font: disable sprite test in valgrind 2025-08-21 06:57:25 -07:00
Mitchell Hashimoto
fe5eafac0a font: fix fontconfig leaks in unit tests 2025-08-21 06:53:59 -07:00
Qwerasd
d2ac29c919 font/CoreText: fix positioning for padded scaled glyphs (#8310)
When constraints increased or decreased the size significantly, the
fractional position was getting messed up by the scale. This change
separates that out so that it applies correctly.

I noticed this when messing around with constraints, adding this
constraint to every glyph and then running with `font-family=Arial` and
`adjust-cell-width = -35%` (if you want to reproduce this)
```zig
constraint = .{
    .size_horizontal = .stretch,
    .align_horizontal = .center,
    .pad_left = 0.1,
    .pad_right = 0.1,
};
```
The padding was disproportionately affecting thin glyphs that were
stretched a lot. The problem was that the padding was being multiplied
by the scale.

This also made it so the top or right of said thin glyphs often got
clipped off by the edge of the canvas.

Anyway I fixed it.

|Before|After|
|-|-|
|<img width="1824" height="1480" alt="image"
src="https://github.com/user-attachments/assets/32779f9d-a048-4a8c-b5ea-0e8a851d5119"
/>|<img width="1824" height="1480" alt="image"
src="https://github.com/user-attachments/assets/5bf449e5-699e-4bdc-ac96-2b776f9fb7fa"
/>|
2025-08-20 21:55:51 -06:00
Mitchell Hashimoto
a57afd41ac terminal: fix undefined memory access in unit test 2025-08-20 20:54:29 -07:00
Mitchell Hashimoto
566062c0a5 terminal: fix undefined memory in Tabstops code 2025-08-20 20:44:35 -07:00
Mitchell Hashimoto
be51f3e729 terminal: fix uninitialized memory in Cell init 2025-08-20 20:21:26 -07:00
Mitchell Hashimoto
3ce043123b terminal: fix undefined memory access in PageList eraseRows 2025-08-20 19:53:33 -07:00
Qwerasd
610ce94f2d font/CoreText: fix positioning for padded scaled glyphs
When constraints increased or decreased the size significantly, the
fractional position was getting messed up by the scale. This change
separates that out so that it applies correctly.
2025-08-20 15:26:16 -06:00
Mitchell Hashimoto
4fa7b412d4 terminal: disable integrity checks under Valgrind 2025-08-20 14:05:31 -07:00
Mitchell Hashimoto
42f0c05d7e terminal: fix undefined memory access in OSC parser
Fixes #8007

Verified with `test-valgrind -Dtest-filter="OSC"` which had cond access
errors before, and none after this. Basically a copy of #8008.
2025-08-20 13:05:57 -07:00
Jeffrey C. Ollie
108260100c gtk-ng: add a helper to reduce boilerplate in GTK IPC 2025-08-20 14:53:17 -05:00
Mitchell Hashimoto
131f170f89 terminal: change OSC parser to explicit init to set undefined
This works around: https://github.com/ziglang/zig/issues/19148
This lets our `test-valgrind` command catch some issues. We'll have to
follow this pattern in more places but I want to do it incrementally so
things keep passing.

I **do not** want to blindly follow this pattern everywhere. I want to
start by focusing in only on the structs that set `undefined` as default
fields that we're also about to test in isolation with Valgrind. Its
just too much noise otherwise and not a general style I'm sure of; it's
worth it for Valgrind though.
2025-08-20 12:38:29 -07:00
Mitchell Hashimoto
f87213c2f6 build: add run-valgrind and test-valgrind steps
This adds two explicit `zig build` steps: `run-valgrind` and
`test-valgrind` to run the Ghostty exe or tests under Valgrind,
respectively.

This simplifies the manual Valgrind calls in a few ways:

1. It automatically sets the CPU to baseline, which is a frequent and
   requirement for Valgrind on newer CPUs, and generally safe.

2. It sets up the rather complicated set of flags to call Valgrind with,
   importantly setting up our suppressions.

3. It enables pairing it with the typical and comfortable workflow of
   specifying extra args (with `--`) or flags like `-Dtest-filter` for
   tests.
2025-08-20 11:43:48 -07:00
Mitchell Hashimoto
1c96870c17 macos: show copy menu item if selection start is outside viewport
Fixes #8187

This properly handles the scenario with our `read_text` C API when the
selection start is outside the viewport. Previously we'd report null (no
text) which would cascade into things like the right click menu not
showing a copy option.
2025-08-19 14:10:51 -07:00
Mitchell Hashimoto
5745f5048c Configurable right click behavior (#8254)
This MR addresses #4404 following the approach suggested
[here](https://github.com/ghostty-org/ghostty/issues/4404#issuecomment-2708410143).
Implementing the behavior known e.g. from Putty or Windows Terminal.

The following configuration values for `right-click-action` are
provided:
* `context-menu` - Show the context menu.
* `paste` - Paste the contents of the clipboard.
* `copy` - Copy the selected text to the clipboard.
* `copy-and-paste` - Copy the selected text to the clipboard, paste if
nothing is selected.
*  `ignore` - Do nothing, ignore the right-click.

I followed #5935 for getting an idea on where to start. I hope this to
be a temporary solution until "bindable mouse bindings" are introduced.

This is my first time writing Zig code, so I am happy to incorporate any
feedback.

Thank you all very much for your work!
2025-08-19 13:21:12 -07:00
Mitchell Hashimoto
f2de485cae gtk-ng: attach surface size callbacks AFTER realize (#8287)
The `gdk.Surface` is only ever available *after* the window had been
first presented and mapped. Trying to get the surface during `init` like
what we had previously done will **always** return null.
2025-08-19 12:36:23 -07:00
Mitchell Hashimoto
33b1c969d7 Fix PageList Reflow OOM Conditions (#8277)
Previously, when encountering an OOM when copying graphemes, hyperlinks,
or styles to a new page during reflow, the attempted resolution was to
copy the current row in to a new page and continue on- which works in
99% of cases, but isn't sound, since it's possible for a single row to
exceed the capacity on any of these.

This led to rare but real crashes like #8009.

I've added tests that produce all of the failure conditions, and
resolved them by changing the strategy from making a new page to
increasing the capacity of the current one.

There should probably be some level of abstraction added around this,
since multiple places in the code now do this sort of thing- attempt to
add some managed memory to a page, adjusting their capacity upwards as
necessary. But for now, I kept it all inline here.
2025-08-19 12:30:53 -07:00
Luzian Bieri
54b7e1838c feat: add right-click action configuration 2025-08-19 21:29:52 +02:00
Leah Amelia Chen
7977b3695a gtk-ng: attach surface size callbacks AFTER realize
The `gdk.Surface` is only ever available *after* the window had been
first presented and mapped. Trying to get the surface during `init`
like what we had previously done will **always** return null.
2025-08-20 03:29:15 +08:00
Mitchell Hashimoto
b3f68f6653 gtk-ng: fix toggle_window_decoration (#8286)
When window-decoration=none, setting the window decoration to null would
just mean it would default to none again, creating a cycle of torment
none can break out of... that sounds a bit too dramatic doesn't it

Fixes #8274
2025-08-19 12:27:38 -07:00
Mitchell Hashimoto
b65b42a5fa zsh: minor shell integration improvements (#8281)
- test `setupZsh`
- clean up `_ghostty_file` in the early exit path
- improve some `.zshenv` comments
2025-08-19 12:07:24 -07:00
Mitchell Hashimoto
27c2babae1 config: fix accidental codeblock indents (#8284)
In our webgen we treat 4 consecutive spaces as a code block, which is
often triggered by mistake when a paragraph is encased within a list.

We should probably fix this more thoroughly at some point since I don't
think actual Markdown parsers have the same behavior, but for now we
just fall back to using 3-space indents.

As an example of this occurring on the tip website:
<img width="1177" height="1012" alt="paragraphs being erroneously turned
into code blocks"
src="https://github.com/user-attachments/assets/878a8c83-3e37-41b7-90d9-fbd5b692bf16"
/>
2025-08-19 12:06:44 -07:00
Leah Amelia Chen
f3d8aac1e9 gtk-ng: fix toggle_window_decoration
When window-decoration=none, setting the window decoration to null would
just mean it would default to none again, creating a cycle of torment
none can break out of... that sounds a bit too dramatic doesn't it

Fixes #8274
2025-08-20 03:06:12 +08:00
Leah Amelia Chen
2421132d80 config: fix accidental codeblock indents
In our webgen we treat 4 consecutive spaces as a code block, which is
often triggered by mistake when a paragraph is encased within a list.

We should probably fix this more thoroughly at some point since I don't
think actual Markdown parsers have the same behavior, but for now we
just fall back to using 3-space indents.
2025-08-20 02:37:38 +08:00
Jon Parise
8300512a91 zsh: clarify that an unset ZDOTDIR defaults to HOME
This fixes the incorrect comment and uses $HOME (rather than ~) to be a
little bit more explicit.

Also, our script is named ghostty-integration, not ghostty.zsh, so
update that part of the comment, too.
2025-08-19 10:41:47 -04:00
Jon Parise
e8a60a375c zsh: unset _ghostty_file in the early exit path
If we're running a too-old version of zsh, we exit early. This skipped
the _ghostty_file cleanup path below.
2025-08-19 10:36:26 -04:00
Jon Parise
f430c03ff3 zsh: add tests for setupZsh 2025-08-19 10:35:05 -04:00
Qwerasd
a53ec1e567 PageList: increase capacity for style OOM during reflow 2025-08-18 19:18:20 -06:00
Qwerasd
ac308b0418 test(PageList): add failing test for reflow style OOM 2025-08-18 19:18:20 -06:00
Qwerasd
15aa9df051 PageList: increase capacity for grapheme OOM during reflow 2025-08-18 18:49:33 -06:00
Qwerasd
3fcfc34ef7 test(PageList): add failing test for reflow grapheme OOM 2025-08-18 18:39:10 -06:00