Scrollback filling should happen after cursor position is finalized
This commit is contained in:
parent
a4d9d948ab
commit
0f3ff4e2d9
@ -212,6 +212,33 @@ realloc_lb(LineBuf *old, unsigned int lines, unsigned int columns, index_type *n
|
||||
return ans;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_selection_empty(const Selection *s) {
|
||||
int start_y = (int)s->start.y - (int)s->start_scrolled_by, end_y = (int)s->end.y - (int)s->end_scrolled_by;
|
||||
return s->start.x == s->end.x && s->start.in_left_half_of_cell == s->end.in_left_half_of_cell && start_y == end_y;
|
||||
}
|
||||
|
||||
static inline void
|
||||
index_selection(const Screen *self, Selections *selections, bool up) {
|
||||
for (size_t i = 0; i < selections->count; i++) {
|
||||
Selection *s = selections->items + i;
|
||||
if (!is_selection_empty(s)) {
|
||||
if (up) {
|
||||
if (s->start.y == 0) s->start_scrolled_by += 1;
|
||||
else s->start.y--;
|
||||
if (s->end.y == 0) s->end_scrolled_by += 1;
|
||||
else s->end.y--;
|
||||
} else {
|
||||
if (s->start.y >= self->lines - 1) s->start_scrolled_by -= 1;
|
||||
else s->start.y++;
|
||||
if (s->end.y >= self->lines - 1) s->end_scrolled_by -= 1;
|
||||
else s->end.y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define INDEX_GRAPHICS(amtv) { \
|
||||
bool is_main = self->linebuf == self->main_linebuf; \
|
||||
static ScrollData s; \
|
||||
@ -221,6 +248,16 @@ realloc_lb(LineBuf *old, unsigned int lines, unsigned int columns, index_type *n
|
||||
grman_scroll_images(self->grman, &s, self->cell_size); \
|
||||
}
|
||||
|
||||
|
||||
#define INDEX_DOWN \
|
||||
if (self->overlay_line.is_active) deactivate_overlay_line(self); \
|
||||
linebuf_reverse_index(self->linebuf, top, bottom); \
|
||||
linebuf_clear_line(self->linebuf, top); \
|
||||
INDEX_GRAPHICS(1) \
|
||||
self->is_dirty = true; \
|
||||
index_selection(self, &self->selections, false);
|
||||
|
||||
|
||||
static bool
|
||||
screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
||||
if (self->overlay_line.is_active) deactivate_overlay_line(self);
|
||||
@ -247,19 +284,11 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
||||
if (n == NULL) return false;
|
||||
|
||||
|
||||
int lines_to_fill = -1;
|
||||
if (is_main && OPT(scrollback_fill_enlarged_window)) {
|
||||
int lines_to_fill = (lines - self->main_linebuf->ynum) + (
|
||||
lines_to_fill = (lines - self->main_linebuf->ynum) + (
|
||||
linebuf_continued_lines_count(self->main_linebuf, self->cursor->y) - linebuf_continued_lines_count(n, y));
|
||||
const unsigned int top = 0, bottom = lines-1;
|
||||
Line last_history_line = {.xnum=self->historybuf->xnum};
|
||||
while (lines_to_fill-- > 0) {
|
||||
if (!historybuf_pop_line(self->historybuf, &last_history_line)) break;
|
||||
linebuf_reverse_index(n, top, bottom);
|
||||
INDEX_GRAPHICS(1);
|
||||
linebuf_add_line_to_top(n, &last_history_line);
|
||||
}
|
||||
}
|
||||
|
||||
Py_CLEAR(self->main_linebuf); self->main_linebuf = n;
|
||||
if (is_main) setup_cursor();
|
||||
grman_resize(self->main_grman, self->lines, lines, self->columns, columns);
|
||||
@ -295,6 +324,14 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
||||
self->cursor->y = num_content_lines;
|
||||
if (self->cursor->y >= self->lines) { self->cursor->y = self->lines - 1; screen_index(self); }
|
||||
}
|
||||
if (lines_to_fill > 0) {
|
||||
const unsigned int top = 0, bottom = self->lines-1;
|
||||
while (lines_to_fill-- > 0) {
|
||||
if (!historybuf_pop_line(self->historybuf, self->alt_linebuf->line)) break;
|
||||
INDEX_DOWN;
|
||||
linebuf_add_line_to_top(self->main_linebuf, self->alt_linebuf->line);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -394,12 +431,6 @@ move_widened_char(Screen *self, CPUCell* cpu_cell, GPUCell *gpu_cell, index_type
|
||||
*dest_gpu = src_gpu;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_selection_empty(const Selection *s) {
|
||||
int start_y = (int)s->start.y - (int)s->start_scrolled_by, end_y = (int)s->end.y - (int)s->end_scrolled_by;
|
||||
return s->start.x == s->end.x && s->start.in_left_half_of_cell == s->end.in_left_half_of_cell && start_y == end_y;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
selection_has_screen_line(const Selections *selections, const int y) {
|
||||
for (size_t i = 0; i < selections->count; i++) {
|
||||
@ -1058,26 +1089,6 @@ screen_cursor_to_column(Screen *self, unsigned int column) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
index_selection(const Screen *self, Selections *selections, bool up) {
|
||||
for (size_t i = 0; i < selections->count; i++) {
|
||||
Selection *s = selections->items + i;
|
||||
if (!is_selection_empty(s)) {
|
||||
if (up) {
|
||||
if (s->start.y == 0) s->start_scrolled_by += 1;
|
||||
else s->start.y--;
|
||||
if (s->end.y == 0) s->end_scrolled_by += 1;
|
||||
else s->end.y--;
|
||||
} else {
|
||||
if (s->start.y >= self->lines - 1) s->start_scrolled_by -= 1;
|
||||
else s->start.y++;
|
||||
if (s->end.y >= self->lines - 1) s->end_scrolled_by -= 1;
|
||||
else s->end.y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define INDEX_UP \
|
||||
if (self->overlay_line.is_active) deactivate_overlay_line(self); \
|
||||
linebuf_index(self->linebuf, top, bottom); \
|
||||
@ -1111,14 +1122,6 @@ screen_scroll(Screen *self, unsigned int count) {
|
||||
}
|
||||
}
|
||||
|
||||
#define INDEX_DOWN \
|
||||
if (self->overlay_line.is_active) deactivate_overlay_line(self); \
|
||||
linebuf_reverse_index(self->linebuf, top, bottom); \
|
||||
linebuf_clear_line(self->linebuf, top); \
|
||||
INDEX_GRAPHICS(1) \
|
||||
self->is_dirty = true; \
|
||||
index_selection(self, &self->selections, false);
|
||||
|
||||
void
|
||||
screen_reverse_index(Screen *self) {
|
||||
// Move cursor up one line, scrolling screen if needed
|
||||
|
||||
@ -91,14 +91,10 @@ class BaseTest(TestCase):
|
||||
options = Options(merge_configs(defaults._asdict(), final_options))
|
||||
set_options(options)
|
||||
|
||||
def create_screen(self, cols=5, lines=5, scrollback=5, cell_width=10, cell_height=20, options=None, content=()):
|
||||
def create_screen(self, cols=5, lines=5, scrollback=5, cell_width=10, cell_height=20, options=None):
|
||||
self.set_options(options)
|
||||
c = Callbacks()
|
||||
s = Screen(c, lines, cols, scrollback, cell_width, cell_height, 0, c)
|
||||
for content_line in content:
|
||||
s.draw(content_line)
|
||||
s.linefeed()
|
||||
s.carriage_return()
|
||||
return s
|
||||
|
||||
def assertEqualAttributes(self, c1, c2):
|
||||
|
||||
@ -305,45 +305,45 @@ class TestScreen(BaseTest):
|
||||
|
||||
def test_scrollback_fill_after_resize(self):
|
||||
def prepare_screen(content=()):
|
||||
return self.create_screen(
|
||||
lines=5,
|
||||
cols=5,
|
||||
options={'scrollback_fill_enlarged_window': True},
|
||||
content=content,
|
||||
)
|
||||
ans = self.create_screen(options={'scrollback_fill_enlarged_window': True})
|
||||
for line in content:
|
||||
ans.draw(line)
|
||||
ans.linefeed()
|
||||
ans.carriage_return()
|
||||
return ans
|
||||
|
||||
def assert_lines(lines, s):
|
||||
return self.ae(lines, str(s.linebuf).split("\n"))
|
||||
def assert_lines(*lines):
|
||||
return self.ae(lines, tuple(str(s.line(i)) for i in range(s.lines)))
|
||||
|
||||
# Height increased, width unchanged → pull down lines to fill new space at the top
|
||||
s = prepare_screen([str(i) for i in range(0, 6)])
|
||||
assert_lines(['2', '3', '4', '5', ''], s)
|
||||
s = prepare_screen(map(str, range(6)))
|
||||
assert_lines('2', '3', '4', '5', '')
|
||||
s.resize(7, s.columns)
|
||||
assert_lines(['0', '1', '2', '3', '4', '5', ''], s)
|
||||
assert_lines('0', '1', '2', '3', '4', '5', '')
|
||||
|
||||
# Height increased, width increased → rewrap, pull down
|
||||
s = prepare_screen(['0', '1', '2', '3' * 15])
|
||||
assert_lines(['2', '33333', '33333', '33333', ''], s)
|
||||
assert_lines('2', '33333', '33333', '33333', '')
|
||||
s.resize(7, 12)
|
||||
assert_lines(['0', '1', '2', '333333333333', '333', '', ''], s)
|
||||
assert_lines('0', '1', '2', '333333333333', '333', '', '')
|
||||
|
||||
# Height increased, width decreased → rewrap, pull down if possible
|
||||
s = prepare_screen(['0', '1', '2', '3' * 5])
|
||||
assert_lines(['0', '1', '2', '33333', ''], s)
|
||||
assert_lines('0', '1', '2', '33333', '')
|
||||
s.resize(6, 4)
|
||||
assert_lines(['0', '1', '2', '3333', '3', ''], s)
|
||||
assert_lines('0', '1', '2', '3333', '3', '')
|
||||
|
||||
# Height unchanged, width increased → rewrap, pull down if possible
|
||||
s = prepare_screen(['0', '1', '2', '3' * 15])
|
||||
assert_lines(['2', '33333', '33333', '33333', ''], s)
|
||||
assert_lines('2', '33333', '33333', '33333', '')
|
||||
s.resize(s.lines, 12)
|
||||
assert_lines(['1', '2', '333333333333', '333', ''], s)
|
||||
assert_lines('1', '2', '333333333333', '333', '')
|
||||
|
||||
# Height decreased, width increased → rewrap, pull down if possible
|
||||
s = prepare_screen(['0', '1', '2', '3' * 15])
|
||||
assert_lines(['2', '33333', '33333', '33333', ''], s)
|
||||
assert_lines('2', '33333', '33333', '33333', '')
|
||||
s.resize(4, 12)
|
||||
assert_lines(['2', '333333333333', '333', ''], s)
|
||||
assert_lines('2', '333333333333', '333', '')
|
||||
|
||||
def test_tab_stops(self):
|
||||
# Taken from vttest/main.c
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user