Commit graph

1348 commits

Author SHA1 Message Date
Daniel Eklöf
e63150305e
Add support for background blur
This patch adds a new config option: colors{,2}.blur=no|yes. When
enabled, transparent background are also blurred.

Note that this requires the brand new ext-background-effect-v1
protocol, and specifically, that the compositor implements the blur
effect.
2025-12-20 16:08:59 +01:00
Daniel Eklöf
aa26676c43
builtin terminfo: add custom 'query-os-name'
Inspired by Kitty's 'kitty-query-os_name'. Notable changes:

* Drop kitty prefix
* os_name -> os-name
* Use "uname -s" without any transformations (e.g. no lower-casing)

    $ ./utils/xtgettcap query-os-name
    reply: (44 chars): <ESC>P1+r71756572792d6f732d6e616d65=4C696E7578<ESC>\
      query-os-name=Linux

Closes #2209
2025-12-20 15:59:31 +01:00
Daniel Eklöf
1caba0d993
config: remove deprecated config option cursor.color
This option was deprecated in 1.23.0. Use colors-{dark,light}.cursor
instead.
2025-12-20 15:57:19 +01:00
Daniel Eklöf
cf2b390f6e
config: add [colors-dark] and [colors-light], replacing [colors] and [colors2]
The main reason for having two color sections is to be able to switch
between dark and light. Thus, it's better if the section names reflect
this, rather than the more generic 'colors' and 'colors2' (which was
the dark one and which was the light one, now again?)

When the second color section was added, we kept the original name,
colors, to make sure we didn't break existing configurations, and
third-party themes.

However, in the long run, it's probably better to be specific in the
section naming, to avoid confusion.

So, add 'colors-dark', and 'colors-light'. Keep 'colors' and 'colors2'
as aliases for now, but mark them as deprecated. They WILL be removed
in a future release.

Also rename the option values for initial-color-theme, from 1/2, to
dark/light. Keep the old ones for now, marked as deprecated.

Update all bundled themes to use the new names. In the light-only
themes (i.e. themes that define a single, light, theme), use
colors-light, and set initial-color-theme=light.

Possible improvements: disable color switching if only one color
section has been explicitly configured (todo: figure out how to handle
the default color theme values...)
2025-12-20 15:51:30 +01:00
Daniel Eklöf
4e96780eef
shm: revert part of 299186a654
299186a654 introduced a regression,
where we don't handle SHM buffer "hiccups" correctly.

If foot, for some reason is forced to render a frame "too soon", we
might end up having multiple buffers "in flight" (i.e. committed to
the compositor). This could happen if the compositor pushes multiple
configure events rapidly, for example. Or anything else that forces
foot to render something "immediately", without waiting for a frame
callback.

The compositor typically releases both buffers at the same time (or
close to it), so the _next_ time we want to render a frame, we
have *two* buffers to pick between. The problem here is that after
299186a654, foot no longer purges the
additional buffer(s), but keeps all of them around. This messes up
foot's age tracking, and the _next_ time we're forced to pull two
buffers (without the compositor releasing the first one in between),
we try to apply damage tracking that is no longer valid. This results
in visual glitches. This never self-repairs, and we're stuck with
visual glitches until the window is resized, and we're forced to
allocate completely new buffers.

It is unclear why 299186a654 stopped
removing the buffers. It was likely done early in the development, and
is no longer needed. So far, I haven't noticed any bugs by
re-introducing the buffer purging, but further testing is needed.
2025-12-17 08:09:23 +01:00
Daniel Eklöf
6e533231b0
term: mouse SGR mode: don't emit negative CSI values
When reporting the column/row pixel value in mouse SGR mode, we
emitted negative values when the cursor was being dragged outside the
window.

Unfortunately, negative values aren't allowed in CSI parameters, as
'-' is an intermediate value.

It was done this way, to be consistent with XTerm behavior. Allegedly,
XTerm has changed its behavior in patch 404.

With that in mind, and seeing that foot has never emitted negative
values in any other mouse mode, let's stop emitting negative values in
SGR mode too.

Closes #2226
2025-12-13 09:56:29 +01:00
Daniel Eklöf
65bd79b77d
term: reverse-scroll: fix crash when viewport ends up outside the (new) scrollback
If the viewport has been scrolled up, it is possible for a
reverse-scroll (rin) to cause the viewport to point to lines outside
the scrollback. This is an issue if the scrollback isn't full, since
in that case, the viewport will contain NULL lines. This will
potentially trigger assertions in a couple of different places.

Example backtrace:

    #2 0x555555cd230c in bug ../../debug.c:44
    #3 0x555555ad485e in grid_row_in_view ../../grid.h:83
    #4 0x555555b15a89 in grid_render ../../render.c:3465
    #5 0x555555b3b0ab in fdm_hook_refresh_pending_terminals ../../render.c:5165
    #6 0x555555a74980 in fdm_poll ../../fdm.c:435
    #7 0x555555ac2b85 in main ../../main.c:676

Detect when this happens, and force-move the viewport to ensure it is
valid.

Closes #2232
2025-12-13 09:55:27 +01:00
Daniel Eklöf
fc9625678f
config: add toplevel-tag=TAG
Add support for the new xdg-toplevel-tag-v1 Wayland protocol, by
exposing a new config option, `toplevel-tag`, and a corresponding
command option, `--toplevel-tag` (in both `foot` and `footclient`).

This can help the compositor with session management, or custom window
rules.

Closes #2212
2025-11-12 11:04:25 +01:00
Daniel Eklöf
c9abab0807
changelog: triple-click when there's a quote in the last column 2025-11-12 07:46:34 +01:00
Daniel Eklöf
1fce0e69f5
changelog: case sensitive scrollback search: move to correct release 2025-11-01 08:12:52 +01:00
Daniel Eklöf
9728ada028
csi: focus mode (private mode 1004): send focus event immediate, when enabled
This lets the application now the current state, without having to
wait for the user to switch focus.

Fixes #2202
2025-11-01 08:12:03 +01:00
Ronan Pigott
143f220527
search: do not emit composing keys
When we are in the composing state for XCompose key sequences, we
should not add the compose component keys to the search buffer.
2025-11-01 08:08:55 +01:00
c4llv07e
5ae4955e83
search: use case insensitive search only if there's no uppercase in search 2025-10-30 06:36:12 +01:00
Daniel Eklöf
82e75851e4
changelog: add new 'unreleased' section 2025-10-16 08:50:31 +02:00
Daniel Eklöf
dc5a921d2c
changelog: prepare for 1.25.0 2025-10-16 08:46:36 +02:00
Daniel Eklöf
dbf18ba444
wayland: always render a new frame after a fullscreen change
This is needed, since we disable alpha in fullscreen, and since we use
different image buffer formats (XRGB vs. ARGB) when we have alpha
vs. when we don't (and fullscreen always disables alpha).

Normally, this happens anyway, as the window is resized when going in
or out from fullscreen. But, it's technically possible for a
compositor to change an application's fullscreen state without
resizing the window.
2025-10-15 09:41:52 +02:00
Daniel Eklöf
96605bf52f
extract: number of spaces after the tab shouldn't include the tab cell itself
This fixes an off by one, where we sometimes "ate" an extra space when
extracting contents with tabs. This happened if the tab (and its
subsequent spaces) were followed by an additional space.

Closes #2194
2025-10-11 10:13:10 +02:00
Daniel Eklöf
7ed36c1033
config: add colors.dim-blend-towards=black|white
Before this patch, we always blended towards black when dimming
text. However, with light color themes, it usually looks better if we
dim towards white instead.

This option allows you to choose which color to blend towards.

The default is 'black' in '[colors]', and 'white' in '[colors2]'.

Closes #2187
2025-10-10 11:10:38 +02:00
Daniel Eklöf
371837ef7b
changelog: updated jump label colors in modus-operandi 2025-10-10 10:36:41 +02:00
Daniel Eklöf
299186a654
render: when double-buffering, pre-apply previous frame's damage early
Foot likes it when compositor releases buffer immediately, as that
means we only have to re-render the cells that have changed since the
last frame.

For various reasons, not all compositors do this. In this case, foot
is typically forced to switch between two buffers, i.e. double-buffer.

In this case, each frame starts with copying over the damage from the
previous frame, to the new frame. Then we start rendering the updated
cells.

Bringing over the previous frame's damage can be slow, if the changed
area was large (e.g. when scrolling one or a few lines, or on full
screen updates). It's also done single-threaded. Thus it not only
slows down frame rendering, but pauses everything else (i.e. input
processing). All in all, it reduces performance and increases input
latency.

But we don't have to wait until it's time to render a frame to copy
over the previous frame's damage. We can do that as soon as the
compositor has released the buffer (for the frame _before_ the
previous frame). And we can do this in a thread.

This frees up foot to continue processing input, and reduces frame
rendering time since we can now start rendering the modified cells
immediately, without first doing a large memcpy(3).

In worst case scenarios (or perhaps we should consider them best case
scenarios...), I've seen up to a 10x performance increase in frame
rendering times (this obviously does *not* include the time it takes
to copy over the previous frame's damage, since that doesn't affect
neither input processing nor frame rendering).

Implemented by adding a callback mechanism to the shm abstraction
layer. Use it for the grid buffers, and kick off a thread that copies
the previous frame's damage, and resets the buffers age to 0 (so that
foot understands it can start render to it immediately when it later
needs to render a frame).

Since we have certain way of knowing if a compositor releases buffers
immediately or not, use a bit of heuristics; if we see 10 consecutive
non-immediate releases (that is, we reset the counter as soon as we do
see an immediate release), this new "pre-apply damage" logic is
enabled. It can be force-disabled with tweak.pre-apply-damage=no.

We also need to take care to wait for the thread before resetting the
render's "last_buf" pointer (or we'll SEGFAULT in the thread...).

We must also ensure we wait for the thread to finish before we start
rendering a new frame. Under normal circumstances, the wait time is
always 0, the thread has almost always finished long before we need to
render the next frame. But it _can_ happen.

Closes #2188
2025-10-10 10:23:17 +02:00
Daniel Eklöf
bb314425ef
changelog: shm buffer stride alignment 2025-10-05 09:40:57 +02:00
Daniel Eklöf
80951ab7a6
term: osc8: tag *all* cells in a multi-column character as an URI
When we print a character to the grid, we must also update its OSC-8
state if an OSC-8 URI is currently active.

For double-width characters, this was only being done for the first
cell.

This causes the labels in URL mode to be off, as the link was
effectively chopped up into multiple pieces.

Closes #2179
2025-10-04 09:24:47 +02:00
Daniel Eklöf
c34f063307
changelog: add new 'unreleased' section 2025-09-12 10:22:21 +02:00
Daniel Eklöf
f715f3b55f
changelog: prepare for 1.24.0 2025-09-12 10:18:06 +02:00
Daniel Eklöf
65528f455d
meson: utempter del has no argument
This fixes an issue where we didn't record a logout record when using
the libutempter backend.
2025-09-09 17:34:02 +02:00
Ryan Roden-Corrent
298196365c
config: add 'uppercase-regex-insert'
This makes the "uppercase hint character inserts selected text"
behavior added in #1975 configurable, as it can have unexpected
behavior for some users.

It defaults to "on", preserving the new behavior of `foot`, after

Fixes #2159.
2025-08-31 11:36:28 +02:00
Daniel Eklöf
ed7652db50
config: value_to_*(): don't overwrite result variable on error
Some of the value_to_*() functions wrote directly to the output
variable, even when the value was invalid. This often resulted in the
an actual configuration option (i.e. a member in the config struct) to
be overwritten by an invalid value.

