macOS bitmap-only fonts are a poorly documented format, which are often
distributed as `.dfont` or `.dfon` files. They use a 'bhed' table in
place of the usual 'head', but the table format is byte-identical, so
enabling the use of bitmap-only fonts only requires us to properly fetch
this table while calculating metrics.
ref: https://fontforge.org/docs/techref/bitmaponlysfnt.html
Reverts #3550 for obvious reasons, and may close issue #2168 because
this should now mean that bitmap fonts are properly supported under both
font backends due to #3837 - unless `otb` fonts are still not properly
supported under FreeType (they are not supported under CoreText because
CoreText does not know how to handle them).
I tested this change with the `.dfont` distribution of
[Cozette](https://github.com/slavfox/Cozette) v1.25.2 and saw no visual
issues.
macOS bitmap-only fonts are a poorly documented format, which are often
distributed as `.dfont` or `.dfon` files. They use a 'bhed' table in
place of the usual 'head', but the table format is byte-identical, so
enabling the use of bitmap-only fonts only requires us to properly fetch
this table while calculating metrics.
ref: https://fontforge.org/docs/techref/bitmaponlysfnt.html
On my system (pop-os 22.04 LTS) with system theme and seperate light and
dark themes, ghostty always defaults to light mode. Switches between
light and dark mode are properly handled.
In the logs this error is reported:
error(gtk): unable to get current color scheme:
GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such method
“ReadOne”
The spec notes that the other functions are "[Deprecated, use ReadOne
instead.](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Settings.html)"
so using ReadOne is cerainly the correct path.
I've managed to fix this on my system by checking for the error and
falling back to an implementation using the deprecated Read.
Discussion: https://github.com/ghostty-org/ghostty/discussions/3704
Issue: https://github.com/ghostty-org/ghostty/issues/4038
When writing selected text to file, use `topLeft` and `bottomRight` instead of
`start` and `end` to ensure correct coordinate ordering. This fixes an issue
where selection files could be empty when selecting text in reverse order.
- Use `terminal.Selection.topLeft()` for start coordinate
- Use `terminal.Selection.bottomRight()` for end coordinate
Fixes#3953Fixes#3284
This fixes two issues. In fixing one issue, the other became apparent so
I fixed both in this one commit.
The first issue is that on macOS, the `open` command should take the
`-t` flag to open text files in a text editor. To do this, the `os.open`
function now takes a type hint that is used to better do the right
thing.
Second, the order of the paths that we attempt to open when editing a
config on macOS is wrong. Our priority when loading configs is well
documented:
https://ghostty.org/docs/config#macos-specific-path-(macos-only). But
open_config does the opposite. This makes it too easy for people to have
configs that are being overridden without them realizing it.
This commit changes the order of the paths to match the documented
order. If neither path exists, we prefer AppSupport.
We refresh the link hover state in two (generic) cases
1. When the modifiers change
2. When the cursor changes position
Each of these have additional state qualifiers. Modify the qualifiers
such that we refresh links under the following scenarios:
1. Modifiers change
- Control is pressed (this is handled in the renderer)
- Mouse reporting is off
OR
Mouse reporting is on AND shift is pressed AND we are NOT reporting
shift to the terminal
2. Cursor changes position
- Control is pressed (this is handled in the renderer)
- We previously were over a link
- The position changed (or we had no previous position)
- Mouse reporting is off
OR
Mouse reporting is on AND shift is pressed AND we are NOT reporting
shift to the terminal
This fixes a few issues with the previous implementation:
1. If mouse reporting was on and you were over a link, pressing ctrl
would enable link hover state. If you moved your mouse, you would
exit that state. The logic in the keyCallback and the
cursorPosCallback was not the same. Now, they both check for the same
set of conditions
2. If mouse reporting was off, you could hold control and move the mouse
to discover links. If mouse reporting was on, holding control + shift
would not allow you to discover links. You had to be hovering one
when you pressed the modifiers. Previously, we only refreshed links
if we *weren't* reporting the mouse event. Now, we refresh links even
even if we report a mouse event (ie a mouse motion event with the
shift modifier pressed *will* hover links and also report events)
## Old Behavior
Notice that the state of the hyperlink is erratic in `comlink`. When I
am over it and press ctrl the link is underlined and the url hint in the
lower left shown for one frame, but then the state is dropped.
https://github.com/user-attachments/assets/52d6a8c8-8459-4d67-85eb-5d91f9833771
## New Behavior
State is retained when holding ctrl+shift. And the link only underlines
if I press both ctrl+shift. If I move the mouse around while holding
these keys, I can discover new links.
https://github.com/user-attachments/assets/78fa8e97-eb0c-4618-bd96-fe40d6bc67ce
The previous approach to wrapping `sudo` had a few shortcomings:
1. We were (re)defining our 'sudo' function wrapper in the "precmd"
path. It only needs to be defined once in the shell session.
2. If there was an existing 'sudo' alias, the function definition would
conflict and result in a syntax error.
Fix (1) by hoisting the 'sudo' function into global scope. I also
considered only defining our wrapper if an executable `sudo` binary
could be found (e.g. `-x $(builtin command -v sudo)`, but let's keep the
existing behavior for now. This allows for a `sudo` command to be
installed later in the shell session and still be wrapped.
Address (2) by defining the wrapper function using `function sudo`
(instead of `sudo()`) syntax. An explicit function definition won't
clash with an existing 'sudo' alias, although the alias will continue to
take precedence (i.e. our wrapper won't be called). If the alias is
defined _after_ our 'sudo' function is defined, our function will call
the aliased command.
This ordering is relevant because it can result in different behaviors
depending on when a user defines their aliases relative to sourcing the
shell integration script. Our recommendation remains that users either
use automatic shell injection or manually source the shell integration
script _before_ other things in their `.bashrc`, so that aligns with the
expected behavior of the 'sudo' wrapper with regard to aliases. Given
that, I don't think we need any more explicit user-facing documentation
on this beyond the script-level comments.
Fixes#3953Fixes#3284
This fixes two issues. In fixing one issue, the other became apparent so
I fixed both in this one commit.
The first issue is that on macOS, the `open` command should take the
`-t` flag to open text files in a text editor. To do this, the `os.open`
function now takes a type hint that is used to better do the right
thing.
Second, the order of the paths that we attempt to open when editing a
config on macOS is wrong. Our priority when loading configs is well documented:
https://ghostty.org/docs/config#macos-specific-path-(macos-only). But
open_config does the opposite. This makes it too easy for people to have
configs that are being overridden without them realizing it.
This commit changes the order of the paths to match the documented
order. If neither path exists, we prefer AppSupport.
The comptime path of the GTK `atLeast()` version function fails to take
the proceeding portion of the version into account. For example version
5.1.0 is incorrectly marked as less than 4.16.7 due to the minor version
(1) being less than the minor we are comparing against (16).
This update required that the major versions be equal when comparing
minor versions and the major and minor versions be equal when comparing
micro versions.
For example, building against GTK 4.17.1:
Before: version.atLeast(4,16,2) -> false
After: version.atLeast(4,16,2) -> true
The previous approach to wrapping `sudo` had a few shortcomings:
1. We were (re)defining our 'sudo' function wrapper in the "precmd"
path. It only needs to be defined once in the shell session.
2. If there was an existing 'sudo' alias, the function definition would
conflict and result in a syntax error.
Fix (1) by hoisting the 'sudo' function into global scope. I also
considered only defining our wrapper if an executable `sudo` binary
could be found (e.g. `-x $(builtin command -v sudo)`, but let's keep the
existing behavior for now. This allows for a `sudo` command to be
installed later in the shell session and still be wrapped.
Address (2) by defining the wrapper function using `function sudo`
(instead of `sudo()`) syntax. An explicit function definition won't
clash with an existing 'sudo' alias, although the alias will continue to
take precedence (i.e. our wrapper won't be called). If the alias is
defined _after_ our 'sudo' function is defined, our function will call
the aliased command.
This ordering is relevant because it can result in different behaviors
depending on when a user defines their aliases relative to sourcing the
shell integration script. Our recommendation remains that users either
use automatic shell injection or manually source the shell integration
script _before_ other things in their `.bashrc`, so that aligns with the
expected behavior of the 'sudo' wrapper with regard to aliases. Given
that, I don't think we need any more explicit user-facing documentation
on this beyond the script-level comments.
Before this change, there seemed to be some artifacting in the window
corners due to the window border no longer outlining the content
properly. By detecting the situation, we can turn the window border
radius off.
Signed-off-by: Tristan Partin <tristan@partin.io>
If a blur radius config value was previously set but then removed or set
to 0, the new blur radius would not take effect on config reload due to
the early return clause.
The comptime path of the GTK `atLeast()` version function fails to take
the preceeding portion of the version into account. For example version
5.1.0 is incorrectly marked as less than 4.16.7 due to the minor version
(1) being less than the minor we are comparing against (16).
For example, building against GTK 4.17.1:
Before: version.atLeast(4,16,2) -> false
After: version.atLeast(4,16,2) -> true
Fixes#3202
Two changes to get here:
1. Do not fail startup if crash reporting initialization fails. This is a
non-critical feature and should not prevent the terminal from starting.
2. Avoid freeing Sentry transport on error path. This segfaults.
Upstream issue will be reported separately.