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.
This commit is contained in:
Daniel Eklöf 2020-01-05 15:16:40 +01:00
parent ee7ff9501e
commit 5a89520274
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 29 additions and 6 deletions

View file

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

View file

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

View file

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