For example, -o initial-color-theme=0 would set
conf->initial_color_theme to -1, resulting in a crash later, when
initializing a terminal instance.
2025-08-25 15:46:19 +02:00
Daniel Eklöf
b13a8f12d2
server/client: add support for sending SIGUSR to footclient
This patch adds the IPC infrastructure necessary to propagate
SIGUSR1/SIGUSR2 from a footclient process to the server process.

By targeting a particular footclient instance, only that particular
instance changes theme. This is different from when targeting the
server process, where all instances change theme.

Closes #2156
2025-08-01 09:38:05 +02:00
Daniel Eklöf
70d99a8051
changelog: SIGUSR changes in the server 2025-07-30 12:38:14 +02:00
Daniel Eklöf
83303bd2a4
url-mode: for some reason we sorted the label letters before assigning them
Don't do this. Now that we **don't** sort them, the first letter
chosen by the user is always assigned to the bottom most URL.

Closes #2140 (again)
2025-07-29 11:18:49 +02:00
Daniel Eklöf
86d63f08ba
changelog: add new 'unreleased' section 2025-07-23 08:31:30 +02:00
Daniel Eklöf
95e8b18c12
changelog: prepare for 1.23.1 2025-07-23 08:27:59 +02:00
Daniel Eklöf
fcde74a181
osc: color reset: read default color from currently active theme 2025-07-22 13:30:28 +02:00
Daniel Eklöf
7ab43ebf74
shm: don't set pixman_fmt_without_alpha twice
When selecting 16-bit surfaces, we set pixman_fmt_without_alpha twice,
and never set pixman_fmt_with_alpha.

This caused 10-bit surfaces to be used instead, since it checks if
pixman_fmt_with_alpha has been overridden or not.
2025-07-21 13:49:57 +02:00
Daniel Eklöf
01387f9593
main: SIGUSR1 selects the first color theme, SIGUSR2 the second
Before this patch, SIGUSR1 toggled between [colors] and
[colors2].

Now, SIGUSR1 changes to [colors], regardless of what the current color
theme is, and SIGUSR2 changes to [colors2].

Closes #2144
2025-07-18 08:33:42 +02:00
Daniel Eklöf
cc290fa9b0
url-mode: assign label keys in reverse order
The _last_ URL is often the one you are interested in, and with this
change, it is always assigned the first (and thus the same) key.

