The global config doesn’t necessarily reflect the correct
configuration to use - we should *always* use the current terminal
instance’s conf pointer.
* Move selection override modifier mask to the key_binding_set struct
* Always warn if XDG activation is unavailable, not just if
bell.urgent is set (we no longer have access to this information)
* Pass ‘bool presentation_timings’ as a parameter to wayl_init()
* Remove ‘presentation_timings’ member from the ‘terminal’ struct
Closes#932
Up until now, our Wayland seats have been tracking key bindings. This
makes sense, since the seat’s keymap determines how the key bindings
are resolved.
However, tying bindings to the seat/keymap alone isn’t enough, since
we also depend on the current configuration (i.e. user settings) when
resolving a key binding.
This means configurations that doesn’t match the wayland object’s
configuration, currently don’t resolve key bindings correctly. This
applies to footclients where the user has overridden key bindings on
the command line (e.g. --override key-bindings.foo=bar).
Thus, to correctly resolve key bindings, each set of key bindings must
be tied *both* to a seat/keymap, *and* a configuration.
This patch introduces a key-binding manager, with an API to
add/remove/lookup, and load/unload keymaps from sets of key bindings.
In the API, sets are tied to a seat and terminal instance, since this
makes the most sense (we need to instantiate, or incref a set whenever
a new terminal instance is created). Internally, the set is tied to a
seat and the terminal’s configuration.
Sets are *added* when a new seat is added, and when a new terminal
instance is created. Since there can only be one instance of each
seat, sets are always removed when a seat is removed.
Terminals on the other hand can re-use the same configuration (and
typically do). Thus, sets ref-count the configuration. In other words,
when instantiating a new terminal, we may not have to instantiate a
new set of key bindings, but can often be incref:ed instead.
Whenever the keymap changes on a seat, all key bindings sets
associated with that seat reloads (re-resolves) their key bindings.
Closes#931
Search mode and ‘flash’ (OSC-555) both achieves similar visual
effects: flash tints the entire window yellow, and search mode dims
it (except the search match).
But, they do so in completely different ways. Search mode is detected
in render_cell(), and the colors are then dimmed there.
Flash is implemented by blending a yellow, semi-transparent color on
top of the rendered grid.
This patch replaces those two implementations with a single one. We
add a new sub-surface, called the ‘overlay’. In normal mode, it’s
unmapped.
When either search mode, or flash, is enabled, we enable it, and
fill it with a semi-transparent color. Yellow for ‘flash’, and
“black” (i.e. no color) for search mode.
The compositor then blends it with the grid. Hopefully on the GPU,
meaning it’ll be faster than if we blend in software.
There are more performance benefits however. By using a separate
surface, we can do much better damage tracking.
The normal grid rendering code no longer have to care about neither
search mode, nor flash. Thus, we get rid of a couple of ‘if’
statements in render_cell(), which is nice. But more importantly, we
can drop full grid repaints in a couple of circumstances:
* Entering/exiting search mode
* Every frame while flash is active
Now, when rendering the search mode overlay, we do want to do some
damage tracking, also of the overlay.
This, since search mode doesn’t dim the *entire* window. The search
match is *not* dimmed. This is implemented by punching a hole in the
overlay sub-surface. That is, we make part of it *fully*
transparent. The basic idea is to set a clip region that excludes the
search match, and then dim the rest of the overlay.
It’s slightly more complicated than that however, if we want to reuse
the last frame’s overlay buffer (i.e we don’t want to re-render
the *entire* overlay every frame).
In short, we need to:
* Clear (punch hole) in areas that are part of this frame’s search
match, but not the last frame’s (since those parts are _already_
cleared).
* Dim the areas that were part of the last frame’s search match, but
aren’t anymore (the rest of the overlay should already be dimmed).
To do this, we save the last frame’s “holes” (as a pixman
region). Then, when rendering the next frame, we first calculate the
new frame’s “holes” region.
The region to clear is “this frame’s holes minus last frame’s holes”
The region to dim is “last frame’s holes minus this frames holes”.
Finally, we compute the bounding box of all modified cells by taking
the union of the two diff regions mentioned above. This allows us to
limit the buffer damage sent to the compositor.
We have a number of sub-surfaces for which we are *not* interrested in
pointer (or touch) input.
Up until now, we’ve manually dealt with these, by recognizing these
surfaces in all pointer events, and ignoring them.
But, lo and behold, there are better ways of doing this. By clearing
the subsurface’s input region, the compositor will do this for us -
when a pointer is outside a surface’s input region, the event is
passed to the next surface underneath it.
This is exactly what we want! Do this for all subsurfaces, *except*
the CSDs.
With this, it is now possible to map key combos to custom escapes. The
new bindings are defined in a new section, “text-bindings”, on the
form “string=key combo”.
The string can consist of printable characters, or \xNN style hex
digits:
[text-bindings]
abcd = Control+a
\x1b[A = Control+b Control+c Control+d # map ctrl+b/c/d to UP
Fcft no longer uses wchar_t, but plain uint32_t to represent
codepoints.
Since we do a fair amount of string operations in foot, it still makes
sense to use something that actually _is_ a string (or character),
rather than an array of uint32_t.
For this reason, we switch out all wchar_t usage in foot to
char32_t. We also verify, at compile-time, that char32_t used
UTF-32 (which is what fcft expects).
Unfortunately, there are no string functions for char32_t. To avoid
having to re-implement all wcs*() functions, we add a small wrapper
layer of c32*() functions.
These wrapper functions take char32_t arguments, but then simply call
the corresponding wcs*() function.
For this to work, wcs*() must _also_ be UTF-32 compatible. We can
check for the presence of the __STDC_ISO_10646__ macro. If set,
wchar_t is at least 4 bytes and its internal representation is UTF-32.
FreeBSD does *not* define this macro, because its internal wchar_t
representation depends on the current locale. It _does_ use UTF-32
_if_ the current locale is UTF-8.
Since foot enforces UTF-8, we simply need to check if __FreeBSD__ is
defined.
Other fcft API changes:
* fcft_glyph_rasterize() -> fcft_codepoint_rasterize()
* font.space_advance has been removed
* ‘tags’ have been removed from fcft_grapheme_rasterize()
* ‘fcft_log_init()’ removed
* ‘fcft_init()’ and ‘fcft_fini()’ must be explicitly called
POSIX.1-2008 has marked gettimeofday(2) as obsolete, recommending the
use of clock_gettime(2) instead.
CLOCK_MONOTONIC has been used instead of CLOCK_REALTIME because it is
unaffected by manual changes in the system clock. This makes it better
for our purposes, namely, measuring the difference between two points in
time.
tv_sec has been casted to long in most places since POSIX does not
define the actual type of time_t.
Our internal binding handling cares about a different set of
modifiers, compared to the kitty keyboard protocol.
To handle this, get_current_modifiers() has been modified, to no
longer strip the “unsignificant” modifiers. This is now up to the
caller to do.
To help, we keep two masks (for significant modifiers) in the seat
struct; one for our internal binding handling (and the legacy keyboard
protocol), and one for the kitty keyboard protocol. These two masks
are updated when the seat’s keymap is updated/changed.
When emitting an escape sequence for a printable character, with
modifiers (e.g. ctrl+a), use the key’s base symbol instead of
“lowering” it.
This means we now handle e.g. ctrl+2 and ctrl+shift+2, with Swedish
layout.
There’s a twist however. We *only* use the base symbol if the
modifiers that is used to “generate” the symbol are “significant”.
Significant modifiers are, in this context, modifiers we can encode in
the kitty escape sequences.
In the Swedish layout, pressing AltGr+2 results in ‘@’. AltGr cannot
be encoded in the kitty protocol. If we were to use the base symbol,
AltGr+Alt+2 would result in exactly the same escape sequence as Alt+2.
This is an application of the xdg activation protocol that will allow
compositors to associate new foot toplevels with the command that
launched them.
footclient receives an activation token from the launcher which the
compositor can use to track application startup. It passes the token
to the foot server, which then activates the new window with the token
to complete the startup sequence.
We now emit button 6/7 events (when the client application grabs the
mouse). This buttons map to mouse wheel horizontal scroll events. Or, left/right
tilting, if you like.
Wayland report these as ‘axis’ events (just like regular scroll wheel events),
and thus we need to translate those scroll events to button events.
libinput does not define any mouse buttons for wheel tilts, so we add our own
defitions. These are added last in the BTN_* range, just before the BTN_JOYSTICK
events.
We still use the primary font, but use a custom size, based on the
title bar’s height.
This fixes an issue where the window title could be way too small, or
way too big. And changed size when the terminal font size was changed.
The configure event asks the client to change its decoration
mode. The configured state should not be applied immediately.
Clients must send an ack_configure in response to this event.
See xdg_surface.configure and xdg_surface.ack_configure for
details.
In particular, ”the configured state should *not* be applied
immediately”.
Instead, treat CSD/SSD changes like all other window dimension related
changes: store the to-be mode in win->configure, and apply it in the
surface configure event.
This fixes an issue where foot incorrectly resized the window when the
server switched between CSD/SSD at run-time.
Only enable XDG activation when compiling against wayland-protocols
1.21. Older versions don’t have this protocol.
When available, define HAVE_XDG_ACTIVATION.
Make all usages of xdg_activation_v1 and xdg_activation_token_v1
conditional.
This ensures different seat’s don’t step on each others IME pre-edit
state.
It also removes most dependencies on having a valid term pointer for
many IME operations.
We’re still not all the way, since we support disabling IME with a
private mode, which is per terminal, not seat.
Thus, we still require the seat to have keyboard focus on one of our
windows.
Closes#324. But note that *rendering* of multiple seat’s IME pre-edit
strings is still broken.
Fixes log spamming in Sway:
00:54:07.780 [DEBUG] [wlr] [types/wlr_text_input_v3.c:181] Text input commit received without focus
00:54:07.780 [INFO] [sway/input/text_input.c:127] Inactive text input tried to commit an update
Closes#384
By default, the URL isn’t shown on the jump-label. For auto-detect
URLs, doing so is virtually always useless, as the URL is already
visible in the grid.
For OSC-8 URLs however, the URL is often _not_ visible in the
grid. Many times, seeing the URL is still not needed (if you’re doing
‘ls --hyperlink’, you already know what the URIs are).
But it is still useful to have a way to show the URLs.
This patch adds a new key binding action that can be used in url-mode
to toggle the URL on and off in the jump label.
It is bound to ctrl+t by default.
Up until now, the various key binding modes (“normal”, “search” and
“url”) have used their own struct definitions for their key bindings.
The only reason for this was to have a properly typed “action” (using
the appropriate “action” enum).
This caused lots of duplicated code. This patch refactors this to use
a single struct definition for the “unparsed” key bindings handled by
the configuration, and another single definition for “parsed” bindings
used while handling input.
This allows us to implement configuration parsing, keymap translation
and so on using one set of functions, regardless of key binding mode.
This works just like show-urls-launch, except that instead of opening
the URL (typically using xdg-open), it is placed in the clipboard when
activated.
Instead of disabling content centering, delay the TIOCSWINSZ (a.k.a
delay sending the new dimensions to the client) by a small amount
while doing an interactive resize.
Non-interactive resizes are still immediate.
For now, force a resize when the user stops the interactive
resize. This ensures the client application receives the new
dimensions immediately.
It still works without the last, forced, resize, but there typically
be a small delay until the client application receives the final
dimensions.
Closes#301Closes#283
Store a list of currently pressed buttons, and which surface they
belong to (i.e. which surface that received the press).
Then, in motion events (with a button pressed, aka drag operations),
send the event to the “original” surface (that received the press).
Also send release events to the originating surface.
This means a surface receiving a press will always receive a
corresponding release. And no one will receive a release event without
a corresponding press event.
Motion events with a button pressed will *always* use the *first*
button that was pressed. I.e. if you press a button, start dragging,
and then press another button, we keep generating motion events for
the *first* button.