6378 Commits

Author SHA1 Message Date
Mitchell Hashimoto
99db6b59be Add config color palette C bindings (#7195)
C bindings to expose the color palette to Swift for macOS. Returns the
full 256 colors from the current color scheme. After fetching the
palette with `ghostty_config_get`, you can access the desired color by
its index in the list.

### Usage

Here is one way to get the palette in Swift.

```swift
import GhosttyKit

private(set) var config: ghostty_config_t? = nil {
    didSet {
        // Free the old value whenever we change
        guard let old = oldValue else { return }
        ghostty_config_free(old)
    }
}

var paletteColors: [Color] {
    var paletteList: ghostty_config_palette_s = .init()
    let key = "palette"
    
    if (!ghostty_config_get(config, &paletteList, key, UInt(key.count))) {
        return []
    }
    
    var colors: [Color] = []
    let mirror = Mirror(reflecting: paletteList.colors)
    
    for (_, element) in mirror.children {
        if let color = element as? ghostty_config_color_s {
            colors.append(Color(
                red: Double(color.r) / 255,
                green: Double(color.g) / 255,
                blue: Double(color.b) / 255
            ))
        }
    }
    
    print("Palette Colors: ", colors)
    return colors
}
```
Result (GruvboxDarkHard theme)
![CleanShot 2025-04-25 at 14 21
39](https://github.com/user-attachments/assets/a282fd8d-3e5e-4281-819c-dff00b84318f)
2025-04-27 07:14:26 -07:00
rhodes-b
bbbe81efc5 z2d context no longer has err return 2025-04-26 23:51:04 -05:00
Friedrich Stoltzfus
77f5fc34f1 Add config color palette C bindings
C bindings to expose the color palette to Swift for macOS.
2025-04-25 14:10:35 -04:00
Jeffrey C. Ollie
75cc4b29fd gtk: require blueprint-compiler 0.16 for building
Changes:

1. Require `blueprint-compiler` 0.16.0 (or newer) for building from
   a git checkout. With #6822 distributions that can't meet that
   requirement can use generated source tarballs to build.
2. Remove all `.ui` files as they are unnecessary.
3. Simplify the `Builder` interface since raw `.ui` files are no
   longer used.
4. Removed build-time check of raw `.ui` files.
2025-04-23 10:35:10 -05:00
Jeffrey C. Ollie
6bd9e35cd6 snap: build from source tarball 2025-04-23 08:10:01 -05:00
Leorize
ebc169dbaf Fix flatpak packaging to a working state
This should make testing Flatpak builds a lot easier.

To build, enter `flatpak/` directory and run:

    flatpak-builder --repo=repo builddir com.mitchellh.ghostty.yml

alternatively, using org.flatpak.Builder flatpak:

    flatpak run -p org.flatpak.Builder \
      --repo=repo \
      builddir \
      com.mitchellh.ghostty.yml

The resulting flatpak can be installed using

    flatpak install ./repo com.mitchellh.ghostty

Credit of AppStream metadata goes to @yorickpeterse.
2025-04-22 10:56:09 -07:00
Mitchell Hashimoto
17b0bf585d apprt/gtk: add menu to new tab button to create splits (#7137)
Closes: https://github.com/ghostty-org/ghostty/discussions/6828
2025-04-22 09:07:10 -07:00
Mitchell Hashimoto
74e1c47623 macOS: Command Palette (#7153)
This introduces a command palette (inspired by @pluiedev's work in
#5681, but not using it as a base) for macOS.

The command palette is available in the `View` menu and also bindable
via `toggle_command_palette`, default binding is `cmd+shift+p` to match
VSCode.

The commands in the command palette must map to a _bindable_ action,
though they may not have an associated keybinding. This means that any
new binding actions we add in the future can be represented here and
also makes it easy in the future to add configuration to add new custom
entries to the command palette. For this initial PR, the available
commands are hardcoded (`src/input/commands.zig`).

I've noticed in other programs (VSCode, Zed), the command palette
contains pretty much _all available actions_ even if they're basically
useless in the context of a command palette. For example, Zed has the
"toggle command palette" action in the command palette and it... does
nothing (it probably should hide the palette). I followed @pluiedev's
lead and made this subjective in this PR but I wonder if we should
actually force all binding actions to be available.

There are various other improvements I'd like to make but omitted from
this PR for the sake of limiting scope:

* Instead of an entry with no matches doing nothing, we can allow users
to manually input _any_ configurable binding.
* Localization, since macOS doesn't have any yet. But for Linux when we
port this we probably have to change our strings extraction.

## Demo


https://github.com/user-attachments/assets/a2155cfb-d86b-4c1a-82b5-74ba927e4d69
2025-04-22 08:52:27 -07:00
Mitchell Hashimoto
3e5fe5de9a move command filtering into apprt 2025-04-22 08:33:32 -07:00
Mitchell Hashimoto
28404e946b order commands alphabetically and preserve capitalization 2025-04-21 17:13:12 -07:00
Mitchell Hashimoto
e5e9d43d52 renderer/opengl: reduce flickering/stretching on resize
Fixes #2446

Two separate issues:

  1. Ensure that our screen size matches the viewport size when
     drawFrame is called. By the time drawFrame is called, GTK will have
     updated the OpenGL context, but our deferred screen size may still
     be incorrect since we wait for the pty to update the screen size.

  2. Do not clear our cells buffer when the screen size changes, instead
     changing to a mechanism that only clears the buffers when we have
     over 50% wasted space.

Co-authored-by: Andrew de los Reyes <adlr@rivosinc.com>
2025-04-21 14:02:55 -07:00
Tristan Partin
1c62ddffc4 apprt/gtk: add menu to new tab button to create splits
Closes: https://github.com/ghostty-org/ghostty/discussions/6828
Signed-off-by: Tristan Partin <tristan@partin.io>
2025-04-21 13:01:37 -05:00
Mitchell Hashimoto
a732bb272d fix CI 2025-04-21 10:54:23 -07:00
Mitchell Hashimoto
6dad763e69 input: omit commands that are platform-specific 2025-04-21 10:20:32 -07:00
Tristan Partin
f2fa47bca7 apprt/gtk: fix typo
I had a copy-paste error when I used right instead of up.

Signed-off-by: Tristan Partin <tristan@partin.io>
2025-04-21 12:12:54 -05:00
Mitchell Hashimoto
6d2685b5a2 add toggle command palette binding 2025-04-21 10:05:30 -07:00
Mitchell Hashimoto
8615dfb73d libghostty: add API for getting commands 2025-04-21 08:32:05 -07:00
Mitchell Hashimoto
a34134e643 input: defind Command struct and default commands 2025-04-21 08:32:05 -07:00
Kat
160b26708c Remove note about default from bell-features→system's description. 2025-04-21 03:24:05 +00:00
Mitchell Hashimoto
31b2ac4b79 macOS: Do not send control characters as UTF8 keyboard text
Fixes a regression where `ctrl+enter` was not encoding properly since
our input stack changes.
2025-04-19 06:54:36 -07:00
Mitchell Hashimoto
18d6faf597 macOS: translation mods should never have "control"
This also lets us get rid of our `C-/` special handling to prevent a
system beep.
2025-04-18 15:10:57 -07:00
Mitchell Hashimoto
65356c25da macOS/libghostty: rework keyboard input handling (#7121)
This is a large refactor of the keyboard input handling code in
libghostty and macOS. Previously, libghostty did a lot of things that
felt out of scope or was repeated work due to lacking context. For
example, libghostty would do full key translation from key event to
character (including unshifted translation) as well as managing dead key
states and setting the proper preedit text.

This is all information the apprt can and should have on its own.
NSEvent on macOS already provides us with all of this information,
there's no need to redo the work. The reason we did in the first place
is mostly historical: libghostty powered our initial macOS port years
ago when we didn't have an AppKit runtime yet.

This cruft has already practically been the source of numerous issues,
e.g.
https://github.com/ghostty-org/ghostty/issues/5558, but many other hacks
along the way, too.

This commit pushes all preedit (e.g. dead key) handling and key
translation
including unshifted keys up into the caller of libghostty.

Besides code cleanup, a practical benefit of this is that key event
handling on macOS is now about 10x faster on average. That's because
we're avoiding repeated key translations as well as other unnecessary
work. This should have a meaningful impact on input latency but I didn't
measure the full end-to-end latency.

A scarier part of this commit is that key handling is not well tested
since its a GUI component. I suspect we'll have some fallout for certain
keyboard layouts or input methods, but I did my best to run through
everything I could think of.

This also fixes one bug where preedit state didn't properly clear when
changing keyboard layouts. This now does and matches the behavior
of native apps like TextEdit and Terminal.app
2025-04-18 12:06:32 -07:00
Tristan Partin
85268d4f82 apprt/gtk: refactor action callbacks to reduce code duplication (#7126)
It was getting very monotonous reading the code.
2025-04-18 13:11:12 -05:00
Tristan Partin
793c727986 apprt/gtk: refactor action callbacks to reduce code duplication
It was getting very monotonous reading the code.

Signed-off-by: Tristan Partin <tristan@partin.io>
2025-04-18 12:54:36 -05:00
phanium
9bab900c75 vim: fix syntax highlight on scratch buffer 2025-04-18 21:50:24 +08:00
Mitchell Hashimoto
b3cb38c3fa macOS/libghostty: rework keyboard input handling
This is a large refactor of the keyboard input handling code in
libghostty and macOS. Previously, libghostty did a lot of things that
felt out of scope or was repeated work due to lacking context. For
example, libghostty would do full key translation from key event to
character (including unshifted translation) as well as managing dead key
states and setting the proper preedit text.

This is all information the apprt can and should have on its own.
NSEvent on macOS already provides us with all of this information,
there's no need to redo the work. The reason we did in the first place
is mostly historical: libghostty powered our initial macOS port years
ago when we didn't have an AppKit runtime yet.

This cruft has already practically been the source of numerous issues, e.g.
#5558, but many other hacks along the way, too.

This commit pushes all preedit (e.g. dead key) handling and key translation
including unshifted keys up into the caller of libghostty.

Besides code cleanup, a practical benefit of this is that key event
handling on macOS is now about 10x faster on average. That's because
we're avoiding repeated key translations as well as other unnecessary
work. This should have a meaningful impact on input latency but I didn't
measure the full end-to-end latency.

A scarier part of this commit is that key handling is not well tested
since its a GUI component. I suspect we'll have some fallout for certain
keyboard layouts or input methods, but I did my best to run through
everything I could think of.
2025-04-17 14:24:12 -07:00
Mitchell Hashimoto
cc690eddb5 macOS: Implement basic bell features (no sound)
Fixes #7099

This adds basic bell features to macOS to conceptually match the GTK
implementation. When a bell is triggered, macOS will do the following:

  1. Bounce the dock icon once, if the app isn't already in focus.
  2. Add a bell emoji (🔔) to the title of the surface that triggered
     the bell. This emoji will be removed after the surface is focused
     or a keyboard event if the surface is already focused. This
     behavior matches iTerm2.

This doesn't add an icon badge because macOS's dockTitle.badgeLabel API
wasn't doing anything for me and I wasn't able to fully figure out
why...
2025-04-15 10:41:15 -07:00
Mitchell Hashimoto
da6b478fbe terminal: clear correct row on index operation in certain edge cases
Fixes #7066

This fixes an issue where under certain conditions (expanded below), we
would not clear the correct row, leading to the screen having duplicate
data.

This was triggered by a page state of the following:

```
      +----------+ = PAGE 0
  ... :          :
 4305 |1ABCD00000|
 4306 |2EFGH00000|
      :^         : = PIN 0
     +-------------+ ACTIVE
 4307 |3IJKL00000| | 0
      +----------+ :
      +----------+ : = PAGE 1
    0 |          | | 1
    1 |          | | 2
      +----------+ :
     +-------------+
```

Namely, the cursor had to NOT be on the last row of the first page,
but somewhere on the first page. Then, when an `index` (LF) operation
was performed the result would look like this:

```
      +----------+ = PAGE 0
  ... :          :
 4305 |1ABCD00000|
 4306 |2EFGH00000|
     +-------------+ ACTIVE
 4307 |3IJKL00000| | 0
      :^         : : = PIN 0
      +----------+ :
      +----------+ : = PAGE 1
    0 |3IJKL00000| | 1
    1 |          | | 2
      +----------+ :
     +-------------+
```

The `3IJKL` line was duplicated. What was happening here is that we
performed the index operation correctly but failed to clear the cursor
line as expected.

This is because we were always clearing the first row in the page
instead of the row of the cursor.

Test added.
2025-04-14 15:54:00 -07:00
Mitchell Hashimoto
c23b389cf1 gtk: implement bell (#7087)
This PR implements a more lightweight alternative to #5326 that contains
features that I personally think Just Make Sense for the bell.

No configs, no GStreamer stuff, just sane defaults to get us started.
2025-04-14 11:19:19 -07:00
Leah Amelia Chen
3a973c692a gtk(bell): add bell-features config option
Co-authored-by: Jeffrey C. Ollie <jeff@ocjtech.us>
2025-04-15 00:18:05 +08:00
Leah Amelia Chen
abd7d9202b gtk(bell): mark tab as needing attention on bell 2025-04-14 23:44:13 +08:00
Leah Amelia Chen
10a591fba2 gtk(bell): use gdk.Surface.beep for bell
Co-authored-by: Jeffrey C. Ollie <jeff@ocjtech.us>
2025-04-14 23:44:13 +08:00
Leah Amelia Chen
a0760cabd6 gtk: implement bell
Co-authored-by: Jeffrey C. Ollie <jeff@ocjtech.us>
2025-04-14 23:44:13 +08:00
Mitchell Hashimoto
6d3f97ec1e Mouse drag while clicked should cancel any mouse link actions
Fixes #7077

This follows pretty standard behavior across native or popular applications
on both platforms macOS and Linux. The basic behavior is that if you
do a mouse down event and then drag the mouse beyond the current
character, then any mouse up actions are canceled (beyond emiting the
event itself).

This fixes a specific scenario where you could do the following:

  1. Click anywhere (mouse down)
  2. Drag over a valid link
  3. Press command/control (to activate the link)
  4. Release the mouse button (mouse up)
  5. The link is triggered

Now, step 3 and step 5 do not happen. Links are not even highlighted in
this scenario. This matches iTerm2 on macOS which has a similar
command-to-activate-links behavior.
2025-04-13 14:56:40 -07:00
Andrej Daskalov
dcc2e9eaf8 Merge branch 'main' into mk-localization 2025-04-11 21:47:07 +02:00
Francesc Arpi Roca
d749e1b87e i18n: fix the "deny" catalan translation 2025-04-11 10:20:53 -07:00
Francesc Arpi Roca
a092d7ae42 i18n: add catalan translations 2025-04-11 10:20:44 -07:00
g
c19f2aa1bc Add pt-BR translations to ghostty 2025-04-11 10:12:06 -07:00
Mitchell Hashimoto
9751f43529 Add Spanish translations (419 = Latin America) (#6940)
Hi!
I have followed the instructions and added translations for Spanish,
Country Latin America 419 according to
[this](https://localizely.com/locale-code/es-419/) and other online
sources.
In the provided links there was no references to 419, but I created it
via the suggested command:
`msginit -i po/com.mitchellh.ghostty.pot -l es_419.UTF-8 -o
"po/es_419.UTF-8.po" `
Glad to be able to contribute to this excellent product!
Cheers!
2025-04-11 10:11:26 -07:00
MiguelElGallo
a9f9abd615 add Spanish (Latin America) locale support 2025-04-11 10:08:44 -07:00
Emir SARI
913c6dc7df feat: Add Turkish translations 2025-04-11 09:57:19 -07:00
Nico Geesink
e52aad5dea Add nl_NL (Dutch) translations 2025-04-11 09:50:44 -07:00
Mitchell Hashimoto
52ac670913 CODEOWNERS 2025-04-11 09:47:11 -07:00
blackzeshi
2b0a81d982 Merge branch 'main' into add_russian 2025-04-11 09:45:55 -07:00
blackzeshi
df5dd1858a add russian translation 2025-04-11 09:45:37 -07:00
Kirwiisp
e2a8a3243c i18n: Add French translation 2025-04-11 09:41:49 -07:00
Lon Sagisawa
20ef2150de i18n: Add Japanese translations 2025-04-11 09:38:37 -07:00
halosatrio
1222e80eb1 i18n: add id_ID code locale 2025-04-11 09:26:00 -07:00
Mitchell Hashimoto
d7f75b348d config: allow commands to specify whether they shell expand or not (#7044)
Fixes #7032 

This introduces a syntax for `command` and `initial-command` that allows
the user to specify whether it should be run via `/bin/sh -c` or not.
The syntax is a prefix `direct:` or `shell:` prior to the command, with
no prefix implying a default behavior as documented.

Previously, we unconditionally ran commands via `/bin/sh -c`, primarily
to avoid having to do any shell expansion ourselves. We also leaned on
it as a crutch for PATH-expansion but this is an easy problem compared
to shell expansion.

For the principle of least surprise, this worked well for configurations
specified via the config file, and is still the default. However, these
configurations are also set via the `-e` special flag to the CLI, and it
is very much not the principle of least surprise to have the command run
via `/bin/sh -c` in that scenario since a shell has already expanded all
the arguments and given them to us in a nice separated format. But we
had no way to toggle this behavior.

This commit introduces the ability to do this, and changes the defaults
so that `-e` doesn't shell expand. Further, we also do PATH lookups
ourselves for the non-shell expanded case because thats easy (using
execvpe style extensions but implemented as part of the Zig stdlib). We
don't do path expansion (e.g. `~/`) because thats a shell expansion.

So to be clear, there are no two polar opposite behavioes here with
clear semantics:

1. Direct commands are passed to `execvpe` directly, space separated.
This will not handle quoted strings, environment variables, path
expansion (e.g. `~/`), command expansion (e.g. `$()`), etc.

2. Shell commands are passed to `/bin/sh -c` and will be shell expanded
as per the shell's rules. This will handle everything that `sh`
supports.

In doing this work, I also stumbled upon a variety of smaller
improvements that could be made:

- A number of allocations have been removed from the startup path that
only existed to add a null terminator to various strings. We now have
null terminators from the beginning since we are almost always on a
system that's going to need it anyways.

- For bash shell integration, we no longer wrap the new bash command in
a shell since we've formed a full parsed command line.

- The process of creating the command to execute by termio is now unit
tested, so we can test the various complex cases particularly on macOS
of wrapping commands in the login command.

- `xdg-terminal-exec` on Linux uses the `direct:` method by default
since it is also assumed to be executed via a shell environment.
2025-04-10 16:32:18 -04:00
Mitchell Hashimoto
d4a5e5f88e elvish: use kitty-shell-cwd:// to report pwd (#7033)
OSC 7's standard body is a percent-encoded file:// URL. There isn't an
easy way for us to percent-encode the path ($pwd) component here without
implementing a custom function.

Instead, switch to the kitty-shell-cwd:// scheme, which Kitty introduced
to ease this implementation challenge in shell scripts. It accepts the
path string verbatim, without an encoding.

In Ghostty, we accept both the file:// and kitty-shell-cwd:// schemes,
and we attempt to URI-decode them both, so in practice this is more
about the "correctness" of this protocol than a functional change. It's
also possible we might decide to treat these schemes differently in the
runtime, like Kitty does.

Also, fix the `platform:hostname` function call syntax.
2025-04-10 16:19:26 -04:00