Implement live-reload of config colors on SIGUSR1.

This commit is contained in:
wreald 2024-09-18 18:40:26 +10:00
parent a50f78c599
commit 341cdabdd2
7 changed files with 87 additions and 0 deletions

View file

@ -3276,6 +3276,7 @@ config_load(struct config *conf, const char *conf_path,
enum fcft_capabilities fcft_caps = fcft_capabilities();
*conf = (struct config) {
.path = NULL,
.term = xstrdup(FOOT_DEFAULT_TERM),
.shell = get_shell(),
.title = xstrdup("foot"),
@ -3517,6 +3518,8 @@ config_load(struct config *conf, const char *conf_path,
if (conf_file.path && conf_file.fd >= 0) {
LOG_INFO("loading configuration from %s", conf_file.path);
conf->path = xstrdup(conf_file.path);
FILE *f = fdopen(conf_file.fd, "r");
if (f == NULL) {
LOG_AND_NOTIFY_ERRNO("%s: failed to open", conf_file.path);
@ -3788,6 +3791,20 @@ config_clone(const struct config *old)
return conf;
}
void
config_reload_colors(struct config *conf)
{
user_notifications_t notifications = tll_init();
config_override_t overrides = tll_init();
struct config new_conf = {NULL};
config_load(&new_conf, conf->path, &notifications, &overrides, false, false);
// TODO: should we do something with any notifications that come from
// loading the config?
conf->colors = new_conf.colors;
}
UNITTEST
{
struct config original;
@ -3816,6 +3833,7 @@ UNITTEST
void
config_free(struct config *conf)
{
free(conf->path);
free(conf->term);
free(conf->shell);
free(conf->title);

View file

@ -132,6 +132,7 @@ struct custom_regex {
};
struct config {
char *path;
char *term;
char *shell;
char *title;
@ -423,6 +424,7 @@ bool config_load(
bool as_server);
void config_free(struct config *conf);
struct config *config_clone(const struct config *old);
void config_reload_colors(struct config *conf);
bool config_font_parse(const char *pattern, struct config_font *font);
void config_font_list_destroy(struct config_font_list *font_list);

24
main.c
View file

@ -45,6 +45,20 @@ fdm_sigint(struct fdm *fdm, int signo, void *data)
return true;
}
static bool
fdm_sigusr1_server(struct fdm *fdm, int signo, void *data)
{
server_hard_reload_config_colors(data);
return true;
}
static bool
fdm_sigusr1_term(struct fdm *fdm, int signo, void *data)
{
term_hard_reload_config_colors(data);
return true;
}
static void
print_usage(const char *prog_name)
{
@ -608,6 +622,15 @@ main(int argc, char *const *argv)
goto out;
}
bool ok = as_server ?
fdm_signal_add(fdm, SIGUSR1, fdm_sigusr1_server, server)
: fdm_signal_add(fdm, SIGUSR1, fdm_sigusr1_term, term);
if (!ok) {
LOG_WARN("failed to set SIGUSR1 handler");
goto out;
}
LOG_INFO("added USR1 handler");
struct sigaction sig_ign = {.sa_handler = SIG_IGN};
sigemptyset(&sig_ign.sa_mask);
if (sigaction(SIGHUP, &sig_ign, NULL) < 0 ||
@ -645,6 +668,7 @@ out:
reaper_destroy(reaper);
fdm_signal_del(fdm, SIGTERM);
fdm_signal_del(fdm, SIGINT);
fdm_signal_del(fdm, SIGUSR1);
fdm_destroy(fdm);
config_free(&conf);

View file

@ -591,6 +591,20 @@ err:
return NULL;
}
/* Reload configured colors from disk. */
void
server_hard_reload_config_colors(struct server *server) {
config_reload_colors((struct config *)server->conf);
tll_foreach(server->wayl->terms, it) {
struct terminal *term = it->item;
((struct config *)term->conf)->colors = server->conf->colors;
term_soft_reload_config_colors(term);
}
}
void
server_destroy(struct server *server)
{

View file

@ -9,3 +9,4 @@ struct server;
struct server *server_init(const struct config *conf, struct fdm *fdm,
struct reaper *reaper, struct wayland *wayl);
void server_destroy(struct server *server);
void server_hard_reload_config_colors(struct server *server);

View file

@ -4693,3 +4693,28 @@ term_send_size_notification(struct terminal *term)
term->rows, term->cols, height, width);
term_to_slave(term, buf, n);
}
/* Reload configured colors from disk. */
void
term_hard_reload_config_colors(struct terminal *term) {
config_reload_colors((struct config *)term->conf);
term_soft_reload_config_colors(term);
}
/* Reset colors to the in-memory config values. Does not reload the config from
disk. */
void
term_soft_reload_config_colors(struct terminal *term) {
term->colors.fg = term->conf->colors.fg;
term->colors.bg = term->conf->colors.bg;
term->colors.alpha = term->conf->colors.alpha;
term->colors.cursor_fg = term->conf->cursor.color.text;
term->colors.cursor_bg = term->conf->cursor.color.cursor;
term->colors.selection_fg = term->conf->colors.selection_fg;
term->colors.selection_bg = term->conf->colors.selection_bg;
memcpy(term->colors.table, term->conf->colors.table, sizeof(term->colors.table));
term_damage_all(term);
render_refresh(term);
}

View file

@ -982,6 +982,9 @@ void term_enable_size_notifications(struct terminal *term);
void term_disable_size_notifications(struct terminal *term);
void term_send_size_notification(struct terminal *term);
void term_hard_reload_config_colors(struct terminal *term);
void term_soft_reload_config_colors(struct terminal *term);
static inline void term_reset_grapheme_state(struct terminal *term)
{
#if defined(FOOT_GRAPHEME_CLUSTERING)