mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-03 07:15:29 -04:00
term: scrolling: clear selection *before* scrolling
We normally don't clear the selection when scrolling. The exception is when the selection covers re-used rows. I.e. rows that we scroll in and clear. In this case we cancel the selection (we _could_ modify it and keep as much as possible and only remove the re-used rows...). We must do this *before* scrolling, since scrolling will swap rows (when there's a scrolling region). When this happens, the selection is "corrupted", and canceling it afterwards will not work.
This commit is contained in:
parent
e3992b8379
commit
a1c95562fb
1 changed files with 15 additions and 12 deletions
27
terminal.c
27
terminal.c
|
|
@ -1735,6 +1735,12 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const int begin_scrolled_in = max(region.end - rows, region.start);
|
||||||
|
const int end_scrolled_in = region.end;
|
||||||
|
|
||||||
|
if (selection_on_rows_in_view(term, begin_scrolled_in, end_scrolled_in - 1))
|
||||||
|
selection_cancel(term);
|
||||||
|
|
||||||
bool view_follows = term->grid->view == term->grid->offset;
|
bool view_follows = term->grid->view == term->grid->offset;
|
||||||
term->grid->offset += rows;
|
term->grid->offset += rows;
|
||||||
term->grid->offset &= term->grid->num_rows - 1;
|
term->grid->offset &= term->grid->num_rows - 1;
|
||||||
|
|
@ -1750,15 +1756,10 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
||||||
for (int i = term->rows - 1; i >= region.end; i--)
|
for (int i = term->rows - 1; i >= region.end; i--)
|
||||||
grid_swap_row(term->grid, i - rows, i, false);
|
grid_swap_row(term->grid, i - rows, i, false);
|
||||||
|
|
||||||
const int begin_scrolled_in = max(region.end - rows, region.start);
|
|
||||||
|
|
||||||
/* Erase scrolled in lines */
|
/* Erase scrolled in lines */
|
||||||
for (int r = begin_scrolled_in; r < region.end; r++)
|
for (int r = begin_scrolled_in; r < end_scrolled_in; r++)
|
||||||
erase_line(term, grid_row_and_alloc(term->grid, r));
|
erase_line(term, grid_row_and_alloc(term->grid, r));
|
||||||
|
|
||||||
if (selection_on_rows_in_view(term, begin_scrolled_in, region.end - 1))
|
|
||||||
selection_cancel(term);
|
|
||||||
|
|
||||||
sixel_delete_in_range(term, max(region.end - rows, region.start), region.end - 1);
|
sixel_delete_in_range(term, max(region.end - rows, region.start), region.end - 1);
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
||||||
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
||||||
|
|
@ -1784,6 +1785,13 @@ term_scroll_reverse_partial(struct terminal *term,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Row numbers of "new" lines scrolled in */
|
||||||
|
const int start_scrolled_in = region.start;
|
||||||
|
const int end_scrolled_in = min(region.start + rows, region.end);
|
||||||
|
|
||||||
|
if (selection_on_rows_in_view(term, start_scrolled_in, end_scrolled_in - 1))
|
||||||
|
selection_cancel(term);
|
||||||
|
|
||||||
bool view_follows = term->grid->view == term->grid->offset;
|
bool view_follows = term->grid->view == term->grid->offset;
|
||||||
term->grid->offset -= rows;
|
term->grid->offset -= rows;
|
||||||
while (term->grid->offset < 0)
|
while (term->grid->offset < 0)
|
||||||
|
|
@ -1804,15 +1812,10 @@ term_scroll_reverse_partial(struct terminal *term,
|
||||||
for (int i = 0 + rows; i < region.start + rows; i++)
|
for (int i = 0 + rows; i < region.start + rows; i++)
|
||||||
grid_swap_row(term->grid, i, i - rows, false);
|
grid_swap_row(term->grid, i, i - rows, false);
|
||||||
|
|
||||||
const int end_scrolled_in = min(region.start + rows, region.end);
|
|
||||||
|
|
||||||
/* Erase scrolled in lines */
|
/* Erase scrolled in lines */
|
||||||
for (int r = region.start; r < end_scrolled_in; r++)
|
for (int r = start_scrolled_in; r < end_scrolled_in; r++)
|
||||||
erase_line(term, grid_row_and_alloc(term->grid, r));
|
erase_line(term, grid_row_and_alloc(term->grid, r));
|
||||||
|
|
||||||
if (selection_on_rows_in_view(term, region.start, end_scrolled_in - 1))
|
|
||||||
selection_cancel(term);
|
|
||||||
|
|
||||||
sixel_delete_in_range(term, region.start, min(region.start + rows, region.end) - 1);
|
sixel_delete_in_range(term, region.start, min(region.start + rows, region.end) - 1);
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
||||||
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue