Merge branch 'master' into releases/1.23

This commit is contained in:
Daniel Eklöf 2025-07-23 08:27:25 +02:00
commit 5a01dbc234
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 136 additions and 34 deletions

View file

@ -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

30
fdm.c
View file

@ -18,6 +18,18 @@
#include "debug.h"
#include "xmalloc.h"
#if !defined(SIGABBREV_NP)
#include <stdio.h>
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;
}

23
main.c
View file

@ -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);

View file

@ -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 <string.h>')
add_project_arguments('-DSIGABBREV_NP', language: 'c')
endif
utmp_backend = get_option('utmp-backend')
if utmp_backend == 'auto'
host_os = host_machine.system()

69
osc.c
View file

@ -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:
/*

2
shm.c
View file

@ -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) {

View file

@ -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;

View file

@ -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;