config: don't allow colors.flash-alpha to be 1.0

A compositor will not send a frame callback for our main window if it
is fully occluded (for example, by a fully opaque overlay...). This
causes the overlay to stuck.

For regular buffers, it _should_ be enough to *not* hint the
compositor it's opaque. But at least some compositor special cases
single-pixel buffers, and actually look at their pixel value.

Thus, we have two options: implement frame callback handling for the
overlay sub-surface, or ensure we don't use a fully opaque
surface. Since no overlays are fully opaque by default, and the flash
surface is the only one that can be configured to be
opaque (colors.flash-alpha), and since adding frame callback handling
adds a lot of boilerplate code... let's go with the simpler solution
of
This commit is contained in:
Daniel Eklöf 2025-01-02 09:08:24 +01:00
parent c7ab7b3539
commit 56d2c3e990
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 26 additions and 2 deletions

View file

@ -62,6 +62,9 @@
* Runtime changes to the app-id (OSC-176) now limits the app-id string
to 2048 characters ([#1897][1897]).
* `colors.flash-alpha` can no longer be set to 1.0 (i.e. fully
opaque). This fixes an issue where the window would be stuck in the
flash state.
[1897]: https://codeberg.org/dnkl/foot/issues/1897

View file

@ -1445,8 +1445,8 @@ parse_section_colors(struct context *ctx)
if (!value_to_float(ctx, &alpha))
return false;
if (alpha < 0. || alpha > 1.) {
LOG_CONTEXTUAL_ERR("not in range 0.0-1.0");
if (alpha < 0. || alpha >= 1.) {
LOG_CONTEXTUAL_ERR("not in range 0.0-0.999");
return false;
}

View file

@ -1898,6 +1898,27 @@ render_overlay(struct terminal *term)
break;
case OVERLAY_FLASH:
/*
* A compositor will not send a frame callback for our main
* window if it is fully occluded (for example, by a fully
* opaque overlay...). This causes the overlay to stuck.
*
* For regular buffers, it _should_ be enough to *not* hint
* the compositor it's opaque. But at least some compositor
* special cases single-pixel buffers, and actually look at
* their pixel value.
*
* Thus, we have two options: implement frame callback
* handling for the overlay sub-surface, or ensure we don't
* use a fully opaque surface. Since no overlays are fully
* opaque by default, and the flash surface is the only one
* that can be configured to be opaque (colors.flash-alpha),
* and since adding frame callback handling adds a lot of
* boilerplate code... let's go with the simpler solution of
* not allowing colors.flash-alpha to be 1.0.
*/
xassert(term->conf->colors.flash_alpha != 0xffff);
color = color_hex_to_pixman_with_alpha(
term->conf->colors.flash,
term->conf->colors.flash_alpha);