read(2) returning 0 means that the other end of the pipe/pty has been
closed (EOF), so there cannot be any more output to read on the pipe,
and
the io reader thread can just exit.
If exec.wait_after_command=false, the read thread's quit pipe is
immediately written to after the child process dies, so all is well.
However, if wait_after_command=true (which is the case when using
Ghostty
to run a .command/.sh file on macOS), the read thread keeps spinning,
causing persistent 100% CPU usage per exited process.
Fix it by exiting the reader thread on EOF.
If the read thread has already exited, it will have closed the read end
of the quit pipe. Unless SIGPIPE is masked with signal(SIGPIPE, SIG_IGN),
or the macOS-specific fcntl(F_SETNOSIGPIPE), writing to the write end of
a broken pipe kills the writer with SIGPIPE instead of returning -EPIPE
as an error. This causes a crash if the read thread exits before
threadExit.
This was already a possible race condition if read() returns
error.NotOpenForReading or error.InputOutput, but it's now much easier to
trigger due to the recent "termio/exec: fix 100% CPU usage after
wait-after-command process exits" fix.
Fix this by closing the quit pipe instead of writing to it.
This PR adds support for a dedicated `close_tab` keybinding action,
allowing users to bind specific keys for closing tabs. The
implementation:
- Adds `close_tab` as a new keybinding action
- Preserves all existing confirmation dialogs for running processes
- Works seamlessly with macOS native tab system
### Testing
- [x] Tested with single tabs
- [x] Tested with multiple tabs
- [x] Tested with running processes (confirmation dialog)
- [x] Tested with splits within tabs
<img width="797" alt="image"
src="https://github.com/user-attachments/assets/8e09eea3-1f71-40a3-a835-76de14013a29"
/>
https://github.com/user-attachments/assets/155210f7-20fe-4a96-8800-6969df214871
Partially resolved#4331
closes#2721
This PR resolves the issue where the Quick Terminal was not visible when
pressing the global keybind while a full-screen app was active.
### Changes
- Added new configuration options for `quick-terminal-space-behavior`
- The Quick Terminal will now overlay properly on top of full-screen
applications
#### Behavior
##### `quick-terminal-space-behavior = remain`
- The Quick Terminal will be remain open on the space when switching
spaces.
##### `quick-terminal-space-behavior = move`
- The Quick Terminal will be moved to active space when switching
spaces.
If the title is already the current working directory, hide the
subtitle. Otherwise show the current working directory, like if a
command is running for instance.
This is a re-opening of my original PR because I had to delete my fork
and re-fork it.
The reasoning for this PR is discussed at
https://github.com/ghostty-org/ghostty/discussions/3667
But in short, `pkg-config` queries `libadwaita-1` successfully, but not
for `adwaita-1`, hence renaming it would result in better integration
with pkg-config.
As discussed in #2670 and #2722
- This uses an NSPasteboard with the name
`com.mitchellh.ghostty.selection` as a dedicated 'selection' clipboard
- Sets `supports_selection_clipboard` to true for macOS
- Sets the default `copy-on-select` config to `.true` for macOS
- Adds a "Paste Selection" menu item and default cmd+shift+v key binding
for macOS (to match Terminal.app)
Adds the missing Bluetooth permission to Ghostty's application playlist
manifest file, as it was missing. Tweaks have also been made to existing
permission descriptions to be more readable. Should fix an abrupt crash
in Fastfetch and any other apps that may request Bluetooth permissions.
### apprt/gtk: Add version.runtimeAtLeast
This will be used for version checks that are independent of the version
of GTK we built against.
### apprt/gtk: Move most version checks to runtime
Unless we are guarding against symbols added in new versions we now
check against the runtime version of GTK to handle them even when we
didn't build against that version.
This is a major refactor of `build.zig` aimed at improving
maintainability while also fixing some bugs.
The major idea behind the refactor is to split the `build.zig` file up
into distinct `src/build/*.zig` files. By doing so, we can improve
readability of the primary `build.zig` while also enabling better reuse
of steps. Our `build.zig` is now less than 150 lines of code (of course,
it calls into a lot more lines but they're neatly organized now).
Ignore the commit messages I'm going to squash this whole thing.
Improvements:
* `build.zig` is less than 150 lines of readable code.
* Help strings and unicode table generators are only run once when
multiple artifacts are built since the results are the same regardless
of target.
* Metal lib is only built once per architecture (rather than once per
artifact)
* Resources (shell integration, terminfo, etc.) and docs are only
built/installed for artifacts that need them
* Wayland protocols no longer required for source build
Breaking changes:
* Removed broken wasm build (@gabydd will re-add)
* Removed conformance files, shell scripts are better and we don't run
these anymore
* Removed macOS app bundle creation, we don't use this anymore since we
use Xcode
## Extra: Some History
Our `build.zig` hasn't been significantly refactored since the project
started, when Zig was _version 0.10_. Since then, the build system has
changed significantly. We've only ever duct taped the `build.zig` as we
needed to support new Zig versions, new features, etc. It was a mess.
The major improvement is adapting the entire Ghostty `build.zig` to the
Step and LazyPath changes introduced way back in Zig 0.12. This lets us
better take advantage of parallelism and the dependency graph so that
steps are only executed as they're needed.
As such, you can see in the build.zig that we initialize a lot of
things, but unless a final target (i.e. install, run) references those
steps, _they'll never be executed_. This lets us clean up a lot.
'--posix' starts bash in POSIX mode (like /bin/sh). This is rarely used
for interactive shells, and removing automatic shell integration support
for this option allows us to simply/remove some exceptional code paths.
Users are still able to manually source the shell integration script.
Also fix an issue where we would still inject GHOSTTY_BASH_RCFILE if we
aborted the automatic shell integration path _after_ seeing an --rcfile
or --init-file argument.
This refactor enables two very significant improvements to our font
handling, which I will be implementing next:
1. Automatically adjust size of fallback faces to better align with the
primary face, a la CSS
[`font-size-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust).
[^1]
2. Move glyph resizing/positioning out of GPU-land and in to
`renderGlyph` and apply alignment/resizing rules from the nerd fonts
patcher[^2] to the glyphs at rasterization time, so that we can ensure
exact cell fits and swap out our embedded JB Mono with an unpatched
version with a separate dedicated symbols-only nerd font.
In addition to being necessary prep work for those two changes, this PR
is also a minor but real stand-alone improvement. By only computing the
cell metrics for our primary font, we avoid a *lot* of wasted work when
loading fallback fonts, and also avoid that being a source of load
errors, which we don't yet handle gracefully[^3].
To validate this PR I've run the full set of font backend tests locally
on my Mac with no failures, and did a sanity check of running Ghostty
with both renderers and with CoreText and FreeType font backends and
then `cat`ing a file that requires fallback fonts to render, and
everything looks correct.
[^1]: #3029
[^2]: The alignment and resizing rules for the nerd font symbols are
defined in the patcher
[here](6d0b8ba05a/font-patcher (L866-L1151))
[^3]: #2991
PS0 is evaluated after a command is read but before it is executed. The
'preexec' hook (from bash-preexec) is equivalent for our title-updating
purposes and conveniently provides the current command as an argument
(from its own `history 1` call).
The major idea behind the refactor is to split the `build.zig` file up into
distinct `src/build/*.zig` files. By doing so, we can improve readability of
the primary `build.zig` while also enabling better reuse of steps. Our
`build.zig` is now less than 150 lines of code (of course, it calls into a lot
more lines but they're neatly organized now).
Improvements:
* `build.zig` is less than 150 lines of readable code.
* Help strings and unicode table generators are only run once when multiple
artifacts are built since the results are the same regardless of target.
* Metal lib is only built once per architecture (rather than once per artifact)
* Resources (shell integration, terminfo, etc.) and docs are only
built/installed for artifacts that need them
Breaking changes:
* Removed broken wasm build (@gabydd will re-add)
* Removed conformance files, shell scripts are better and we don't run
these anymore
* Removed macOS app bundle creation, we don't use this anymore since we
use Xcode
## Some History
Our `build.zig` hasn't been significantly refactored since the project started,
when Zig was _version 0.10_. Since then, the build system has changed
significantly. We've only ever duct taped the `build.zig` as we needed to
support new Zig versions, new features, etc. It was a mess.
The major improvement is adapting the entire Ghostty `build.zig` to the Step
and LazyPath changes introduced way back in Zig 0.12. This lets us better take
advantage of parallelism and the dependency graph so that steps are only
executed as they're needed.
As such, you can see in the build.zig that we initialize a lot of things, but
unless a final target (i.e. install, run) references those steps, _they'll
never be executed_. This lets us clean up a lot.
'--posix' starts bash in POSIX mode (like /bin/sh). This is rarely used
for interactive shells, and removing automatic shell integration support
for this option allows us to simply/remove some exceptional code paths.
Users are still able to manually source the shell integration script.
Also fix an issue where we would still inject GHOSTTY_BASH_RCFILE if we
aborted the automatic shell integration path _after_ seeing an --rcfile
or --init-file argument.
Unless we are guarding against symbols added in new versions we now
check against the runtime version of GTK to handle them even when we
didn't build against that version.
## Description
This PR adds support for IPv6 URL detection in terminal output,
addressing issue #4743. The implementation enhances URL detection to
properly handle IPv6 addresses in URLs, including various formats and
use cases.
## Changes
- Added dedicated IPv6 URL pattern matching
- Integrated IPv6 pattern with existing URL regex
- Added comprehensive test suite for IPv6 URL scenarios
## Test Cases
The implementation includes test cases for:
- Basic IPv6 URLs (e.g., `http://[::]:8000/`)
- Full IPv6 addresses with ports
- Compressed IPv6 forms
- URLs with paths and query parameters
- Special cases (link-local, multicast)
- Context-specific scenarios (markdown)
## Related Issues
Resolves#4743
PS0 is evaluated after a command is read but before it is executed. The
'preexec' hook (from bash-preexec) is equivalent for our title-updating
purposes and conveniently provides the current command as an argument
(from its own `history 1` call).
- Add IPv6 URL pattern matching to support URLs like http://[::]:8000/
- Separate IPv6 URL pattern from main regex for better maintainability
- Add extensive test cases covering:
- Basic IPv6 URLs with ports
- URLs with paths and query parameters
- Compressed IPv6 forms
- Link-local and multicast addresses
- Mixed scenarios and markdown contexts
This sets the stage for dynamically adjusting the sizes of fallback
fonts based on the primary font's face metrics. It also removes a lot of
unnecessary work when loading fallback fonts, since we only actually use
the metrics based on the parimary font.
**Overview**: add support for file paths starts with `../` `./` and `/`
To implement this I extended the existing regex variable in the
`src/config` dir. In a few test cases, extra space is added
intentionally to verify we don't include space in the URL as it looks &
feels odd.
Here is the text file content used for testing
```console
➜ ~ cat test.txt
https://google.com
file:///Users/ABC/oss/ghostty/build.zig
file:///Users/ABC/oss/ghostty/debug.sh
/Users/ABC/oss/ghostty/src/../debug.sh
../../Applications/Zed.app/Contents/Info.plist
[link](/home/user/ghostty.user/example) -- non-existent
[link](/Users/ABC/oss/ghostty/src/../debug.sh)
first time ../../Applications/Zed.app/Contents/Info.plist contributor
➜ ~
```
Here is the screen recording of the changes.
[](https://www.youtube.com/watch?v=Q8qdwdBVbWk)
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)