Closes #2140
2025-07-17 10:40:20 +02:00
Daniel Eklöf
692b22cbbb
changelog: add new 'unreleased' section 2025-07-16 08:31:42 +02:00
Daniel Eklöf
e72e08625d
changelog: prepare for 1.23.0 2025-07-16 08:14:54 +02:00
Daniel Eklöf
968bc05c32
csi: add '52' to the DA reply, to indicate PSC-52 support
Note: only *copy* is required to be enabled in security.osc52; paste
is optional, see
https://github.com/contour-terminal/contour/issues/1761#issuecomment-2944492097
2025-06-10 07:12:53 +02:00
Daniel Eklöf
499f019dea
osc: 52: clear selection if the payload is the empty string 2025-06-10 07:12:53 +02:00
Daniel Eklöf
d9675a7140
main: do a theme toggle upon receiving SIGUSR1
Caveat: in server mode, *all* instances toggle their themes.
2025-06-10 07:11:45 +02:00
Daniel Eklöf
7347f4beb1
quirks: remove subsurface unmap quirk for Sway
Sway used to have an issue where unmapping a subsurface did not damage
the surface below (https://github.com/swaywm/sway/issues/6960).

This has been fixed for quite some time now, so let's remove the
quirk.
2025-06-09 07:08:24 +02:00
Daniel Eklöf
5a84f8d841
conf: pad: add center-when-fullscreen and center-when-maximized-and-fullscreen
Before this patch, the grid content was *always* centered when the
window was maximized or fullscreened, regardless of how the user had
configured padding.

Now, the behavior is controlled by the 'pad' option. Before this
patch, the syntax was

    pad MxN [center]

Now it is

    pad MxN [center|center-when-fullscreen|center-when-maximized-and-fullscreen]

The default is "pad 0x0 center-when-maximized-and-fullscreen", to
match current behavior.

Closes #2111
2025-05-24 09:56:16 +02:00
Daniel Eklöf
664cdcc65c
cursor-shape: add 'dnd-ask' and 'all-resize'
These (non-css) cursor shapes were added to the cursor-shape-v1
protocol in wayland-protocols 1.42.

We don't need (or use them at all) internally, but add them to the
list we use to translate from shape names to shape enums. This allows
users to set a custom shape (via OSC-22), while still using server
side cursors (i.e. no need to fallback to client-side cursors).

If we try to set a shape not implemented by the server, we get a
protocol error and foot exits. This is bad.

So, make sure we don't do that:

1. First, we need to explicitly bind v2 if implemented by the server
2. Track the bound version number in the wayland struct
3. When matching shape enum, skip shapes not supported in the
   currently bound version of the cursor-shape protocol
2025-05-22 06:59:33 +02:00
Daniel Eklöf
d266599881
wayland: configure: don't commit if we have a pending refresh
Currently, if the following occurs:

1. foot has AxB size
2. Compositor sends CxD size
3. foot detects a resize, acks and saves CxD, but doesn't redraw immediately
4. Compositor sends CxD size again (due to a toplevel state array
   change, for example)

Then foot will detect no resize occurred, and will do an "empty"
commit immediately.

In this particular case that's wrong, since we're effectively
acking+committing the initial AxB size.

Fix by only doing the immediate commit if there's no size
change **and** there's no pending refresh.

Note: normally, we'd resize and refresh+commit immediately, but if
we're waiting for a frame callback, then the refresh+commit will be
delayed (i.e. scheduled). This is what we're checking here.

Closes #2105
2025-05-21 13:07:49 +02:00
Daniel Eklöf
3e1e3ea38c
libxkbcommon: don't require 1.8.0
The version bump was done since we now use XKB_VMOD_NAME_*; macros
added in libxkbcommon 1.8.0.

Not all distros have updated libxkbcommon yet (read: Debian). Since
it's fairly easy to work around, let's do that.

Closes #2103
2025-05-18 11:36:57 +02:00
Daniel Eklöf
ebd1614316
csi: when REP:ing a "combining" character, use correct width
Before this patch, we just called c32width(), which only works on
actual codepoints. If the last printed character is a "combining"
character, i.e. a key into our lookup table for multi-codepoint
graphemes, we need to lookup the grapheme and pick the width from
there.

See https://gitlab.com/AutumnMeowMeow/jexer/-/issues/119#note_2499712901
2025-05-16 18:46:26 +02:00
Daniel Eklöf
073b637d45
render: refactor to allow setting only selection bg or fg
Before this, we only applied custom selection colors, if *both* the
selection bg and fg had been set.

Since the options are already split up into two separate options, and
since it makes sense to at least be able to keep the foreground colors
unchanged (i.e. only setting the selection background), let's allow
only having one of the selection colors set.

Closes #1846
2025-05-05 13:02:32 +02:00
Daniel Eklöf
970e13db8d
config: tweak.surface-bit-depth: add support for 16-bit surfaces
This adds supports for 16-bit surfaces, using the new
PIXMAN_a16b16g16r16 buffer format. This maps to
WL_SHM_FORMAT_ABGR16161616 (little-endian).

Use the new 16-bit surfaces by default, when
gamma-correct-blending=yes.
2025-05-03 09:04:15 +02:00
Daniel Eklöf
7354b94f73
osc: restore configured alpha if OSC-11 has no alpha value
When parsing an OSC-11 without an alpha value (i.e. standard OSC-11,
not rxvt's extended variant), restore the alpha value from the
configuration, rather than keeping whatever the current alpha is.
2025-05-02 18:54:03 +02:00