`load_color` was multiplying the alpha channel by itself as well, rather
than just the `rgb` channels.
Also made sure to divide alpha out before applying gamma encoding back
to text color when not using linear blending, which was another source
of error.
Probably fixes the problem observed in #5133 -- I couldn't reproduce the
exact color shift, but did see a similar one with some of my test
colors. This most visibly affects dimmed text since it uses an alpha of
less than 1 for the text color.
Allowing the alert to be automatically closed after the completion handler finishes doesn't seem to play well when the completion handler closes the window on which the alert is attached
We use `trap` to bootstrap our installation function (__bp_install). We
remove our code upon first execution but need to restore any preexisting
trap calls. We previously used `sed` to process the trap string, but
that had two downsides:
1. `sed` is an external command dependency. It needs to exist on the
system, and we need to invoke it in a subshell (which has some runtime
cost).
2. The regular expression pattern was imperfect and didn't handle
trickier cases like `'` characters in the trap string:
$ (trap "echo 'hello'" DEBUG; trap -p DEBUG)
hello
trap -- 'echo '\''hello'\''' DEBUG
This change removes the dependency on `sed` by locally evaluating the
trap string and extracting any prior trap. This works reliably because
we control the format our trap string, which looks like this (with
newlines expanded):
__bp_trap_string="$(trap -p DEBUG)"
trap - DEBUG
__bp_install
Upstream: https://github.com/rcaloras/bash-preexec/pull/170
We post-process history 1's output to extract the current command. This
processing needs to strip the leading history number, an optional *
character indicating whether the entry was modified (or a space), and
then a space separating character.
We were previously using sed(1) for this, but we can implement an
equivalent transformation using bash's native parameter expansion
syntax.
This also results in ~4x reduction in per-prompt command overhead.
Upstream: https://github.com/rcaloras/bash-preexec/pull/167
We now use a temporary function (__ghostty_bash_startup) to perform the
bash startup sequence. This gives us a local function scope in which to
store some temporary values (like rcfile). This way, they won't leak
into the sourced files' scopes.
Also, use `~/` instead of `$HOME` for home directory paths as a simpler
shorthand notation.
Compositors can actually tell us whether they want to use CSD or SSD!
(Ignore the context menu changes — they will most likely be unified
after #4952 anyway)
We were returning bg colors when we shouldn't have since when we have
background color transparency we need to return any bg color cells as
fully transparent rather than their actual color.
This caused a problem of overly opaque padding when background opacity
was < 1.0
We use `trap` to bootstrap our installation function (__bp_install). We
remove our code upon first execution but need to restore any preexisting
trap calls. We previously used `sed` to process the trap string, but
that had two downsides:
1. `sed` is an external command dependency. It needs to exist on the
system, and we need to invoke it in a subshell (which has some
runtime cost).
2. The regular expression pattern was imperfect and didn't handle
trickier cases like `'` characters in the trap string:
$ (trap "echo 'hello'" DEBUG; trap -p DEBUG)
hello
trap -- 'echo '\''hello'\''' DEBUG
This change removes the dependency on `sed` by locally evaluating the
trap string and extracting any prior trap. This works reliably because
we control the format our trap string, which looks like this (with
newlines expanded):
__bp_trap_string="$(trap -p DEBUG)"
trap - DEBUG
__bp_install
We post-process history 1's output to extract the current command. This
processing needs to strip the leading history number, an optional *
character indicating whether the entry was modified (or a space), and
then a space separating character.
We were previously using sed(1) for this, but we can implement an
equivalent transformation using bash's native parameter expansion
syntax.
This also results in ~4x reduction in per-prompt command overhead.
We now use a temporary function (__ghostty_bash_startup) to perform the
bash startup sequence. This gives us a local function scope in which to
store some temporary values (like rcfile). This way, they won't leak
into the sourced files' scopes.
Also, use `~/` instead of `$HOME` for home directory paths as a simpler
shorthand notation.
We were returning bg colors when we shouldn't have since when we have
background color transparency we need to return any bg color cells as
fully transparent rather than their actual color.
Fixes#4516
By using the `CAMetalLayer`'s `backgroundColor` property instead of
drawing the background color in our shader, it is always stretched to
cover the full surface, even when live-resizing, and it doesn't require
us to draw a frame for it to be initialized so there's no transparent
flash when a new surface is created (as in a new split/tab).
This commit also allows for hot reload of `background-opacity`,
`window-vsync`, and `window-colorspace`.
By using the `CAMetalLayer`'s `backgroundColor` property instead of
drawing the background color in our shader, it is always stretched to
cover the full surface, even when live-resizing, and it doesn't require
us to draw a frame for it to be initialized so there's no transparent
flash when a new surface is created (as in a new split/tab).
This commit also allows for hot reload of `background-opacity`,
`window-vsync`, and `window-colorspace`.
3cdb9a7 made ghostty unable to compile on my debian system (adwaita
1.2.2) due to `adw_tab_overview_set_show_start_title_buttons` and
`adw_tab_overview_set_show_end_title_buttons` which are since 1.3.0. I
increased the comptime check to 1.4.0, this is fine since the assignment
of `tab_overview` is [already comptime guarded by
1.4.0](3cdb9a7dfe/src/apprt/gtk/Window.zig (L130))
This PR addresses #2125 for the Metal renderer. Both options are
available: "Apple-style" blending where colors are blended in a wide
gamut color space, which reduces but does not eliminate artifacts; and
linear blending where colors are blended in linear RGB.
Because this doesn't add support for linear blending on Linux, I don't
know whether the issue should be closed or not.
### List of changes in no particular order
- We now set the layer's color space in the renderer not in the apprt
- We always set the layer to Display P3 color spaces
- If the user hasn't configured their `window-colorspace` to
`display-p3` then terminal colors are automatically converted from sRGB
to the corresponding Display P3 color in the shader
- Background color is not set with the clear color anymore, instead we
explicitly set all bg cell colors since this is needed for minimum
contrast to not break with dark text on the default bg color (try it
out, it forces it fully white right now), and we just draw the
background as a part of the bg cells shader. Note: We may want to move
the main background color to be the `backgroundColor` property on the
`CAMetalLayer`, because this should fix the flash of transparency during
startup (#4516) and the weirdness at the edge of the window when
resizing. I didn't make that a part of this PR because it requires
further changes and my changes are already pretty significant, but I can
make it a follow-up.
- Added a config option for changing alpha blending between "native"
blending, where colors are just blended directly in sRGB (or Display P3)
and linear blending, where colors are blended in linear space.
- Added a config option for an experimental technique that I think works
pretty well which compensates for the perceptual thinning and thickening
of dark and light text respectively when using linear blending.
- Custom shaders can now be hot reloaded with config reloads.
- Fixed a bug that was revealed when I changed how we handle
backgrounds, page widths weren't being set while cloning the screen.
### Main takeaways
Color blending now matches nearly identically to Apple apps like
Terminal.app and TextEdit, not *quite* identical in worst case
scenarios, off by the tiniest bit, because the default color space is
*slightly* different than Display P3.
Linear alpha blending is now available for mac users who prefer more
accurate color reproduction, and personally I think it looks very nice
with the alpha correction turned on, I will be daily driving that
configuration.
### Future work
- Handle primary background color with `CALayer.backgroundColor` instead
of in shader, to avoid issues around edges when resizing.
- Parse color space info directly from ICC profiles and compute the
color conversion matrix dynamically, and pass it as a uniform to the
shaders.
- Port linear blending option to OpenGL.
- Maybe support wide gamut images (right now all images are assumed to
be sRGB).
This commit is quite large because it's fairly interconnected and can't
be split up in a logical way. The main part of this commit is that alpha
blending is now always done in the Display P3 color space, and depending
on the configured `window-colorspace` colors will be converted from sRGB
or assumed to already be Display P3 colors. In addition, a config option
`text-blending` has been added which allows the user to configure linear
blending (AKA "gamma correction"). Linear alpha blending also applies to
images and makes custom shaders receive linear colors rather than sRGB.
In addition, an experimental option has been added which corrects linear
blending's tendency to make dark text look too thin and bright text look
too thick. Essentially it's a correction curve on the alpha channel that
depends on the luminance of the glyph being drawn.
As recommended in
https://github.com/ghostty-org/ghostty/pull/4927#issuecomment-2585003934,
adds a config option `maximize` for starting a window in a maximized
state in terms of window properties. Also adds a `toggle_maximize`
keybind to allow users to manually toggle this feature on and off.
It might make more sense to make this an optional config value so that
we don't toggle the state off if the WM already handles that for us, but
I'll let a reviewer decide.
Closes https://github.com/ghostty-org/ghostty/issues/4646
Previously, the logic navigated to the second-to-last tab instead of the
last tab due to an off-by-one error. This updates the implementation so
that the index calculation to accurately target the last tab. In the
`gotoLastTab` method there was a decrement in the number of max number
of tabs and another increment in the `goToTab` method to get the actual
tab index.
## Description
When pasting URLs from clipboard, the behavior varies based on the
source:
1. From browser address bar:
- Pasteboard types: ["public.utf8-plain-text", "NSStringPboardType"]
- Handled as plain text, resulting in correct full URL paste
2. From clipboard history tools, such as Raycast clipboard history:
- Pasteboard types include "public.url" and related URL types
- URL was being processed through NSURL, which only extracted the path
component
- This resulted in incomplete URLs
## Changes
- Modified `getOpinionatedStringContents()` to differentiate URL types:
- For file URLs (`file://`): preserve existing behavior, return path
only
- For web URLs (`http://`, `https://`): return full URL string via
`absoluteString`
- For non-URL content: maintain existing plain text handling
## Related Issues
Fixes#5026
@caarlos0 Could you please help check if this resolves the issue you
were encountering?
Fixes#5022
The CSI SGR sequence (CSI m) is unique in that its the only CSI sequence
that allows colons as delimiters between some parameters, and the colon
vs. semicolon changes the semantics of the parameters.
Previously, Ghostty assumed that an SGR sequence was either all colons
or all semicolons, and would change its behavior based on the first
delimiter it encountered.
This is incorrect. It is perfectly valid for an SGR sequence to have
both colons and semicolons as delimiters. For example, Kakoune sends the
following:
;4:3;38;2;175;175;215;58:2::190:80:70m
This is equivalent to:
- unset (0)
- curly underline (4:3)
- foreground color (38;2;175;175;215)
- underline color (58:2::190:80:70)
This commit changes the behavior of Ghostty to track the delimiter per
parameter, rather than per sequence. It also updates the SGR parser to
be more robust and handle the various edge cases that can occur. Tests
were added for the new cases.
Fixes#5022
The CSI SGR sequence (CSI m) is unique in that its the only CSI sequence
that allows colons as delimiters between some parameters, and the colon
vs. semicolon changes the semantics of the parameters.
Previously, Ghostty assumed that an SGR sequence was either all colons
or all semicolons, and would change its behavior based on the first
delimiter it encountered.
This is incorrect. It is perfectly valid for an SGR sequence to have
both colons and semicolons as delimiters. For example, Kakoune sends
the following:
;4:3;38;2;175;175;215;58:2::190:80:70m
This is equivalent to:
- unset (0)
- curly underline (4:3)
- foreground color (38;2;175;175;215)
- underline color (58:2::190:80:70)
This commit changes the behavior of Ghostty to track the delimiter per
parameter, rather than per sequence. It also updates the SGR parser to
be more robust and handle the various edge cases that can occur. Tests
were added for the new cases.
Previously, the logic navigated to the second-to-last tab instead of the
last tab due to an off-by-one error. This updates the implementation so
that the index calculation to accurately target the last tab.
In the `gotoLastTab` method there was a decrement in the number of max
number of tabs and another increment in the `goToTab` method to get the
actual tab index.
Fixes#4999
We need to set the level to popUpMenu so that we can move the window
offscreen and animate it over the main menu, but we must reset it back
to floating after the animation is complete so that other higher-level
windows can be shown on top of it such as IME windows.
Fixes#4999
We need to set the level to popUpMenu so that we can move the window
offscreen and animate it over the main menu, but we must reset it back
to floating after the animation is complete so that other higher-level
windows can be shown on top of it such as IME windows.