render: whole-window transparency when unfocused

This adds a new option, colors.unfocused-alpha. When set to a value <
1.0, the entire window (*everything* - all bg/fg colors, images etc)
are made transparent while the window does not have keyboard focus.

The way this is implemented (trying to keep the patch small), we need
to do full-screen repaints while in this mode.

That is, all screen updates result in full-screen repaints when:

* The window does not have keyboard focus
* The window *just* gained keyboard focus (i.e. last frame was
  rendered with transparency)

As such, one can expect a fairly large performance impact when there’s
large amount of output while the window is unfocused.

Focused windows are unaffected, as are unfocused windows when
colors.unfocused-alpha == 1.0.
This commit is contained in:
Daniel Eklöf 2021-08-11 17:36:42 +02:00
parent 2fbc336eb9
commit 9013a810f1
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
7 changed files with 57 additions and 0 deletions

View file

@ -144,6 +144,7 @@
* Mouse buttons 6/7 (mouse wheel left/right).
* `url.uri-characters` option to `foot.ini`
(https://codeberg.org/dnkl/foot/issues/654).
* `colors.unfocused-alpha` to `foot.ini`.
### Changed

View file

@ -1359,6 +1359,18 @@ parse_section_colors(const char *key, const char *value, struct config *conf,
return true;
}
else if (strcmp(key, "unfocused-alpha") == 0) {
double alpha;
if (!str_to_double(value, &alpha) || alpha < 0. || alpha > 1.) {
LOG_AND_NOTIFY_ERR("%s:%d: [colors]: unfocused-alpha: expected a value in the range 0.0-1.0",
path, lineno);
return false;
}
conf->colors.unfocused_alpha = alpha * 65535.;
return true;
}
else {
LOG_AND_NOTIFY_ERR("%s:%d: [colors]: %s: invalid key", path, lineno, key);
return false;
@ -2940,6 +2952,7 @@ config_load(struct config *conf, const char *conf_path,
.fg = default_foreground,
.bg = default_background,
.alpha = 0xffff,
.unfocused_alpha = 0xffff,
.selection_fg = 0x80000000, /* Use default bg */
.selection_bg = 0x80000000, /* Use default fg */
.use_custom = {

View file

@ -154,6 +154,7 @@ struct config {
uint32_t bg;
uint32_t table[256];
uint16_t alpha;
uint16_t unfocused_alpha;
uint32_t selection_fg;
uint32_t selection_bg;
uint32_t url;

View file

@ -509,6 +509,26 @@ _alpha_ option.
Background translucency. A value in the range 0.0-1.0, where 0.0
means completely transparent, and 1.0 is opaque. Default: _1.0_.
*unfocused-alpha*
Window translucency applied when window does not have keyboard
focus. Unlike *alpha*, this option affects everything (all
background colors, foreground colors, images etc).
Note that *alpha* is also applied.
Be aware that there is a performance penalty of using this, as
damage tracking is disabled while the window is
unfocused. I.e. all screen updates will result in fullscreen
repaints. This is not an issue when the window content is static,
or updates at a slow pace (e.g. top), but can be noticeable with
high amounts of output. Performance is unaffected in focused
windows.
Valid values are in the range 0.0-1.0, where 0.0 means completely
transparent, and 1.0 is opaque.
Default: _1.0_
*selection-foreground*, *selection-background*
Foreground (text) and background color to use in selected
text. Note that *both* options must be set, or the default will be

View file

@ -66,6 +66,7 @@
[colors]
# alpha=1.0
# unfocused-alpha=1.0
# foreground=dcdccc
# background=111111
# regular0=222222 # black

View file

@ -2366,6 +2366,9 @@ grid_render(struct terminal *term)
term->render.last_buf->height != buf->height ||
term->flash.active || term->render.was_flashing ||
term->is_searching != term->render.was_searching ||
(term->conf->colors.unfocused_alpha < 0xffff && (
!term->kbd_focus ||
!term->render.was_focused)) ||
term->render.margins)
{
force_full_repaint(term, buf);
@ -2392,6 +2395,7 @@ grid_render(struct terminal *term)
term->render.last_buf = buf;
term->render.was_flashing = term->flash.active;
term->render.was_searching = term->is_searching;
term->render.was_focused = term->kbd_focus;
shm_addref(buf);
buf->age = 0;
@ -2677,6 +2681,22 @@ grid_render(struct terminal *term)
xassert(buf->width % term->scale == 0);
xassert(buf->height % term->scale == 0);
if (!term->kbd_focus && term->conf->colors.unfocused_alpha < 0xffff) {
pixman_color_t unfocused_alpha =
{0, 0, 0, term->conf->colors.unfocused_alpha};
pixman_image_t *transparent =
pixman_image_create_solid_fill(&unfocused_alpha);
pixman_image_composite32(
PIXMAN_OP_IN_REVERSE, transparent, NULL, buf->pix[0],
0, 0, 0, 0, 0, 0, buf->width, buf->height);
pixman_image_unref(transparent);
wl_surface_damage_buffer(
term->window->surface, 0, 0, buf->width, buf->height);
}
wl_surface_attach(term->window->surface, buf->wl_buf, 0, 0);
wl_surface_commit(term->window->surface);
}

View file

@ -554,6 +554,7 @@ struct terminal {
struct buffer *last_buf; /* Buffer we rendered to last time */
bool was_flashing; /* Flash was active last time we rendered */
bool was_searching;
bool was_focused;
size_t search_glyph_offset;