term: cancel selection when scrolling wraps

If we scroll enough, we'll eventually end up wrapping around the
entire scrollback buffer. At this point, a selection is no longer
valid, so cancel it.

Note: this was very obvious when scrolling in the alt screen, since
its scrollback buffer is what you see on the screen (i.e. it has no
scrollback).
This commit is contained in:
Daniel Eklöf 2019-08-05 20:16:17 +02:00
parent 1e08d93528
commit c06f141189
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 23 additions and 2 deletions

View file

@ -24,6 +24,20 @@ selection_enabled(const struct terminal *term)
term->mouse_tracking != MOUSE_MOTION);
}
bool
selection_on_row_in_view(const struct terminal *term, int row_no)
{
if (term->selection.start.row == -1 || term->selection.end.row == -1)
return false;
const struct coord *start = &term->selection.start;
const struct coord *end = &term->selection.end;
assert(start->row <= end->row);
row_no += term->grid->view;
return row_no >= start->row && row_no <= end->row;
}
static char *
extract_selection(const struct terminal *term)
{

View file

@ -18,6 +18,7 @@ void selection_mark_word(struct terminal *term, int col, int row,
void selection_to_clipboard(struct terminal *term, uint32_t serial);
void selection_from_clipboard(struct terminal *term, uint32_t serial);
void selection_from_primary(struct terminal *term);
bool selection_on_row_in_view(const struct terminal *term, int row_no);
bool text_to_clipboard(struct terminal *term, char *text, uint32_t serial);
void text_from_clipboard(

View file

@ -282,8 +282,11 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
grid_swap_row(term->grid, i - rows, i);
/* Erase scrolled in lines */
for (int r = max(region.end - rows, 0); r < region.end; r++)
for (int r = max(region.end - rows, 0); r < region.end; r++) {
erase_line(term, grid_row(term->grid, r));
if (selection_on_row_in_view(term, r))
selection_cancel(term);
}
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
term->grid->cur_row = grid_row(term->grid, term->cursor.row);
@ -325,8 +328,11 @@ term_scroll_reverse_partial(struct terminal *term,
grid_swap_row(term->grid, i, i - rows);
/* Erase scrolled in lines */
for (int r = region.start; r < min(region.start + rows, region.end); r++)
for (int r = region.start; r < min(region.start + rows, region.end); r++) {
erase_line(term, grid_row(term->grid, r));
if (selection_on_row_in_view(term, r))
selection_cancel(term);
}
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
term->grid->cur_row = grid_row(term->grid, term->cursor.row);