From 54b5ae95c1bb01c5103b3ce97a8faebe75e142bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 22 Feb 2021 10:22:41 +0100 Subject: [PATCH] url-mode: snapshot screen state when entering URL mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, we automatically exited URL mode whenever we received data on the PTY. This was done since we don’t know _what_ has changed on the screen, and we don’t want to display misleading jump labels. However, this becomes a problem in curses-like applications that periodically updates part of the screen. For example, a statusbar with a clock. This patch changes this behavior; instead of cancelling URL mode when receiving PTY data, we snapshot the grid when entering URL mode. When *rendering*, we use the snapshot:ed grid, while PTY updates modify the “real” grid. Snapshot:ing the grid means taking a full/deep copy of the current grid, including sixel images etc. Finally, it isn’t necessary to “damage” the entire view when *entering* URL mode, since we’re at that point the renderer is in sync with the grid. But we *do* need to damage the entire view when exiting URL mode, since the grid changes on the “real” grid hasn’t been tracked by the renderer. --- render.c | 16 ++++++++++++++++ terminal.c | 2 -- terminal.h | 2 ++ url-mode.c | 14 +++++++++++++- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/render.c b/render.c index 1db813bc..aa172284 100644 --- a/render.c +++ b/render.c @@ -2675,6 +2675,12 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da term->render.pending.title = false; term->render.pending.urls = false; + struct grid *original_grid = term->grid; + if (urls_mode_is_active(term)) { + xassert(term->url_grid_snapshot != NULL); + term->grid = term->url_grid_snapshot; + } + if (csd && term->window->use_csd == CSD_YES) { quirk_weston_csd_on(term); render_csd(term); @@ -2697,6 +2703,8 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da if (it->item.kbd_focus == term) ime_update_cursor_rect(&it->item, term); } + + term->grid = original_grid; } static void @@ -3127,6 +3135,12 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data) term->render.refresh.urls = false; if (term->window->frame_callback == NULL) { + struct grid *original_grid = term->grid; + if (urls_mode_is_active(term)) { + xassert(term->url_grid_snapshot != NULL); + term->grid = term->url_grid_snapshot; + } + if (csd && term->window->use_csd == CSD_YES) { quirk_weston_csd_on(term); render_csd(term); @@ -3145,6 +3159,8 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data) if (it->item.kbd_focus == term) ime_update_cursor_rect(&it->item, term); } + + term->grid = original_grid; } else { /* Tells the frame callback to render again */ term->render.pending.grid |= grid; diff --git a/terminal.c b/terminal.c index 57c9ae18..ac127851 100644 --- a/terminal.c +++ b/terminal.c @@ -227,8 +227,6 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data) cursor_blink_rearm_timer(term); } - urls_reset(term); - uint8_t buf[24 * 1024]; ssize_t count = sizeof(buf); diff --git a/terminal.h b/terminal.h index b1b7c391..2a6ae0b1 100644 --- a/terminal.h +++ b/terminal.h @@ -547,9 +547,11 @@ struct terminal { unsigned max_height; /* Maximum image height, in pixels */ } sixel; + /* TODO: wrap in a struct */ url_list_t urls; wchar_t url_keys[5]; bool urls_show_uri_on_jump_label; + struct grid *url_grid_snapshot; #if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED struct { diff --git a/url-mode.c b/url-mode.c index cea099e9..7fb60845 100644 --- a/url-mode.c +++ b/url-mode.c @@ -637,6 +637,9 @@ urls_render(struct terminal *term) tag_cells_for_url(term, &it->item, true); } + /* Snapshot the current grid */ + term->url_grid_snapshot = grid_snapshot(term->grid); + render_refresh_urls(term); render_refresh(term); } @@ -651,8 +654,15 @@ url_destroy(struct url *url) void urls_reset(struct terminal *term) { - if (likely(tll_length(term->urls) == 0)) + if (likely(tll_length(term->urls) == 0)) { + xassert(term->url_grid_snapshot == NULL); return; + } + + grid_free(term->url_grid_snapshot); + free(term->url_grid_snapshot); + term->url_grid_snapshot = NULL; + term->render.last_cursor.row = NULL; if (term->window != NULL) { tll_foreach(term->window->urls, it) { @@ -669,5 +679,7 @@ urls_reset(struct terminal *term) term->urls_show_uri_on_jump_label = false; memset(term->url_keys, 0, sizeof(term->url_keys)); + + term_damage_view(term); render_refresh(term); }