Before this patch, only the currently “selected” match was
highlighted (by having the “selected” attribute, and by *not* dimming
it, like the rest of the grid during a scrollback search).
With this patch, we now highlight matches within the viewport. While
searching, only the “primary” match is searched-for, and tracked.
Then, when rendering a frame, we find all “secondary” matches as
well. “holes” are added to the search-mode overlay by the means of an
search-match iterator.
The iterator’s text matching logic is *very* similar to what we do
when the search criteria has been updated, and we re-search the
scrollback. It should be possible to refactor this, and share code.
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.
This allows a caller to return a buffer (obtained with
shm_get_buffer()) to the pool,
The buffer must not have been used. I.e. it must not have been
attached and committed to a wayland surface.
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.
When the compositor is asking us to resize ourselves, take
our (visible) CSD borders into account. This is similar to how we
already take the titlebar size into account.
This fixes an issue where the window size “jumps” when the user starts
an interactive resize, when csd.border-width > 0.
This as been observed in GNOME.
The old, complex, way of using a dynamic list to hold each path
component made _some_ sense before, when we needed to support both
~/.config/foot.ini and ~/.config/foot/foot.ini.
But now, it just over complicates things.
When this option is used, the child process in the new terminal
instance will inherit its environment from the footclient process,
instead of the foot server’s.
Implemented by sending (yet another) dynamic string list as part of
the client -> server setup packet. When the new option is *not* used,
the setup packet is now 2 bytes larger than before.
On the server side, the slave process now uses execvpe() instead of
execvp(). There’s plumbing to propagate a new ‘envp’ argument from
term_init() all the way down to slave_exec(). If ‘envp’ is NULL, we
use ‘environ’ instead (thus matching the old behavior of execvp()).
Closes#1004
Before this, foot always emitted a CSI if _any_ modifier was
active. XTerm doesn’t behave quite like this. Instead, it appears to
special-case shift somewhat:
If the generated symbol (e.g ‘A’) is the upper case version of the
pressed key’s base symbol (‘a’), and is in the range a-z, emit a CSI.
If not emit a plain symbol:
Examples (Swedish layout):
* shift-a (generated symbol is ‘A’) emits a CSI
* shift-, (generated symbol is ‘;’) emits ‘;’
* shift-alt-, (generated symbol is ‘;’) emits a CSI
Closes#1009
Checking for specific strings of length 0 or 1 can be done with e.g.:
if (str[0] == '\0') {...}
if (str[0] == '?' && str[1] == '\0') {...}
Doing it this way instead of using strlen(3) means we avoid the
function call overhead and also avoid scanning through more of the
string than is neceessary.
A compiler could perhaps optimize away calls to strlen(3) when the
result is compared to a small constant, but GCC 11.2 only seems to
actually do this[1] for lengths of 0.
[1]: https://godbolt.org/z/qxoW8qqW6
The underline cursor is positioned just below regular underlines. A
bug in the positioning logic related to this, sometimes resulted in
the cursor being thinner than what it should be, or even invisible.
Fixes#1005
This makes the example config `foot.ini` and its man page slightly more
coherent regarding the specification of default values.
Note that the cursor color is not hardcoded like e.g. foreground or
background, thus in the example config, `<inverse foreground/background>`
makes more sense.
If a request handler doesn’t define its own put() handler, simply drop
all DCS parameter data. This way, we won’t end up allocating
potentially large buffers for unsupported/unimplemented DCS requests.
Closes#959
When matching “untranslated” bindings (by matching the base symbol of
the key, e.g. ctrl+shift+2 in US layout), require that no
non-significant modifiers are active.
This fixes an issue where AltGr was “ignored”, and would cause certain
combinations to match a key binding.
Example: ctrl+altgr+0, on many European layouts matched against the
default ctrl+0 (reset the font size), instead of emitting ^]
To make this work, we now need to filter out “locked”
modifiers (e.g. NumLock and CapsLock). Otherwise having e.g. NumLock
active would prevent *all* untranslated matching to fail.
Closes#983
Use the (relatively new) macro __has_include() to check if
stdc-predef.h exists, and only include it if it does.
If stdc-predef.h does not exist, or if the compiler does not implement
__has_include(), stdc-predef.h is *not* included.