From 5a895202740963971423ee27d5c0f77a4a3f84cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 5 Jan 2020 15:16:40 +0100 Subject: [PATCH] render: ensure cursor is always visible in the search box Maintain a view 'offset' (which glyph from the search string to start rendering at). This defines the start of the viewable area. The end is the offset + the search box size (which is limited to the window size). Adjust this offset whenever the cursor moves outside the viewable area. For now, this is always done in the same way: set the offset to the cursor position. This means that when we're entering text at the end of the search criteria (i.e. the normal case; we're simply typing), and the search box reaches the window size, the cursor will jump to the start of the search box, which will be empty. This could be confusing, but let's go with for now. --- render.c | 32 ++++++++++++++++++++++++++------ search.c | 1 + terminal.h | 2 ++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/render.c b/render.c index 403c62ef..93eb1399 100644 --- a/render.c +++ b/render.c @@ -886,10 +886,19 @@ render_search_box(struct terminal *term) { assert(term->window->search_sub_surface != NULL); + const size_t wanted_visible_chars = max(20, term->search.len); + const int scale = term->scale >= 1 ? term->scale : 1; - const int margin = scale * 3; - const int width = min(term->width, 2 * margin + max(20, term->search.len) * term->cell_width); - const int height = min(term->height, 2 * margin + 1 * term->cell_height); + const size_t margin = scale * 3; + + const size_t width = min( + term->width - 2 * margin, + 2 * margin + wanted_visible_chars * term->cell_width); + const size_t height = min( + term->height - 2 * margin, + 2 * margin + 1 * term->cell_height); + + const size_t visible_chars = (width - 2 * margin) / term->cell_width; unsigned long cookie = (uintptr_t)term + 1; struct buffer *buf = shm_get_buffer(term->wl->shm, width, height, cookie); @@ -908,8 +917,19 @@ render_search_box(struct terminal *term) int y = margin; pixman_color_t fg = color_hex_to_pixman(term->colors.table[0]); + if (term->search.cursor < term->render.search_offset || + term->search.cursor >= term->render.search_offset + visible_chars + 2) + { + /* Make sure cursor is always visible */ + term->render.search_offset = term->search.cursor; + } + /* Text (what the user entered - *not* match(es)) */ - for (size_t i = 0; i < term->search.len; i++) { + for (size_t i = term->render.search_offset; + i < term->search.len && + i - term->render.search_offset < visible_chars + 1; + i++) + { if (i == term->search.cursor) draw_bar(term, buf->pix, font, &fg, x, y); @@ -932,8 +952,8 @@ render_search_box(struct terminal *term) wl_subsurface_set_position( term->window->search_sub_surface, - max(0, term->width - width - margin), - max(0, term->height - height - margin)); + max(0, (int32_t)term->width - width - margin), + max(0, (int32_t)term->height - height - margin)); wl_surface_damage_buffer(term->window->search_surface, 0, 0, width, height); wl_surface_attach(term->window->search_surface, buf->wl_buf, 0, 0); diff --git a/search.c b/search.c index 6eef411c..408c08bd 100644 --- a/search.c +++ b/search.c @@ -51,6 +51,7 @@ search_cancel_keep_selection(struct terminal *term) term->search.match = (struct coord){-1, -1}; term->search.match_len = 0; term->is_searching = false; + term->render.search_offset = 0; term_xcursor_update(term); render_refresh(term); diff --git a/terminal.h b/terminal.h index e12a914e..287663e9 100644 --- a/terminal.h +++ b/terminal.h @@ -310,6 +310,8 @@ struct terminal { bool was_flashing; /* Flash was active last time we rendered */ bool was_searching; + size_t search_offset; + bool presentation_timings; struct timespec input_time; struct timespec commit_time;