mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-05 07:15:30 -04:00
notify: break out desktop notifications from osc.c
This commit is contained in:
parent
21cc68d49e
commit
03cbb6ad90
5 changed files with 117 additions and 91 deletions
|
|
@ -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',
|
||||||
|
|
|
||||||
103
notify.c
Normal file
103
notify.c
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
#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 (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);
|
||||||
93
osc.c
93
osc.c
|
|
@ -3,10 +3,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#define LOG_MODULE "osc"
|
#define LOG_MODULE "osc"
|
||||||
#define LOG_ENABLE_DBG 0
|
#define LOG_ENABLE_DBG 0
|
||||||
|
|
@ -14,9 +10,9 @@
|
||||||
#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 "spawn.h"
|
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
#include "uri.h"
|
#include "uri.h"
|
||||||
#include "vt.h"
|
#include "vt.h"
|
||||||
|
|
@ -408,92 +404,7 @@ osc_notify(struct terminal *term, char *string)
|
||||||
const char *title = strtok_r(string, ";", &ctx);
|
const char *title = strtok_r(string, ";", &ctx);
|
||||||
const char *msg = strtok_r(NULL, "\x00", &ctx);
|
const char *msg = strtok_r(NULL, "\x00", &ctx);
|
||||||
|
|
||||||
LOG_DBG("notify: title=\"%s\", msg=\"%s\"", title, msg);
|
notify_notify(term, title, msg);
|
||||||
|
|
||||||
/* TODO: move everything below to a separate function, to be able
|
|
||||||
* to support multiple escape sequences */
|
|
||||||
|
|
||||||
if (title == NULL || msg == 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(msg, strlen(msg));
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue