sixel: scroll-up: don’t break out early of loop

This function loops the list of sixels, and discards those that would
be scrolled out if the grid offset is moved forward by the specified
number of rows.

The criteria is when the rebased row value is less than the number of
rows to scroll.

A rebased row number is a zero-based number starting at the beginning
of the scrollback. Thus, when scrolling 5 rows, rows with a rebased
row number between 0-4 will be scrolled out.

For performance reasons, we used to break out of the loop as soon as a
row number *larger* than the scroll count.

This however does not work. The sixels are sorted by their *end*
row. While this works in most cases (think images outputted in the
shell in the normal screen), it doesn’t always.

In the alt screen, where applications can print images just about
anywhere, it is possible to have *any* start row number anywhere in
the sixel list. Just as long as their *end* row numbers are sorted.

For example, a huuuge sixel that covers the entire scrollback. This
sixel will naturally be first in the list (and thus sixel_scroll_up()
will visit it *last*, since it iterates the list in reverse), but
should still be destroyed when scrolling.
This commit is contained in:
Daniel Eklöf 2020-10-04 19:11:40 +02:00
parent e870a0068f
commit b66e235e84
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

14
sixel.c
View file

@ -246,11 +246,21 @@ sixel_scroll_up(struct terminal *term, int rows)
struct sixel *six = &it->item;
int six_start = rebase_row(term, six->pos.row);
if (six_start < rows) {
sixel_erase(term, six);
tll_remove(term->grid->sixel_images, it);
} else
break;
} else {
/*
* Unfortunately, we cannot break here.
*
* The sixels are sorted on their *end* row. This means
* there may be a sixel with a top row that will be
* scrolled out *anywhere* in the list (think of a huuuuge
* sixel that covers the entire scrollback)
*/
//break;
}
}
verify_sixels(term);