From 4847cc3bd1c32a7d188b3c2e226435842c51d1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 11 Oct 2023 18:19:31 +0200 Subject: [PATCH 1/5] changelog: add new 'unreleased' section --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa87ff4b..cd46e444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog +* [Unreleased](#unreleased) * [1.16.0](#1-16-0) * [1.15.3](#1-15-3) * [1.15.2](#1-15-2) @@ -46,6 +47,16 @@ * [1.2.0](#1-2-0) +## Unreleased +### Added +### Changed +### Deprecated +### Removed +### Fixed +### Security +### Contributors + + ## 1.16.0 ### Added From 7d7b48f10448cedc4806f77e58b8c89daecee614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 11 Oct 2023 18:39:43 +0200 Subject: [PATCH 2/5] changelog: fix link to issue 1077 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd46e444..4a520e29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,7 +63,7 @@ * Support for building with _wayland-protocols_ as a subproject. * Mouse wheel scrolls can now be used in `mouse-bindings` - ([#1077](1077)). + ([#1077][1077]). * New mouse bindings: `scrollback-up-mouse` and `scrollback-down-mouse`, bound to `BTN_BACK` and `BTN_FORWARD` respectively. From c006ac3a079d00e30f9d1cd7986d8112724629b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 12 Oct 2023 16:16:11 +0200 Subject: [PATCH 3/5] shm: memfd_create: fallback to not using MFD_NOEXEC_SEAL MFD_NOEXEC_SEAL was introduced in linux 6.3. Kernels before that will *reject* memfd_create() calls that set it. This caused foot to exit (i.e. not start at all), when compiled on linux >= 6.3, but run on linux < 6.3. We _do_ want to use MFD_NOEXEC_SEAL, since a) our memory mapped really shouldn't be executable, and b) to silence a warning on linux >= 6.3. To handle all cases, first try *with* MFD_NOEXEC_SEAL. If that fails with EINVAL, retry *without* it. Closes #1514 --- CHANGELOG.md | 5 +++++ shm.c | 21 ++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a520e29..39c22d87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,11 @@ ### Deprecated ### Removed ### Fixed +* Foot not starting on linux kernels before 6.3 ([#1514][1514]). + +[1514]: https://codeberg.org/dnkl/foot/issues/1514 + + ### Security ### Contributors diff --git a/shm.c b/shm.c index 8ca0ead0..171459f6 100644 --- a/shm.c +++ b/shm.c @@ -27,10 +27,8 @@ #define MAP_UNINITIALIZED 0 #endif -#if defined(MFD_NOEXEC_SEAL) - #define FOOT_MFD_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL) -#else - #define FOOT_MFD_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING) +#if !defined(MFD_NOEXEC_SEAL) + #define MFD_NOEXEC_SEAL 0 #endif #define TIME_SCROLL 0 @@ -339,7 +337,20 @@ get_new_buffers(struct buffer_chain *chain, size_t count, /* Backing memory for SHM */ #if defined(MEMFD_CREATE) - pool_fd = memfd_create("foot-wayland-shm-buffer-pool", FOOT_MFD_FLAGS); + /* + * Older kernels reject MFD_NOEXEC_SEAL with EINVAL. Try first + * *with* it, and if that fails, try again *without* it. + */ + errno = 0; + pool_fd = memfd_create( + "foot-wayland-shm-buffer-pool", + MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL); + + if (pool_fd < 0 && errno == EINVAL) { + pool_fd = memfd_create( + "foot-wayland-shm-buffer-pool", MFD_CLOEXEC | MFD_ALLOW_SEALING); + } + #elif defined(__FreeBSD__) // memfd_create on FreeBSD 13 is SHM_ANON without sealing support pool_fd = shm_open(SHM_ANON, O_RDWR | O_CLOEXEC, 0600); From 4aa67e464a04bf64d30aff70019ce0d8b4d5e136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 12 Oct 2023 16:22:50 +0200 Subject: [PATCH 4/5] sixel: erase: fix clearing of cell->attrs.clean When erasing a sixel, the cells underneath it must be marked as 'dirty', in order to be re-rendered. This was not being done correctly; the for loop loops *from* the start col, meaning the *end* col is *not* sixel->pos.col, as that's the *number* of columns, not the *end* column. --- sixel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sixel.c b/sixel.c index bd2ebe1d..8a0b130f 100644 --- a/sixel.c +++ b/sixel.c @@ -180,7 +180,7 @@ sixel_erase(struct terminal *term, struct sixel *sixel) row->dirty = true; - for (int c = sixel->pos.col; c < min(sixel->cols, term->cols); c++) + for (int c = sixel->pos.col; c < min(sixel->pos.col + sixel->cols, term->cols); c++) row->cells[c].attrs.clean = 0; } From f5f2f5a954ee6cf3532a6aba023860ada183d486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 12 Oct 2023 16:24:15 +0200 Subject: [PATCH 5/5] render: fix surface damage when rendering sixels. Pass a damage region to render_row()/render_cell() when rendering partially visible cells underneath a sixel. This ensures the affected regions are later reported as 'damaged' to the Wayland compositor. Closes #1515 --- CHANGELOG.md | 3 +++ render.c | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39c22d87..f276e493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,9 +53,12 @@ ### Deprecated ### Removed ### Fixed + * Foot not starting on linux kernels before 6.3 ([#1514][1514]). +* Cells underneath erased sixels not being repainted ([#1515][1515]). [1514]: https://codeberg.org/dnkl/foot/issues/1514 +[1515]: https://codeberg.org/dnkl/foot/issues/1515 ### Security diff --git a/render.c b/render.c index 81e9a0a4..11d323d5 100644 --- a/render.c +++ b/render.c @@ -1199,7 +1199,8 @@ render_sixel_chunk(struct terminal *term, pixman_image_t *pix, const struct sixe static void render_sixel(struct terminal *term, pixman_image_t *pix, - const struct coord *cursor, const struct sixel *sixel) + pixman_region32_t *damage, const struct coord *cursor, + const struct sixel *sixel) { xassert(sixel->pix != NULL); xassert(sixel->width >= 0); @@ -1293,8 +1294,7 @@ render_sixel(struct terminal *term, pixman_image_t *pix, */ if (!sixel->opaque) { /* TODO: multithreading */ - int cursor_col = cursor->row == term_row_no ? cursor->col : -1; - render_row(term, pix, NULL, row, term_row_no, cursor_col); + render_row(term, pix, damage, row, term_row_no, cursor_col); } else { for (int col = sixel->pos.col; col < min(sixel->pos.col + sixel->cols, term->cols); @@ -1309,7 +1309,7 @@ render_sixel(struct terminal *term, pixman_image_t *pix, if ((last_row_needs_erase && last_row) || (last_col_needs_erase && last_col)) { - render_cell(term, pix, NULL, row, term_row_no, col, cursor_col == col); + render_cell(term, pix, damage, row, term_row_no, col, cursor_col); } else { cell->attrs.clean = 1; cell->attrs.confined = 1; @@ -1333,6 +1333,7 @@ render_sixel(struct terminal *term, pixman_image_t *pix, static void render_sixel_images(struct terminal *term, pixman_image_t *pix, + pixman_region32_t *damage, const struct coord *cursor) { if (likely(tll_length(term->grid->sixel_images)) == 0) @@ -1370,7 +1371,7 @@ render_sixel_images(struct terminal *term, pixman_image_t *pix, } sixel_sync_cache(term, &it->item); - render_sixel(term, pix, cursor, &it->item); + render_sixel(term, pix, damage, cursor, &it->item); } } @@ -2974,7 +2975,10 @@ grid_render(struct terminal *term) } } - render_sixel_images(term, buf->pix[0], &cursor); + pixman_region32_t damage; + pixman_region32_init(&damage); + + render_sixel_images(term, buf->pix[0], &damage, &cursor); if (term->render.workers.count > 0) { mtx_lock(&term->render.workers.lock); @@ -2985,9 +2989,6 @@ grid_render(struct terminal *term) xassert(tll_length(term->render.workers.queue) == 0); } - pixman_region32_t damage; - pixman_region32_init(&damage); - for (int r = 0; r < term->rows; r++) { struct row *row = grid_row_in_view(term->grid, r);