From 76d494484f0b26f7785c0964cc412609d09607ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 30 Nov 2022 10:51:45 +0100 Subject: [PATCH] url-mode: tag cells after snapshot:ing the grid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this patch, hyperlinked cells were tagged with the “URL” attribute (thus instructing the renderer to draw an underline) *before* the grid was snapshot. When exiting URL mode, the cells were once again updated, this time removing the URL attribute. But what if an escape sequence had modified the grid _while we were in URL mode_? Depending on the sequence, it could move cells around in such a way, that when exiting URL mode, the affected cells weren’t updated correctly. I.e. we left some cells with the URL attribute still set. The fix is simple: tag cells in the snapshot:ed grid only (which isn’t affected by any escape sequence received while in URL mode). Not in the *actual* grid (which _is_ affected). --- CHANGELOG.md | 1 + url-mode.c | 32 +++++++++++++++++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f7d033b..13b87f4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ * Scaling factor not being correctly applied when converting pt-or-px config values (e.g. letter offsets, line height etc). * Selection being stuck visually when `IL` and `DL`.` +* URL underlines sometimes still being visible after exiting URL mode. [1173]: https://codeberg.org/dnkl/foot/issues/1173 [1190]: https://codeberg.org/dnkl/foot/issues/1190 diff --git a/url-mode.c b/url-mode.c index 6fa16623..7d7ffd81 100644 --- a/url-mode.c +++ b/url-mode.c @@ -746,15 +746,18 @@ tag_cells_for_url(struct terminal *term, const struct url *url, bool value) if (url->url_mode_dont_change_url_attr) return; + struct grid *grid = term->url_grid_snapshot; + xassert(grid != NULL); + const struct coord *start = &url->range.start; const struct coord *end = &url->range.end; - size_t end_r = end->row & (term->grid->num_rows - 1); + size_t end_r = end->row & (grid->num_rows - 1); - size_t r = start->row & (term->grid->num_rows - 1); + size_t r = start->row & (grid->num_rows - 1); size_t c = start->col; - struct row *row = term->grid->rows[r]; + struct row *row = grid->rows[r]; row->dirty = true; while (true) { @@ -766,10 +769,10 @@ tag_cells_for_url(struct terminal *term, const struct url *url, bool value) break; if (++c >= term->cols) { - r = (r + 1) & (term->grid->num_rows - 1); + r = (r + 1) & (grid->num_rows - 1); c = 0; - row = term->grid->rows[r]; + row = grid->rows[r]; if (row == NULL) { /* Un-allocated scrollback. This most likely means a * runaway OSC-8 URL. */ @@ -788,15 +791,6 @@ urls_render(struct terminal *term) if (tll_length(win->term->urls) == 0) return; - xassert(tll_length(win->urls) == 0); - tll_foreach(win->term->urls, it) { - struct wl_url url = {.url = &it->item}; - wayl_win_subsurface_new(win, &url.surf, false); - - tll_push_back(win->urls, url); - tag_cells_for_url(term, &it->item, true); - } - /* Dirty the last cursor, to ensure it is erased */ { struct row *cursor_row = term->render.last_cursor.row; @@ -819,6 +813,15 @@ urls_render(struct terminal *term) /* Snapshot the current grid */ term->url_grid_snapshot = grid_snapshot(term->grid); + xassert(tll_length(win->urls) == 0); + tll_foreach(win->term->urls, it) { + struct wl_url url = {.url = &it->item}; + wayl_win_subsurface_new(win, &url.surf, false); + + tll_push_back(win->urls, url); + tag_cells_for_url(term, &it->item, true); + } + render_refresh_urls(term); render_refresh(term); } @@ -860,7 +863,6 @@ urls_reset(struct terminal *term) } tll_foreach(term->urls, it) { - tag_cells_for_url(term, &it->item, false); url_destroy(&it->item); tll_remove(term->urls, it); }