diff --git a/CHANGELOG.md b/CHANGELOG.md index 8985905e..96040e86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog +* [Unreleased](#unreleased) * [1.23.0](#1-23-0) * [1.22.3](#1-22-3) * [1.22.2](#1-22-2) @@ -63,6 +64,34 @@ * [1.2.0](#1-2-0) +## Unreleased +### Added +### Changed + +* URL labels are now assigned in reverse order, from bottom to + top. This ensures the **last** URL (which is often the one you are + interested in) is always assigned the same key ([#2140][2140]). +* Sending `SIGUSR1` no longer **toggles** between `[colors]` and + `[colors2]`, but explicitly changes to `[colors]`. `SIGUSR2` changes + to `[colors2]` ([#2144][2144]). + +[2140]: https://codeberg.org/dnkl/foot/issues/2140 +[2144]: https://codeberg.org/dnkl/foot/issues/2144 + + +### Deprecated +### Removed +### Fixed + +* 10-bit surfaces sometimes used instead of 16-bit. +* OSC-104/110/111/112/117/119 (reset colors) not taking the currently + active theme into account. + + +### Security +### Contributors + + ## 1.23.0 ### Added diff --git a/fdm.c b/fdm.c index ea30443b..4822cd97 100644 --- a/fdm.c +++ b/fdm.c @@ -18,6 +18,18 @@ #include "debug.h" #include "xmalloc.h" +#if !defined(SIGABBREV_NP) +#include + +static const char * +sigabbrev_np(int sig) +{ + static char buf[16]; + snprintf(buf, sizeof(buf), "<%d>", sig); + return buf; +} +#endif + struct fd_handler { int fd; int events; @@ -113,7 +125,8 @@ fdm_destroy(struct fdm *fdm) for (int i = 0; i < SIGRTMAX; i++) { if (fdm->signal_handlers[i].callback != NULL) - LOG_WARN("handler for signal %d not removed", i); + LOG_WARN("handler for signal %d (SIG%s) not removed", + i, sigabbrev_np(i)); } if (tll_length(fdm->hooks_low) > 0 || @@ -338,7 +351,8 @@ bool fdm_signal_add(struct fdm *fdm, int signo, fdm_signal_handler_t handler, void *data) { if (fdm->signal_handlers[signo].callback != NULL) { - LOG_ERR("signal %d already has a handler", signo); + LOG_ERR("signal %d (SIG%s) already has a handler", + signo, sigabbrev_np(signo)); return false; } @@ -347,14 +361,16 @@ fdm_signal_add(struct fdm *fdm, int signo, fdm_signal_handler_t handler, void *d sigaddset(&mask, signo); if (sigprocmask(SIG_BLOCK, &mask, &original) < 0) { - LOG_ERRNO("failed to block signal %d", signo); + LOG_ERRNO("failed to block signal %d (SIG%s)", + signo, sigabbrev_np(signo)); return false; } struct sigaction action = {.sa_handler = &signal_handler}; sigemptyset(&action.sa_mask); if (sigaction(signo, &action, NULL) < 0) { - LOG_ERRNO("failed to set signal handler for signal %d", signo); + LOG_ERRNO("failed to set signal handler for signal %d (SIG%s)", + signo, sigabbrev_np(signo)); sigprocmask(SIG_SETMASK, &original, NULL); return false; } @@ -374,7 +390,8 @@ fdm_signal_del(struct fdm *fdm, int signo) struct sigaction action = {.sa_handler = SIG_DFL}; sigemptyset(&action.sa_mask); if (sigaction(signo, &action, NULL) < 0) { - LOG_ERRNO("failed to restore signal handler for signal %d", signo); + LOG_ERRNO("failed to restore signal handler for signal %d (SIG%s)", + signo, sigabbrev_np(signo)); return false; } @@ -386,7 +403,8 @@ fdm_signal_del(struct fdm *fdm, int signo) sigemptyset(&mask); sigaddset(&mask, signo); if (sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) { - LOG_ERRNO("failed to unblock signal %d", signo); + LOG_ERRNO("failed to unblock signal %d (SIG%s)", + signo, sigabbrev_np(signo)); return false; } diff --git a/main.c b/main.c index 37bbb6a7..f97f21b5 100644 --- a/main.c +++ b/main.c @@ -46,13 +46,22 @@ fdm_sigint(struct fdm *fdm, int signo, void *data) } static bool -fdm_sigusr1(struct fdm *fdm, int signo, void *data) +fdm_sigusr(struct fdm *fdm, int signo, void *data) { struct wayland *wayl = data; - tll_foreach(wayl->terms, it) { - struct terminal *term = it->item; - term_theme_toggle(term); + xassert(signo == SIGUSR1 || signo == SIGUSR2); + + if (signo == SIGUSR1) { + tll_foreach(wayl->terms, it) { + struct terminal *term = it->item; + term_theme_switch_to_1(term); + } + } else { + tll_foreach(wayl->terms, it) { + struct terminal *term = it->item; + term_theme_switch_to_2(term); + } } return true; @@ -621,8 +630,11 @@ main(int argc, char *const *argv) goto out; } - if (!fdm_signal_add(fdm, SIGUSR1, &fdm_sigusr1, wayl)) + if (!fdm_signal_add(fdm, SIGUSR1, &fdm_sigusr, wayl) || + !fdm_signal_add(fdm, SIGUSR2, &fdm_sigusr, wayl)) + { goto out; + } struct sigaction sig_ign = {.sa_handler = SIG_IGN}; sigemptyset(&sig_ign.sa_mask); @@ -660,6 +672,7 @@ out: key_binding_manager_destroy(key_binding_manager); reaper_destroy(reaper); fdm_signal_del(fdm, SIGUSR1); + fdm_signal_del(fdm, SIGUSR2); fdm_signal_del(fdm, SIGTERM); fdm_signal_del(fdm, SIGINT); fdm_destroy(fdm); diff --git a/meson.build b/meson.build index b9994c11..8a072dcf 100644 --- a/meson.build +++ b/meson.build @@ -25,6 +25,12 @@ if cc.has_function('execvpe', add_project_arguments('-DEXECVPE', language: 'c') endif +if cc.has_function('sigabbrev_np', + args: ['-D_GNU_SOURCE'], + prefix: '#include ') + add_project_arguments('-DSIGABBREV_NP', language: 'c') +endif + utmp_backend = get_option('utmp-backend') if utmp_backend == 'auto' host_os = host_machine.system() diff --git a/osc.c b/osc.c index 834029c1..0b492564 100644 --- a/osc.c +++ b/osc.c @@ -1515,10 +1515,14 @@ osc_dispatch(struct terminal *term) case 104: { /* Reset Color Number 'c' (whole table if no parameter) */ + const struct color_theme *theme = + term->colors.active_theme == COLOR_THEME1 + ? &term->conf->colors + : &term->conf->colors2; + if (string[0] == '\0') { LOG_DBG("resetting all colors"); - for (size_t i = 0; i < ALEN(term->colors.table); i++) - term->colors.table[i] = term->conf->colors.table[i]; + memcpy(term->colors.table, theme->table, sizeof(term->colors.table)); term_damage_view(term); } @@ -1540,7 +1544,7 @@ osc_dispatch(struct terminal *term) } LOG_DBG("resetting color #%u", idx); - term->colors.table[idx] = term->conf->colors.table[idx]; + term->colors.table[idx] = theme->table[idx]; term_damage_color(term, COLOR_BASE256, idx); } @@ -1553,16 +1557,28 @@ osc_dispatch(struct terminal *term) case 110: /* Reset default text foreground color */ LOG_DBG("resetting foreground color"); - term->colors.fg = term->conf->colors.fg; + + const struct color_theme *theme = + term->colors.active_theme == COLOR_THEME1 + ? &term->conf->colors + : &term->conf->colors2; + + term->colors.fg = theme->fg; term_damage_color(term, COLOR_DEFAULT, 0); break; case 111: { /* Reset default text background color */ LOG_DBG("resetting background color"); - bool alpha_changed = term->colors.alpha != term->conf->colors.alpha; - term->colors.bg = term->conf->colors.bg; - term->colors.alpha = term->conf->colors.alpha; + const struct color_theme *theme = + term->colors.active_theme == COLOR_THEME1 + ? &term->conf->colors + : &term->conf->colors2; + + bool alpha_changed = term->colors.alpha != theme->alpha; + + term->colors.bg = theme->bg; + term->colors.alpha = theme->alpha; if (alpha_changed) { wayl_win_alpha_changed(term->window); @@ -1574,10 +1590,16 @@ osc_dispatch(struct terminal *term) break; } - case 112: + case 112: { LOG_DBG("resetting cursor color"); - term->colors.cursor_fg = term->conf->colors.cursor.text; - term->colors.cursor_bg = term->conf->colors.cursor.cursor; + + const struct color_theme *theme = + term->colors.active_theme == COLOR_THEME1 + ? &term->conf->colors + : &term->conf->colors2; + + term->colors.cursor_fg = theme->cursor.text; + term->colors.cursor_bg = theme->cursor.cursor; if (term->conf->colors.use_custom.cursor) { term->colors.cursor_fg |= 1u << 31; @@ -1586,16 +1608,31 @@ osc_dispatch(struct terminal *term) term_damage_cursor(term); break; + } - case 117: + case 117: { LOG_DBG("resetting selection background color"); - term->colors.selection_bg = term->conf->colors.selection_bg; - break; - case 119: - LOG_DBG("resetting selection foreground color"); - term->colors.selection_fg = term->conf->colors.selection_fg; + const struct color_theme *theme = + term->colors.active_theme == COLOR_THEME1 + ? &term->conf->colors + : &term->conf->colors2; + + term->colors.selection_bg = theme->selection_bg; break; + } + + case 119: { + LOG_DBG("resetting selection foreground color"); + + const struct color_theme *theme = + term->colors.active_theme == COLOR_THEME1 + ? &term->conf->colors + : &term->conf->colors2; + + term->colors.selection_fg = theme->selection_fg; + break; + } case 133: /* diff --git a/shm.c b/shm.c index b586b504..4680c12c 100644 --- a/shm.c +++ b/shm.c @@ -994,7 +994,7 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances, pixman_fmt_without_alpha = PIXMAN_a16b16g16r16; shm_fmt_without_alpha = WL_SHM_FORMAT_XBGR16161616; - pixman_fmt_without_alpha = PIXMAN_a16b16g16r16; + pixman_fmt_with_alpha = PIXMAN_a16b16g16r16; shm_fmt_with_alpha = WL_SHM_FORMAT_ABGR16161616; if (!have_logged) { diff --git a/terminal.c b/terminal.c index 135f21ce..2e23f749 100644 --- a/terminal.c +++ b/terminal.c @@ -1409,6 +1409,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, pixman_region32_init(&term->render.last_overlay_clip); term_update_ascii_printer(term); + memcpy(term->colors.table, theme->table, sizeof(term->colors.table)); for (size_t i = 0; i < 4; i++) { const struct config_font_list *font_list = &conf->fonts[i]; @@ -1443,8 +1444,6 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, xassert(tll_length(term->wl->monitors) > 0); term->scale = tll_front(term->wl->monitors).scale; - memcpy(term->colors.table, theme->table, sizeof(term->colors.table)); - /* Initialize the Wayland window backend */ if ((term->window = wayl_win_init(term, token)) == NULL) goto err; diff --git a/url-mode.c b/url-mode.c index 35843219..c25396cd 100644 --- a/url-mode.c +++ b/url-mode.c @@ -634,12 +634,12 @@ urls_assign_key_combos(const struct config *conf, url_list_t *urls) size_t combo_idx = 0; - tll_foreach(*urls, it) { + tll_rforeach(*urls, it) { bool id_already_seen = false; /* Look for already processed URLs where both the URI and the * ID matches */ - tll_foreach(*urls, it2) { + tll_rforeach(*urls, it2) { if (&it->item == &it2->item) break; @@ -659,7 +659,7 @@ urls_assign_key_combos(const struct config *conf, url_list_t *urls) * them; if so, reuse the *same* key combo. */ bool url_already_seen = false; - tll_foreach(*urls, it2) { + tll_rforeach(*urls, it2) { if (&it->item == &it2->item) break; @@ -679,7 +679,7 @@ urls_assign_key_combos(const struct config *conf, url_list_t *urls) free(combos[i]); #if defined(_DEBUG) && LOG_ENABLE_DBG - tll_foreach(*urls, it) { + tll_rforeach(*urls, it) { if (it->item.key == NULL) continue;