From 7c6686221f328e9399eb679c246662c801b2356b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 8 Oct 2020 19:55:32 +0200 Subject: [PATCH] bell: optionally render margins in red when receiving BEL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add anew config option, ‘bell=none|set-urgency’. When set to ‘set-urgency’, the margins will be painted in red (if the window did not have keyboard focus). This is intended as a cheap replacement for the ‘urgency’ hint, that doesn’t (yet) exist on Wayland. Closes #157 --- CHANGELOG.md | 8 ++++++++ config.c | 15 +++++++++++++++ config.h | 2 ++ csi.c | 1 + doc/foot.ini.5.scd | 16 ++++++++++++++++ foot.ini | 1 + render.c | 32 ++++++++++++++++++++++++++++++++ terminal.c | 17 +++++++++++++++++ terminal.h | 2 ++ vt.c | 3 +-- 10 files changed, 95 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aabed84b..f919972d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,14 @@ terminfo). This mode can be enabled/disabled with `CSI ? 45 h` and `CSI ? 45 l`. It is **enabled** by default (https://codeberg.org/dnkl/foot/issues/150). +* **bell** option to `foot.ini`. Can be set to `set-urgency` to make + foot render the margins in red when receiving `BEL` while **not** + having keyboard focus. Note that Wayland does **not** implement an + _urgency_ hint like X11, but that there is a + [proposal](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/9) + to add support for this. The value `set-urgency` was chosen for + forward-compatibility, in the hopes that this proposal eventualizes + (https://codeberg.org/dnkl/foot/issues/157). ### Changed diff --git a/config.c b/config.c index ff5d6c59..3bece45e 100644 --- a/config.c +++ b/config.c @@ -517,6 +517,20 @@ parse_section_main(const char *key, const char *value, struct config *conf, conf->pad_y = y; } + else if (strcmp(key, "bell") == 0) { + if (strcmp(value, "set-urgency") == 0) + conf->bell_set_urgency = true; + else if (strcmp(value, "none") == 0) + conf->bell_set_urgency = false; + else { + LOG_AND_NOTIFY_ERR( + "%s:%d: [default]: bell: " + "expected either 'set-urgency' or 'none'", path, lineno); + conf->bell_set_urgency = false; + return false; + } + } + else if (strcmp(key, "initial-window-mode") == 0) { if (strcmp(value, "windowed") == 0) conf->startup_mode = STARTUP_WINDOWED; @@ -1867,6 +1881,7 @@ config_load(struct config *conf, const char *conf_path, }, .pad_x = 2, .pad_y = 2, + .bell_set_urgency = false, .startup_mode = STARTUP_WINDOWED, .fonts = tll_init(), .scrollback = { diff --git a/config.h b/config.h index 1c0edc58..58b6f8a7 100644 --- a/config.h +++ b/config.h @@ -72,6 +72,8 @@ struct config { unsigned pad_x; unsigned pad_y; + bool bell_set_urgency; + enum { STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN } startup_mode; tll(struct config_font) fonts; diff --git a/csi.c b/csi.c index 9a8d7a38..1b5d070b 100644 --- a/csi.c +++ b/csi.c @@ -363,6 +363,7 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) /* DECSCNM */ term->reverse = enable; term_damage_all(term); + term_damage_margins(term); break; case 6: { diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 60da2d67..22b2adde 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -91,6 +91,22 @@ in this order: (including SMT). Note that this is not always the best value. In some cases, the number of physical _cores_ is better. +*bell* + Action to perform when receiving a *BEL* character. Can be set to + either *set-urgency* or *none*. + + When set to *set-urgency*, the margins will be painted in red + whenever *BEL* is received while the window does *not* have + keyboard focus. Note that Wayland currently does not have an + _urgency_ hint like X11. The value *set-urgency* was chosen for + forward-compatibility in the hopes that a corresponding Wayland + protocol is added in the future (in which case foot will use that + instead of painting its margins red). + + When set to *none*, no special action is taken when receiving *BEL*. + + Default: _none_. + # SECTION: scrollback diff --git a/foot.ini b/foot.ini index 952bf00c..fea2f2b8 100644 --- a/foot.ini +++ b/foot.ini @@ -9,6 +9,7 @@ # term=foot # login-shell=no # workers= +# bell=none [scrollback] # lines=1000 diff --git a/render.c b/render.c index 20d66512..427c8d44 100644 --- a/render.c +++ b/render.c @@ -541,6 +541,35 @@ draw_cursor: return cell_cols; } +static void +render_urgency(struct terminal *term, struct buffer *buf) +{ + uint32_t red = term->colors.table[1]; + pixman_color_t bg = color_hex_to_pixman(red); + + if (term->is_searching) + color_dim(&bg); + + int width = min(min(term->margins.left, term->margins.right), + min(term->margins.top, term->margins.bottom)); + + pixman_image_fill_rectangles( + PIXMAN_OP_SRC, buf->pix[0], &bg, 4, + (pixman_rectangle16_t[]){ + /* Top */ + {0, 0, term->width, width}, + + /* Bottom */ + {0, term->height - width, term->width, width}, + + /* Left */ + {0, width, width, term->height - 2 * width}, + + /* Right */ + {term->width - width, width, width, term->height - 2 * width}, + }); +} + static void render_margin(struct terminal *term, struct buffer *buf, int start_line, int end_line, bool apply_damage) @@ -578,6 +607,9 @@ render_margin(struct terminal *term, struct buffer *buf, term->margins.right, line_count * term->cell_height}, }); + if (term->render.urgency) + render_urgency(term, buf); + if (apply_damage) { /* Top */ wl_surface_damage_buffer( diff --git a/terminal.c b/terminal.c index c05d71d4..077d15f0 100644 --- a/terminal.c +++ b/terminal.c @@ -2073,6 +2073,12 @@ term_kbd_focus_in(struct terminal *term) return; term->kbd_focus = true; + + if (term->render.urgency) { + term->render.urgency = false; + term_damage_margins(term); + } + cursor_refresh(term); if (term->focus_events) @@ -2363,6 +2369,17 @@ term_flash(struct terminal *term, unsigned duration_ms) } } +void +term_bell(struct terminal *term) +{ + if (term->kbd_focus || !term->conf->bell_set_urgency) + return; + + /* There's no 'urgency' hint in Wayland - we just paint the margins red */ + term->render.urgency = true; + term_damage_margins(term); +} + bool term_spawn_new(const struct terminal *term) { diff --git a/terminal.h b/terminal.h index 817ee8ba..cac3b7b0 100644 --- a/terminal.h +++ b/terminal.h @@ -389,6 +389,7 @@ struct terminal { } pending; bool margins; /* Someone explicitly requested a refresh of the margins */ + bool urgency; /* Signal 'urgency' (paint borders red) */ int scrollback_lines; /* Number of scrollback lines, from conf (TODO: move out from render struct?) */ @@ -574,6 +575,7 @@ void term_xcursor_update_for_seat(struct terminal *term, struct seat *seat); void term_set_window_title(struct terminal *term, const char *title); void term_flash(struct terminal *term, unsigned duration_ms); +void term_bell(struct terminal *term); bool term_spawn_new(const struct terminal *term); void term_enable_app_sync_updates(struct terminal *term); diff --git a/vt.c b/vt.c index 6cd5ead7..ed26da73 100644 --- a/vt.c +++ b/vt.c @@ -124,8 +124,7 @@ action_execute(struct terminal *term, uint8_t c) case '\a': /* BEL - bell */ - // LOG_INFO("BELL"); - // term_flash(term, 50); + term_bell(term); break; case '\b':