From 56d2c3e990509d18de31e6009e0d0c6254f99b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 2 Jan 2025 09:08:24 +0100 Subject: [PATCH] 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 --- CHANGELOG.md | 3 +++ config.c | 4 ++-- render.c | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdc1828b..994805dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/config.c b/config.c index 7f1ce055..3b8ce7e8 100644 --- a/config.c +++ b/config.c @@ -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; } diff --git a/render.c b/render.c index ed6b802e..8fc741b5 100644 --- a/render.c +++ b/render.c @@ -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);