bell: optionally render margins in red when receiving BEL

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
This commit is contained in:
Daniel Eklöf 2020-10-08 19:55:32 +02:00
parent 7e0cfd46c6
commit 7c6686221f
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
10 changed files with 95 additions and 2 deletions

View file

@ -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

View file

@ -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 = {

View file

@ -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;

1
csi.c
View file

@ -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: {

View file

@ -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

View file

@ -9,6 +9,7 @@
# term=foot
# login-shell=no
# workers=<number of logical CPUs>
# bell=none
[scrollback]
# lines=1000

View file

@ -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(

View file

@ -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)
{

View file

@ -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);

3
vt.c
View file

@ -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':