mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-26 07:57:59 -04:00
Merge branch 'bell-enhancement'
This commit is contained in:
commit
63572e4223
6 changed files with 125 additions and 54 deletions
|
|
@ -38,6 +38,9 @@
|
||||||
* Unicode 13 characters U+1FB70 - U+1FB8B to list of box drawing
|
* Unicode 13 characters U+1FB70 - U+1FB8B to list of box drawing
|
||||||
characters rendered by foot itself (rather than using font glyphs)
|
characters rendered by foot itself (rather than using font glyphs)
|
||||||
(https://codeberg.org/dnkl/foot/issues/471).
|
(https://codeberg.org/dnkl/foot/issues/471).
|
||||||
|
* Dedicated bell section in config, supporting multiple actions and
|
||||||
|
a new `command` action to run an arbitrary command.
|
||||||
|
(https://codeberg.org/dnkl/foot/pulls/483)
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
@ -67,6 +70,8 @@
|
||||||
|
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
* **bell** option in `foot.ini`; set actions in **[bell]** section instead.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
@ -78,6 +83,7 @@
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
### Contributors
|
### Contributors
|
||||||
|
* [r\_c\_f](https://codeberg.org/r_c_f)
|
||||||
|
|
||||||
|
|
||||||
## 1.7.2
|
## 1.7.2
|
||||||
|
|
|
||||||
66
config.c
66
config.c
|
|
@ -594,18 +594,33 @@ parse_section_main(const char *key, const char *value, struct config *conf,
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(key, "bell") == 0) {
|
else if (strcmp(key, "bell") == 0) {
|
||||||
if (strcmp(value, "set-urgency") == 0)
|
LOG_WARN("deprecated: %s:%d: [default]: bell: set actions in section '[bell]' instead", path, lineno);
|
||||||
conf->bell_action = BELL_ACTION_URGENT;
|
|
||||||
else if (strcmp(value, "notify") == 0)
|
const char fmt[] = "%s:%d \033[1mbell\033[21m, use section \033[1m[bell]\033[21m instead";
|
||||||
conf->bell_action = BELL_ACTION_NOTIFY;
|
char *text = xasprintf(fmt, path, lineno);
|
||||||
else if (strcmp(value, "none") == 0)
|
|
||||||
conf->bell_action = BELL_ACTION_NONE;
|
struct user_notification deprecation = {
|
||||||
|
.kind = USER_NOTIFICATION_DEPRECATED,
|
||||||
|
.text = text,
|
||||||
|
};
|
||||||
|
tll_push_back(conf->notifications, deprecation);
|
||||||
|
|
||||||
|
if (strcmp(value, "set-urgency") == 0) {
|
||||||
|
memset(&conf->bell, 0, sizeof(conf->bell));
|
||||||
|
conf->bell.urgent = true;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "notify") == 0) {
|
||||||
|
memset(&conf->bell, 0, sizeof(conf->bell));
|
||||||
|
conf->bell.notify = true;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "none") == 0) {
|
||||||
|
memset(&conf->bell, 0, sizeof(conf->bell));
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
LOG_AND_NOTIFY_ERR(
|
LOG_AND_NOTIFY_ERR(
|
||||||
"%s:%d: [default]: bell: "
|
"%s%d: [default]: bell: "
|
||||||
"expected either 'set-urgency', 'notify' or 'none'",
|
"expected either 'set-urgency', 'notify' or 'none'",
|
||||||
path, lineno);
|
path, lineno);
|
||||||
conf->bell_action = BELL_ACTION_NONE;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -788,6 +803,28 @@ parse_section_main(const char *key, const char *value, struct config *conf,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
parse_section_bell(const char *key, const char *value, struct config *conf,
|
||||||
|
const char *path, unsigned lineno)
|
||||||
|
{
|
||||||
|
if (strcmp(key, "urgent") == 0)
|
||||||
|
conf->bell.urgent = str_to_bool(value);
|
||||||
|
else if (strcmp(key, "notify") == 0)
|
||||||
|
conf->bell.notify = str_to_bool(value);
|
||||||
|
else if (strcmp(key, "command") == 0) {
|
||||||
|
if (!str_to_spawn_template(conf, value, &conf->bell.command, path, lineno, "bell", key))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (strcmp(key, "command-focused") == 0)
|
||||||
|
conf->bell.command_focused = str_to_bool(value);
|
||||||
|
else {
|
||||||
|
LOG_AND_NOTIFY_ERR("%s:%u: [bell]: %s: invalid key", path, lineno, key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_section_scrollback(const char *key, const char *value, struct config *conf,
|
parse_section_scrollback(const char *key, const char *value, struct config *conf,
|
||||||
const char *path, unsigned lineno)
|
const char *path, unsigned lineno)
|
||||||
|
|
@ -1864,6 +1901,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path, bool errors_ar
|
||||||
{
|
{
|
||||||
enum section {
|
enum section {
|
||||||
SECTION_MAIN,
|
SECTION_MAIN,
|
||||||
|
SECTION_BELL,
|
||||||
SECTION_SCROLLBACK,
|
SECTION_SCROLLBACK,
|
||||||
SECTION_COLORS,
|
SECTION_COLORS,
|
||||||
SECTION_CURSOR,
|
SECTION_CURSOR,
|
||||||
|
|
@ -1887,6 +1925,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path, bool errors_ar
|
||||||
const char *name;
|
const char *name;
|
||||||
} section_info[] = {
|
} section_info[] = {
|
||||||
[SECTION_MAIN] = {&parse_section_main, "main"},
|
[SECTION_MAIN] = {&parse_section_main, "main"},
|
||||||
|
[SECTION_BELL] = {&parse_section_bell, "bell"},
|
||||||
[SECTION_SCROLLBACK] = {&parse_section_scrollback, "scrollback"},
|
[SECTION_SCROLLBACK] = {&parse_section_scrollback, "scrollback"},
|
||||||
[SECTION_COLORS] = {&parse_section_colors, "colors"},
|
[SECTION_COLORS] = {&parse_section_colors, "colors"},
|
||||||
[SECTION_CURSOR] = {&parse_section_cursor, "cursor"},
|
[SECTION_CURSOR] = {&parse_section_cursor, "cursor"},
|
||||||
|
|
@ -2212,7 +2251,6 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
.enabled = false,
|
.enabled = false,
|
||||||
.palette_based = false,
|
.palette_based = false,
|
||||||
},
|
},
|
||||||
.bell_action = BELL_ACTION_NONE,
|
|
||||||
.startup_mode = STARTUP_WINDOWED,
|
.startup_mode = STARTUP_WINDOWED,
|
||||||
.fonts = {tll_init(), tll_init(), tll_init(), tll_init()},
|
.fonts = {tll_init(), tll_init(), tll_init(), tll_init()},
|
||||||
.line_height = { .pt = 0, .px = -1, },
|
.line_height = { .pt = 0, .px = -1, },
|
||||||
|
|
@ -2221,6 +2259,15 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
.vertical_letter_offset = {.pt = 0, .px = 0, },
|
.vertical_letter_offset = {.pt = 0, .px = 0, },
|
||||||
.box_drawings_uses_font_glyphs = false,
|
.box_drawings_uses_font_glyphs = false,
|
||||||
.dpi_aware = DPI_AWARE_AUTO, /* DPI-aware when scaling-factor == 1 */
|
.dpi_aware = DPI_AWARE_AUTO, /* DPI-aware when scaling-factor == 1 */
|
||||||
|
.bell = {
|
||||||
|
.urgent = false,
|
||||||
|
.notify = false,
|
||||||
|
.command = {
|
||||||
|
.raw_cmd = NULL,
|
||||||
|
.argv = NULL,
|
||||||
|
},
|
||||||
|
.command_focused = false,
|
||||||
|
},
|
||||||
.scrollback = {
|
.scrollback = {
|
||||||
.lines = 1000,
|
.lines = 1000,
|
||||||
.indicator = {
|
.indicator = {
|
||||||
|
|
@ -2446,6 +2493,7 @@ config_free(struct config conf)
|
||||||
free(conf.app_id);
|
free(conf.app_id);
|
||||||
free(conf.word_delimiters);
|
free(conf.word_delimiters);
|
||||||
free(conf.jump_label_letters);
|
free(conf.jump_label_letters);
|
||||||
|
free_spawn_template(&conf.bell.command);
|
||||||
free(conf.scrollback.indicator.text);
|
free(conf.scrollback.indicator.text);
|
||||||
free_spawn_template(&conf.notify);
|
free_spawn_template(&conf.notify);
|
||||||
free_spawn_template(&conf.url_launch);
|
free_spawn_template(&conf.url_launch);
|
||||||
|
|
|
||||||
13
config.h
13
config.h
|
|
@ -84,12 +84,6 @@ struct config {
|
||||||
bool palette_based;
|
bool palette_based;
|
||||||
} bold_in_bright;
|
} bold_in_bright;
|
||||||
|
|
||||||
enum {
|
|
||||||
BELL_ACTION_NONE,
|
|
||||||
BELL_ACTION_URGENT,
|
|
||||||
BELL_ACTION_NOTIFY,
|
|
||||||
} bell_action;
|
|
||||||
|
|
||||||
enum { STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN } startup_mode;
|
enum { STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN } startup_mode;
|
||||||
|
|
||||||
enum {DPI_AWARE_AUTO, DPI_AWARE_YES, DPI_AWARE_NO} dpi_aware;
|
enum {DPI_AWARE_AUTO, DPI_AWARE_YES, DPI_AWARE_NO} dpi_aware;
|
||||||
|
|
@ -105,6 +99,13 @@ struct config {
|
||||||
|
|
||||||
bool box_drawings_uses_font_glyphs;
|
bool box_drawings_uses_font_glyphs;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool urgent;
|
||||||
|
bool notify;
|
||||||
|
struct config_spawn_template command;
|
||||||
|
bool command_focused;
|
||||||
|
} bell;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int lines;
|
int lines;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -211,32 +211,6 @@ in this order:
|
||||||
|
|
||||||
Default: _no_.
|
Default: _no_.
|
||||||
|
|
||||||
*bell*
|
|
||||||
Action to perform when receiving a *BEL* character. Can be set to
|
|
||||||
either *set-urgency*, *notify* 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).
|
|
||||||
|
|
||||||
Applications can enable/disable this feature programmatically with
|
|
||||||
the *CSI ? 1042 h* and *CSI ? 1042 l* escape sequences.
|
|
||||||
|
|
||||||
_Note_: expect this feature to be *replaced* with proper
|
|
||||||
compositor urgency support once/if that gets implemented.
|
|
||||||
|
|
||||||
When set to *notify*, foot will emit a desktop notification using
|
|
||||||
the command specified in the *notify* option, but only if the foot
|
|
||||||
window does *not* have keyboard focus.
|
|
||||||
|
|
||||||
When set to *none*, no special action is taken when receiving *BEL*.
|
|
||||||
|
|
||||||
Default: _none_.
|
|
||||||
|
|
||||||
*word-delimiters*
|
*word-delimiters*
|
||||||
String of characters that act as word delimiters when selecting
|
String of characters that act as word delimiters when selecting
|
||||||
text. Note that whitespace characters are _always_ word
|
text. Note that whitespace characters are _always_ word
|
||||||
|
|
@ -288,6 +262,39 @@ in this order:
|
||||||
Default: _url-mode_
|
Default: _url-mode_
|
||||||
|
|
||||||
|
|
||||||
|
# SECTION: bell
|
||||||
|
|
||||||
|
*urgent*
|
||||||
|
When set to _yes_, 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 name *urgent* 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).
|
||||||
|
|
||||||
|
Applications can enable/disable this feature programmatically with
|
||||||
|
the *CSI ? 1042 h* and *CSI ? 1042 l* escape sequences.
|
||||||
|
|
||||||
|
_Note_: expect this feature to be *replaced* with proper
|
||||||
|
compositor urgency support once/if that gets implemented.
|
||||||
|
Default: _no_
|
||||||
|
|
||||||
|
*notify*
|
||||||
|
When set to _yes_, foot will emit a desktop notification using
|
||||||
|
the command specified in the *notify* option whenever *BEL* is
|
||||||
|
received and the window does *not* have keyboard focus. Default:
|
||||||
|
_no_
|
||||||
|
|
||||||
|
*command*
|
||||||
|
When set, foot will execute this command when *BEL* is received.
|
||||||
|
Default: none
|
||||||
|
|
||||||
|
*command-focused*
|
||||||
|
Whether to run the command on *BEL* even while focused. Default:
|
||||||
|
_no_
|
||||||
|
|
||||||
|
|
||||||
# SECTION: scrollback
|
# SECTION: scrollback
|
||||||
|
|
||||||
*lines*
|
*lines*
|
||||||
|
|
|
||||||
6
foot.ini
6
foot.ini
|
|
@ -32,6 +32,12 @@
|
||||||
# workers=<number of logical CPUs>
|
# workers=<number of logical CPUs>
|
||||||
# osc8-underline=url-mode
|
# osc8-underline=url-mode
|
||||||
|
|
||||||
|
[bell]
|
||||||
|
# urgent=no
|
||||||
|
# notify=no
|
||||||
|
# command=
|
||||||
|
# command_focused=no
|
||||||
|
|
||||||
[scrollback]
|
[scrollback]
|
||||||
# lines=1000
|
# lines=1000
|
||||||
# multiplier=3.0
|
# multiplier=3.0
|
||||||
|
|
|
||||||
29
terminal.c
29
terminal.c
|
|
@ -2627,23 +2627,26 @@ term_flash(struct terminal *term, unsigned duration_ms)
|
||||||
void
|
void
|
||||||
term_bell(struct terminal *term)
|
term_bell(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (term->kbd_focus || !term->bell_action_enabled)
|
if (!term->bell_action_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (term->conf->bell_action) {
|
if (!term->kbd_focus) {
|
||||||
case BELL_ACTION_NONE:
|
if (term->conf->bell.urgent) {
|
||||||
break;
|
/* There's no 'urgency' hint in Wayland - we just paint the
|
||||||
|
* margins red */
|
||||||
|
term->render.urgency = true;
|
||||||
|
term_damage_margins(term);
|
||||||
|
}
|
||||||
|
if (term->conf->bell.notify)
|
||||||
|
notify_notify(term, "Bell", "Bell in terminal");
|
||||||
|
}
|
||||||
|
|
||||||
case BELL_ACTION_URGENT:
|
if ((term->conf->bell.command.argv != NULL) && (!term->kbd_focus || term->conf->bell.command_focused)) {
|
||||||
/* There's no 'urgency' hint in Wayland - we just paint the
|
int devnull = open("/dev/null", O_RDONLY);
|
||||||
* margins red */
|
spawn(term->reaper, NULL, term->conf->bell.command.argv, devnull, -1, -1);
|
||||||
term->render.urgency = true;
|
|
||||||
term_damage_margins(term);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BELL_ACTION_NOTIFY:
|
if (devnull >= 0)
|
||||||
notify_notify(term, "Bell", "Bell in terminal");
|
close(devnull);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue