Fixes#5257
Specify environment variables to pass to commands launched in a terminal
surface. The format is `env=KEY=VALUE`.
`env = foo=bar`
`env = bar=baz`
Setting `env` to an empty string will reset the entire map to default
(empty).
`env =`
Setting a key to an empty string will remove that particular key and
corresponding value from the map.
`env = foo=bar`
`env = foo=`
will result in `foo` not being passed to the launched commands.
Setting a key multiple times will overwrite previous entries.
`env = foo=bar`
`env = foo=baz`
will result in `foo=baz` being passed to the launched commands.
These environment variables _will not_ be passed to commands run by Ghostty
for other purposes, like `open` or `xdg-open` used to open URLs in your
browser.
Finishes #378
Supercedes #4159
This adds a new enum value for `macos-non-native-fullscreen`:
`padded-notch`. This value will add padding to the top of the window to
account for the notch on applicable devices while still hiding the
menu.
This value is preferred over "visible-menu" by some people because for
screens without a notch, the window will take up the full height.
The plan in the future is that we may color the padded area when a notch
is present. In this commit it appears as transparent.
`WINDOWID` is the conventional environment variable for scripts that
want to know the X11 window ID of the terminal, so that it may call
tools like `xprop` or `xdotool`. We already know the window ID for
window protocol handling, so we might as well throw this in for
convenience.
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
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
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)
Fixes#3648
The confirm-close-surface configuration can now be set to always
ensuring a confirmation dialog is shown before closing a surface, even
if shell integration indicates no running processes.
When outside the viewport, other actions such as scrolling might be happening, and doing an early return when clearing hyperlinks prevents scrolling upwards.
We do not early return so we can process scrolling when it happens.
A common issue for US-centric users of a terminal is that the "option"
key on macOS is not treated as the "alt" key in the terminal.
## Background
macOS does not have an "alt" key, but instead has an "option" key. The "option"
key is used for a variety of purposes, but the troublesome behavior for some
(and expected/desired behavior for others) is that it is used to input special
characters.
For example, on a US standard layout, `option-b` inputs `∫`. This is not
a typically desired character when using a terminal and most users will
instead expect that `option-b` maps to `alt-b` for keybinding purposes
with whatever shell, TUI, editor, etc. they're using.
On non-US layouts, the "option" key is a critical modifier key for
inputting certain characters in the same way "shift" is a critical
modifier key for inputting certain characters on US layouts.
We previously tried to change the default for `macos-option-as-alt`
to `left` (so that the left option key behaves as alt) because I had the
wrong assumption that international users always used the right option
key with terminals or were used to this. But very quickly beta users
with different layouts (such as German, I believe) noted that this is
not the case and broke their idiomatic input behavior. This behavior was
therefore reverted.
## Solution
This confusing behavior happened frequently enough that I decided to
implement the more complex behavior in this commit. The new behavior is
that when a US layout is active, `macos-option-as-alt` defaults to true
if it is unset. When a non-US layout is active, `macos-option-as-alt`
defaults to false if it is unset. This happens live as users change
their keyboard layout.
**An important goal of Ghostty is to have zero-config defaults** that
satisfy the majority of users. Fiddling with configurations is -- for
most -- an annoying task and software that works well enough out of the
box is delightful. Based on surveying beta users, I believe this commit
will result in less configuration for the majority of users.
## Other Terminals
This behavior is unique amongst terminals as far as I know.
Terminal.app, Kitty, iTerm2, Alacritty (I stopped checking there) all
default to the default macOS behavior (option is option and special
characters are inputted).
All of the aforementioned terminals have a setting to change this
behavior, identical to Ghostty (or, Ghostty identical to them perhaps
since they all predate Ghostty).
I couldn't find any history where users requested the behavior of
defaulting this to something else for US based keyboards. That's
interesting since this has come up so frequently during the Ghostty
beta!
The prior light/dark mode awareness work works on surface-level APIs. As
a result, configurations used at the app-level (such as split divider
colors, inactive split opacity, etc.) are not aware of the current theme
configurations and default to the "light" theme.
This commit adds APIs to specify app-level color scheme changes. This
changes the configuration for the app and sets the default conditional
state to use that new theme. This latter point makes it so that future
surfaces use the correct theme on load rather than requiring some apprt
event loop ticks. Some users have already reported a short "flicker" to
load the correct theme, so this should help alleviate that.
Related #2755
From the mode 2031 spec[1]:
> Send CSI ? 2031 h to the terminal to enable unsolicited DSR (device status
> report) messages for color palette updates and CSI ? 2031 l respectively to
> disable it again.
>
> The sent out DSR looks equivalent to the already above mentioned. This
> notification is not just sent when dark/light mode has been changed by the
> operating system / desktop, but also if the user explicitly changed color
> scheme, e.g. by configuration.
My reading of this paired with the original discussion is that this is
meant to be sent out for anything that could possibly change terminal
colors.
Previous to this commit, we only sent out the DSR when the actual system
light/dark mode changed. This commit changes it to send out the DSR on
any operation that _may_ change the terminal colors.
[1]: https://contour-terminal.org/vt-extensions/color-palette-update-notifications/#example-source-code