- Display keybindings grouped by their source table, with table name as prefix
- Sort default bindings before table bindings, maintaining visual hierarchy
- Support keybindings defined in key tables alongside default bindings
- Enable users to discover all available keybindings across the entire config
Fixes#10020
This improves parsing key tables so that the following edge cases are
now handled correctly, which were regressions from prior tip behavior:
- `/=action`
- `ctrl+/=action`
- `table//=action` (valid to bind `/` in a table)
- `table/a>//=action` (valid to bind a table with a sequence)
Fixes#10020
This improves parsing key tables so that the following edge cases
are now handled correctly, which were regressions from prior tip
behavior:
- `/=action`
- `ctrl+/=action`
- `table//=action` (valid to bind `/` in a table)
- `table/a>//=action` (valid to bind a table with a sequence)
Fixes#9961
This implements chained keybinds as described in #9961.
```
keybind = ctrl+shift+f=toggle_fullscreen
keybind = chain=toggle_window_decorations
```
These work with tables and sequences. For tables, the chain is unique
per table, so the following works:
```
keybind = foo/ctrl+shift+f=toggle_fullscreen
keybind = foo/chain=toggle_window_decorations
```
For sequences, it applies to the most recent sequence:
```
keybind = ctrl+b>f=toggle_fullscreen
keybind = chain=toggle_window_decorations
```
## TODO
Some limitations to resolve in future PRs (make an issue) or commits:
- [x] GTK: Global shortcuts cannot be chained: #10019
- [x] Inspector doesn't show chained keybinds
- [x] `+list-keybinds` doesn't show chains
**AI disclosure:** AI helped write tests, but everything else was
organic. AI did surprisingly bad at trying to implement this feature, so
I threw all of its work away! 😄
Our automatic shell integrations require certain resource paths to
exist. If they're missing, the launched shell could end up in an
inconsistent and unexpected state.
For example, we temporarily set ZDOTDIR to our zsh shell integration
directory and then restore it from our .zshenv file, but if that script
isn't available, the user's shell environment will be broken.
The actual runtime logic change was simple: each shell integration
routine attempts to open its expected resource path and skips automatic
shell integration upon failure. The more complex change was reworking
our unit tests to run in a temporary resources directory structure.
See: #9941
Our automatic shell integrations require certain resource paths to
exist. If they're missing, the launched shell could end up in an
inconsistent and unexpected state.
For example, we temporarily set ZDOTDIR to our zsh shell integration
directory and then restore it from our .zshenv file, but if that script
isn't available, the user's shell environment will be broken.
The actual runtime logic change was simple: each shell integration
routine attempts to open its expected resource path and skips automatic
shell integration upon failure. The more complex change was reworking
our unit tests to run in a temporary resources directory structure.
Two unrelated changes to polish key tables:
1. Key tables should be reset (deactivated) when teh config is reloaded.
This matches the behavior of key sequences as well, which are reset
on config reload.
2. A maximum number of active key tables is now enforced (8).
This prevents a misbehaving config from consuming too much memory
by activating too many key tables. This is an arbitrary limit we
can adjust later if needed.
Part of #9963
This adds a new special key `catch_all` that can be used in keybinding
definitions to match any key that is not explicitly bound. For example:
`keybind = catch_all=new_window` (chaos!).
`catch_all` can be used in combination with modifiers, so if you want to
catch any non-bound key with Ctrl held down, you can do:
`keybind = ctrl+catch_all=new_window`.
`catch_all` can also be used with trigger sequences, so you can do:
`keybind = ctrl+a>catch_all=new_window` to catch any key pressed after
`ctrl+a` that is not explicitly bound and make a new window!
And if you want to remove the catch all binding, it is like any other:
`keybind = catch_all=unbind`.
This prevents a crash in our renderer when it is larger.
I will pair this with apprt changes so that our mac app won't ever allow
a default window larger than the screen but we should be resilient at
the renderer level as well.
Fixes#9957
Our `Page.getRowAndCell` uses a _page-relative_ x/y coordinate system
and we were passing in viewport x/y. This has the possibility to leading
to all sorts of bugs, including the crash found in #9957 but also simply
reading the wrong cell even in single-page scenarios.
#1123 added a warning when the OpenGL version is too old, but
it is never used because GTK enforces the version set with
gl_area.setRequiredVersion() before prepareContext() is called:
we end up with a generic "failed to make GL context" error:
warning(gtk_ghostty_surface): failed to make GL context current: Unable to create a GL context
warning(gtk_ghostty_surface): this error is almost always due to a library, driver, or GTK issue
warning(gtk_ghostty_surface): this is a common cause of this issue: https://ghostty.org/docs/help/gtk-opengl-context
This patch removes the requirement at the GTK level and lets the ghostty
renderer check, now failing as follow:
info(opengl): loaded OpenGL 4.2
error(opengl): OpenGL version is too old. Ghostty requires OpenGL 4.3
warning(gtk_ghostty_surface): failed to initialize surface err=error.OpenGLOutdated
warning(gtk_ghostty_surface): surface failed to initialize err=error.SurfaceError
(Note that this does not render a ghostty window, unlike the previous
error which rendered the "Unable to acquire an OpenGL context for
rendering." view, so while the error itself is easier to understand it
might be harder to view)