mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-08 08:20:59 -04:00
commit
934466bc84
13 changed files with 262 additions and 31 deletions
|
|
@ -86,6 +86,12 @@ means foot can be PGO:d in e.g. sandboxed build scripts. See
|
||||||
* `DECSET` escape to modify the `escape` key to send `\E[27;1;27~`
|
* `DECSET` escape to modify the `escape` key to send `\E[27;1;27~`
|
||||||
instead of `\E`: `CSI ? 27127 h` enables the new behavior, `CSI ?
|
instead of `\E`: `CSI ? 27127 h` enables the new behavior, `CSI ?
|
||||||
27127 l` disables it (the default).
|
27127 l` disables it (the default).
|
||||||
|
* OSC 777;notify: desktop notifications. Use in combination with the
|
||||||
|
new **notify** option in `foot.ini`
|
||||||
|
(https://codeberg.org/dnkl/foot/issues/224).
|
||||||
|
* **bell** option can now be set to `notify`, in which case a desktop
|
||||||
|
notification is emitted when foot receives `BEL` in an unfocused
|
||||||
|
window.
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
||||||
44
config.c
44
config.c
|
|
@ -483,14 +483,17 @@ 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)
|
if (strcmp(value, "set-urgency") == 0)
|
||||||
conf->bell_is_urgent = true;
|
conf->bell_action = BELL_ACTION_URGENT;
|
||||||
|
else if (strcmp(value, "notify") == 0)
|
||||||
|
conf->bell_action = BELL_ACTION_NOTIFY;
|
||||||
else if (strcmp(value, "none") == 0)
|
else if (strcmp(value, "none") == 0)
|
||||||
conf->bell_is_urgent = false;
|
conf->bell_action = BELL_ACTION_NONE;
|
||||||
else {
|
else {
|
||||||
LOG_AND_NOTIFY_ERR(
|
LOG_AND_NOTIFY_ERR(
|
||||||
"%s:%d: [default]: bell: "
|
"%s:%d: [default]: bell: "
|
||||||
"expected either 'set-urgency' or 'none'", path, lineno);
|
"expected either 'set-urgency', 'notify' or 'none'",
|
||||||
conf->bell_is_urgent = false;
|
path, lineno);
|
||||||
|
conf->bell_action = BELL_ACTION_NONE;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -566,6 +569,27 @@ parse_section_main(const char *key, const char *value, struct config *conf,
|
||||||
mbstowcs(conf->word_delimiters, value, chars + 1);
|
mbstowcs(conf->word_delimiters, value, chars + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (strcmp(key, "notify") == 0) {
|
||||||
|
free(conf->notify.raw_cmd);
|
||||||
|
free(conf->notify.argv);
|
||||||
|
|
||||||
|
conf->notify.raw_cmd = NULL;
|
||||||
|
conf->notify.argv = NULL;
|
||||||
|
|
||||||
|
char *raw_cmd = xstrdup(value);
|
||||||
|
char **argv = NULL;
|
||||||
|
|
||||||
|
if (!tokenize_cmdline(raw_cmd, &argv)) {
|
||||||
|
LOG_AND_NOTIFY_ERR(
|
||||||
|
"%s:%d: [default]: notify: syntax error in command line",
|
||||||
|
path, lineno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf->notify.raw_cmd = raw_cmd;
|
||||||
|
conf->notify.argv = argv;
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
LOG_AND_NOTIFY_ERR("%s:%u: [default]: %s: invalid key", path, lineno, key);
|
LOG_AND_NOTIFY_ERR("%s:%u: [default]: %s: invalid key", path, lineno, key);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1924,7 +1948,7 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
.pad_x = 2,
|
.pad_x = 2,
|
||||||
.pad_y = 2,
|
.pad_y = 2,
|
||||||
.bold_in_bright = false,
|
.bold_in_bright = false,
|
||||||
.bell_is_urgent = 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()},
|
||||||
.dpi_aware = true, /* Use DPI by default, not scale factor */
|
.dpi_aware = true, /* Use DPI by default, not scale factor */
|
||||||
|
|
@ -1989,6 +2013,10 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
.server_socket_path = get_server_socket_path(),
|
.server_socket_path = get_server_socket_path(),
|
||||||
.presentation_timings = false,
|
.presentation_timings = false,
|
||||||
.hold_at_exit = false,
|
.hold_at_exit = false,
|
||||||
|
.notify = {
|
||||||
|
.raw_cmd = NULL,
|
||||||
|
.argv = NULL,
|
||||||
|
},
|
||||||
|
|
||||||
.tweak = {
|
.tweak = {
|
||||||
.fcft_filter = FCFT_SCALING_FILTER_LANCZOS3,
|
.fcft_filter = FCFT_SCALING_FILTER_LANCZOS3,
|
||||||
|
|
@ -2004,6 +2032,10 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
.notifications = tll_init(),
|
.notifications = tll_init(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
conf->notify.raw_cmd = xstrdup(
|
||||||
|
"notify-send -a foot -i foot ${title} ${body}");
|
||||||
|
tokenize_cmdline(conf->notify.raw_cmd, &conf->notify.argv);
|
||||||
|
|
||||||
tll_foreach(*initial_user_notifications, it)
|
tll_foreach(*initial_user_notifications, it)
|
||||||
tll_push_back(conf->notifications, it->item);
|
tll_push_back(conf->notifications, it->item);
|
||||||
tll_free(*initial_user_notifications);
|
tll_free(*initial_user_notifications);
|
||||||
|
|
@ -2070,6 +2102,8 @@ config_free(struct config conf)
|
||||||
free(conf.app_id);
|
free(conf.app_id);
|
||||||
free(conf.word_delimiters);
|
free(conf.word_delimiters);
|
||||||
free(conf.scrollback.indicator.text);
|
free(conf.scrollback.indicator.text);
|
||||||
|
free(conf.notify.raw_cmd);
|
||||||
|
free(conf.notify.argv);
|
||||||
for (size_t i = 0; i < ALEN(conf.fonts); i++) {
|
for (size_t i = 0; i < ALEN(conf.fonts); i++) {
|
||||||
tll_foreach(conf.fonts[i], it)
|
tll_foreach(conf.fonts[i], it)
|
||||||
config_font_destroy(&it->item);
|
config_font_destroy(&it->item);
|
||||||
|
|
|
||||||
11
config.h
11
config.h
|
|
@ -72,7 +72,11 @@ struct config {
|
||||||
unsigned pad_y;
|
unsigned pad_y;
|
||||||
|
|
||||||
bool bold_in_bright;
|
bool bold_in_bright;
|
||||||
bool bell_is_urgent;
|
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;
|
||||||
|
|
||||||
|
|
@ -163,6 +167,11 @@ struct config {
|
||||||
bool presentation_timings;
|
bool presentation_timings;
|
||||||
bool hold_at_exit;
|
bool hold_at_exit;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char *raw_cmd;
|
||||||
|
char **argv;
|
||||||
|
} notify;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
enum fcft_scaling_filter fcft_filter;
|
enum fcft_scaling_filter fcft_filter;
|
||||||
bool allow_overflowing_double_width_glyphs;
|
bool allow_overflowing_double_width_glyphs;
|
||||||
|
|
|
||||||
6
csi.c
6
csi.c
|
|
@ -482,7 +482,7 @@ decset_decrst(struct terminal *term, unsigned param, bool enable)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1042:
|
case 1042:
|
||||||
term->bell_is_urgent = enable;
|
term->bell_action_enabled = enable;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -591,7 +591,7 @@ xtsave(struct terminal *term, unsigned param)
|
||||||
case 1034: term->xtsave.meta_eight_bit = term->meta.eight_bit; break;
|
case 1034: term->xtsave.meta_eight_bit = term->meta.eight_bit; break;
|
||||||
case 1035: term->xtsave.num_lock_modifier = term->num_lock_modifier; break;
|
case 1035: term->xtsave.num_lock_modifier = term->num_lock_modifier; break;
|
||||||
case 1036: term->xtsave.meta_esc_prefix = term->meta.esc_prefix; break;
|
case 1036: term->xtsave.meta_esc_prefix = term->meta.esc_prefix; break;
|
||||||
case 1042: term->xtsave.bell_is_urgent = term->bell_is_urgent; break;
|
case 1042: term->xtsave.bell_action_enabled = term->bell_action_enabled; break;
|
||||||
case 1049: term->xtsave.alt_screen = term->grid == &term->alt; break;
|
case 1049: term->xtsave.alt_screen = term->grid == &term->alt; break;
|
||||||
case 2004: term->xtsave.bracketed_paste = term->bracketed_paste; break;
|
case 2004: term->xtsave.bracketed_paste = term->bracketed_paste; break;
|
||||||
case 27127: term->xtsave.modify_escape_key = term->modify_escape_key; break;
|
case 27127: term->xtsave.modify_escape_key = term->modify_escape_key; break;
|
||||||
|
|
@ -626,7 +626,7 @@ xtrestore(struct terminal *term, unsigned param)
|
||||||
case 1034: enable = term->xtsave.meta_eight_bit; break;
|
case 1034: enable = term->xtsave.meta_eight_bit; break;
|
||||||
case 1035: enable = term->xtsave.num_lock_modifier; break;
|
case 1035: enable = term->xtsave.num_lock_modifier; break;
|
||||||
case 1036: enable = term->xtsave.meta_esc_prefix; break;
|
case 1036: enable = term->xtsave.meta_esc_prefix; break;
|
||||||
case 1042: enable = term->xtsave.bell_is_urgent; break;
|
case 1042: enable = term->xtsave.bell_action_enabled; break;
|
||||||
case 1049: enable = term->xtsave.alt_screen; break;
|
case 1049: enable = term->xtsave.alt_screen; break;
|
||||||
case 2004: enable = term->xtsave.bracketed_paste; break;
|
case 2004: enable = term->xtsave.bracketed_paste; break;
|
||||||
case 27127: enable = term->xtsave.modify_escape_key; break;
|
case 27127: enable = term->xtsave.modify_escape_key; break;
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ in this order:
|
||||||
|
|
||||||
*bell*
|
*bell*
|
||||||
Action to perform when receiving a *BEL* character. Can be set to
|
Action to perform when receiving a *BEL* character. Can be set to
|
||||||
either *set-urgency* or *none*.
|
either *set-urgency*, *notify* or *none*.
|
||||||
|
|
||||||
When set to *set-urgency*, the margins will be painted in red
|
When set to *set-urgency*, the margins will be painted in red
|
||||||
whenever *BEL* is received while the window does *not* have
|
whenever *BEL* is received while the window does *not* have
|
||||||
|
|
@ -136,6 +136,9 @@ in this order:
|
||||||
_Note_: expect this feature to be *replaced* with proper
|
_Note_: expect this feature to be *replaced* with proper
|
||||||
compositor urgency support once/if that gets implemented.
|
compositor urgency support once/if that gets implemented.
|
||||||
|
|
||||||
|
When set to *notify*, foot will emit a desktop notification (see
|
||||||
|
the *notify* option).
|
||||||
|
|
||||||
When set to *none*, no special action is taken when receiving *BEL*.
|
When set to *none*, no special action is taken when receiving *BEL*.
|
||||||
|
|
||||||
Default: _none_.
|
Default: _none_.
|
||||||
|
|
@ -145,6 +148,17 @@ in this order:
|
||||||
text. Note that whitespace characters are _always_ word
|
text. Note that whitespace characters are _always_ word
|
||||||
delimiters, regardless of this setting. Default: _,│`|:"'()[]{}<>_
|
delimiters, regardless of this setting. Default: _,│`|:"'()[]{}<>_
|
||||||
|
|
||||||
|
*notify*
|
||||||
|
Command to execute to display a notification. _${title}_ and
|
||||||
|
_${body}_ will be replaced with the notification's actual _title_
|
||||||
|
and _body_ (message content).
|
||||||
|
|
||||||
|
Applications can trigger notifications in the following ways:
|
||||||
|
|
||||||
|
- OSC 777: *\\e]777;notify;<title>;<body>\\e\\\\*
|
||||||
|
|
||||||
|
Default: _notify-send -a foot -i foot ${title} ${body}_.
|
||||||
|
|
||||||
|
|
||||||
# SECTION: scrollback
|
# SECTION: scrollback
|
||||||
|
|
||||||
|
|
|
||||||
1
foot.ini
1
foot.ini
|
|
@ -16,6 +16,7 @@
|
||||||
# bold-text-in-bright=no
|
# bold-text-in-bright=no
|
||||||
# bell=none
|
# bell=none
|
||||||
# word-delimiters=,│`|:"'()[]{}<>
|
# word-delimiters=,│`|:"'()[]{}<>
|
||||||
|
# notify=notify-send -a foot -i foot ${title} ${body}
|
||||||
|
|
||||||
[scrollback]
|
[scrollback]
|
||||||
# lines=1000
|
# lines=1000
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ executable(
|
||||||
'ime.c', 'ime.h',
|
'ime.c', 'ime.h',
|
||||||
'input.c', 'input.h',
|
'input.c', 'input.h',
|
||||||
'main.c',
|
'main.c',
|
||||||
|
'notify.c', 'notify.h',
|
||||||
'quirks.c', 'quirks.h',
|
'quirks.c', 'quirks.h',
|
||||||
'reaper.c', 'reaper.h',
|
'reaper.c', 'reaper.h',
|
||||||
'render.c', 'render.h',
|
'render.c', 'render.h',
|
||||||
|
|
|
||||||
108
notify.c
Normal file
108
notify.c
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include "notify.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#define LOG_MODULE "notify"
|
||||||
|
#define LOG_ENABLE_DBG 0
|
||||||
|
#include "log.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "spawn.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
notify_notify(const struct terminal *term, const char *title, const char *body)
|
||||||
|
{
|
||||||
|
LOG_DBG("notify: title=\"%s\", msg=\"%s\"", title, msg);
|
||||||
|
|
||||||
|
if (term->kbd_focus) {
|
||||||
|
/* No notifications while we’re focused */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title == NULL || body == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (term->conf->notify.argv == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t argv_size = 0;
|
||||||
|
for (; term->conf->notify.argv[argv_size] != NULL; argv_size++)
|
||||||
|
;
|
||||||
|
|
||||||
|
#define append(s, n) \
|
||||||
|
do { \
|
||||||
|
expanded = xrealloc(expanded, len + (n) + 1); \
|
||||||
|
memcpy(&expanded[len], s, n); \
|
||||||
|
len += n; \
|
||||||
|
expanded[len] = '\0'; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
char **argv = malloc((argv_size + 1) * sizeof(argv[0]));
|
||||||
|
|
||||||
|
/* Expand ${title} and ${body} */
|
||||||
|
for (size_t i = 0; i < argv_size; i++) {
|
||||||
|
size_t len = 0;
|
||||||
|
char *expanded = NULL;
|
||||||
|
|
||||||
|
char *start = NULL;
|
||||||
|
char *last_end = term->conf->notify.argv[i];
|
||||||
|
|
||||||
|
while ((start = strstr(last_end, "${")) != NULL) {
|
||||||
|
/* Append everything from the last template's end to this
|
||||||
|
* one's beginning */
|
||||||
|
append(last_end, start - last_end);
|
||||||
|
|
||||||
|
/* Find end of template */
|
||||||
|
start += 2;
|
||||||
|
char *end = strstr(start, "}");
|
||||||
|
|
||||||
|
if (end == NULL) {
|
||||||
|
/* Ensure final append() copies the unclosed '${' */
|
||||||
|
last_end = start - 2;
|
||||||
|
LOG_WARN("notify: unclosed template: %s", last_end);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expand template */
|
||||||
|
if (strncmp(start, "title", end - start) == 0)
|
||||||
|
append(title, strlen(title));
|
||||||
|
else if (strncmp(start, "body", end - start) == 0)
|
||||||
|
append(body, strlen(body));
|
||||||
|
else {
|
||||||
|
/* Unrecognized template - append it as-is */
|
||||||
|
start -= 2;
|
||||||
|
append(start, end + 1 - start);
|
||||||
|
LOG_WARN("notify: unrecognized template: %.*s",
|
||||||
|
(int)(end + 1 - start), start);
|
||||||
|
}
|
||||||
|
|
||||||
|
last_end = end + 1;;
|
||||||
|
}
|
||||||
|
|
||||||
|
append(last_end, term->conf->notify.argv[i] + strlen(term->conf->notify.argv[i]) - last_end);
|
||||||
|
argv[i] = expanded;
|
||||||
|
}
|
||||||
|
argv[argv_size] = NULL;
|
||||||
|
|
||||||
|
#undef append
|
||||||
|
|
||||||
|
LOG_DBG("notify command:");
|
||||||
|
for (size_t i = 0; i < argv_size; i++)
|
||||||
|
LOG_DBG(" argv[%zu] = \"%s\"", i, argv[i]);
|
||||||
|
|
||||||
|
/* Redirect stdin to /dev/null, but ignore failure to open */
|
||||||
|
int devnull = open("/dev/null", O_RDONLY);
|
||||||
|
spawn(term->reaper, NULL, argv, devnull, -1, -1);
|
||||||
|
|
||||||
|
if (devnull >= 0)
|
||||||
|
close(devnull);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < argv_size; i++)
|
||||||
|
free(argv[i]);
|
||||||
|
free(argv);
|
||||||
|
}
|
||||||
6
notify.h
Normal file
6
notify.h
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "terminal.h"
|
||||||
|
|
||||||
|
void notify_notify(
|
||||||
|
const struct terminal *term, const char *title, const char *body);
|
||||||
60
osc.c
60
osc.c
|
|
@ -10,6 +10,7 @@
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "grid.h"
|
#include "grid.h"
|
||||||
|
#include "notify.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "selection.h"
|
#include "selection.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
@ -374,22 +375,37 @@ osc_set_pwd(struct terminal *term, char *string)
|
||||||
free(host);
|
free(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void
|
static void
|
||||||
osc_notify(struct terminal *term, char *string)
|
osc_notify(struct terminal *term, char *string)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* The 'notify' perl extension
|
||||||
|
* (https://pub.phyks.me/scripts/urxvt/notify) is very simple:
|
||||||
|
*
|
||||||
|
* #!/usr/bin/perl
|
||||||
|
*
|
||||||
|
* sub on_osc_seq_perl {
|
||||||
|
* my ($term, $osc, $resp) = @_;
|
||||||
|
* if ($osc =~ /^notify;(\S+);(.*)$/) {
|
||||||
|
* system("notify-send '$1' '$2'");
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* As can be seen, the notification text is not encoded in any
|
||||||
|
* way. The regex does a greedy match of the ';' separator. Thus,
|
||||||
|
* any extra ';' will end up being part of the title. There's no
|
||||||
|
* way to have a ';' in the message body.
|
||||||
|
*
|
||||||
|
* I've changed that behavior slightly in; we split the title from
|
||||||
|
* body on the *first* ';', allowing us to have semicolons in the
|
||||||
|
* message body, but *not* in the title.
|
||||||
|
*/
|
||||||
char *ctx = NULL;
|
char *ctx = NULL;
|
||||||
const char *cmd = strtok_r(string, ";", &ctx);
|
const char *title = strtok_r(string, ";", &ctx);
|
||||||
const char *title = strtok_r(NULL, ";", &ctx);
|
const char *msg = strtok_r(NULL, "\x00", &ctx);
|
||||||
const char *msg = strtok_r(NULL, ";", &ctx);
|
|
||||||
|
|
||||||
LOG_DBG("cmd: \"%s\", title: \"%s\", msg: \"%s\"",
|
notify_notify(term, title, msg);
|
||||||
cmd, title, msg);
|
|
||||||
|
|
||||||
if (cmd == NULL || strcmp(cmd, "notify") != 0 || title == NULL || msg == NULL)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_color_in_grids(struct terminal *term, uint32_t old_color,
|
update_color_in_grids(struct terminal *term, uint32_t old_color,
|
||||||
|
|
@ -673,11 +689,27 @@ osc_dispatch(struct terminal *term)
|
||||||
osc_flash(term);
|
osc_flash(term);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
case 777: {
|
||||||
case 777:
|
/*
|
||||||
osc_notify(term, string);
|
* OSC 777 is an URxvt generic escape used to send commands to
|
||||||
|
* perl extensions. The generic syntax is: \E]777;<command>;<string>ST
|
||||||
|
*
|
||||||
|
* We only recognize the 'notify' command, which is, if not
|
||||||
|
* well established, at least fairly well known.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *param_brk = strchr(string, ';');
|
||||||
|
if (param_brk == NULL) {
|
||||||
|
UNHANDLED();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(string, "notify", param_brk - string) == 0)
|
||||||
|
osc_notify(term, param_brk + 1);
|
||||||
|
else
|
||||||
|
UNHANDLED();
|
||||||
break;
|
break;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UNHANDLED();
|
UNHANDLED();
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,11 @@ void cmd_scrollback_down(struct terminal *term, int rows) {}
|
||||||
void ime_enable(struct seat *seat) {}
|
void ime_enable(struct seat *seat) {}
|
||||||
void ime_disable(struct seat *seat) {}
|
void ime_disable(struct seat *seat) {}
|
||||||
|
|
||||||
|
void
|
||||||
|
notify_notify(const struct terminal *term, const char *title, const char *body)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, const char *const *argv)
|
main(int argc, const char *const *argv)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
25
terminal.c
25
terminal.c
|
|
@ -25,6 +25,7 @@
|
||||||
#include "extract.h"
|
#include "extract.h"
|
||||||
#include "grid.h"
|
#include "grid.h"
|
||||||
#include "ime.h"
|
#include "ime.h"
|
||||||
|
#include "notify.h"
|
||||||
#include "quirks.h"
|
#include "quirks.h"
|
||||||
#include "reaper.h"
|
#include "reaper.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
@ -1091,7 +1092,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
||||||
.eight_bit = true,
|
.eight_bit = true,
|
||||||
},
|
},
|
||||||
.num_lock_modifier = true,
|
.num_lock_modifier = true,
|
||||||
.bell_is_urgent = conf->bell_is_urgent,
|
.bell_action_enabled = true,
|
||||||
.tab_stops = tll_init(),
|
.tab_stops = tll_init(),
|
||||||
.wl = wayl,
|
.wl = wayl,
|
||||||
.render = {
|
.render = {
|
||||||
|
|
@ -1532,6 +1533,8 @@ term_reset(struct terminal *term, bool hard)
|
||||||
term->bracketed_paste = false;
|
term->bracketed_paste = false;
|
||||||
term->focus_events = false;
|
term->focus_events = false;
|
||||||
term->modify_escape_key = false;
|
term->modify_escape_key = false;
|
||||||
|
term->num_lock_modifier = true;
|
||||||
|
term->bell_action_enabled = true;
|
||||||
term->mouse_tracking = MOUSE_NONE;
|
term->mouse_tracking = MOUSE_NONE;
|
||||||
term->mouse_reporting = MOUSE_NORMAL;
|
term->mouse_reporting = MOUSE_NORMAL;
|
||||||
term->charsets.selected = 0;
|
term->charsets.selected = 0;
|
||||||
|
|
@ -2512,12 +2515,24 @@ 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_is_urgent)
|
if (term->kbd_focus || !term->bell_action_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* There's no 'urgency' hint in Wayland - we just paint the margins red */
|
switch (term->conf->bell_action) {
|
||||||
term->render.urgency = true;
|
case BELL_ACTION_NONE:
|
||||||
term_damage_margins(term);
|
break;
|
||||||
|
|
||||||
|
case BELL_ACTION_URGENT:
|
||||||
|
/* There's no 'urgency' hint in Wayland - we just paint the
|
||||||
|
* margins red */
|
||||||
|
term->render.urgency = true;
|
||||||
|
term_damage_margins(term);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BELL_ACTION_NOTIFY:
|
||||||
|
notify_notify(term, "Bell", "Bell in terminal");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ struct terminal {
|
||||||
} meta;
|
} meta;
|
||||||
|
|
||||||
bool num_lock_modifier;
|
bool num_lock_modifier;
|
||||||
bool bell_is_urgent;
|
bool bell_action_enabled;
|
||||||
|
|
||||||
/* Saved DECSET modes - we save the SET state */
|
/* Saved DECSET modes - we save the SET state */
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -295,7 +295,7 @@ struct terminal {
|
||||||
uint32_t meta_eight_bit:1;
|
uint32_t meta_eight_bit:1;
|
||||||
uint32_t meta_esc_prefix:1;
|
uint32_t meta_esc_prefix:1;
|
||||||
uint32_t num_lock_modifier:1;
|
uint32_t num_lock_modifier:1;
|
||||||
uint32_t bell_is_urgent:1;
|
uint32_t bell_action_enabled:1;
|
||||||
uint32_t alt_screen:1;
|
uint32_t alt_screen:1;
|
||||||
uint32_t modify_escape_key:1;
|
uint32_t modify_escape_key:1;
|
||||||
uint32_t ime:1;
|
uint32_t ime:1;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue