diff --git a/kitty/boss.py b/kitty/boss.py index fe340a68e..fc70ec178 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -54,7 +54,7 @@ class Boss(Thread): self.queue_action(self.initialize) self.profile = args.profile self.window, self.opts = window, opts - self.screen = Screen(self) + self.screen = Screen(self, 24, 80, opts.scrollback_lines) self.char_grid = CharGrid(self.screen, opts, window_width, window_height) self.read_bytes = partial(read_bytes_dump, print) if args.dump_commands else read_bytes self.write_buf = memoryview(b'') @@ -143,6 +143,7 @@ class Boss(Thread): def apply_opts_to_screen(self): self.char_grid.apply_opts(self.opts) self.char_grid.dirty_everything() + self.screen.change_scrollback_size(self.opts.scrollback_lines) def render(self): if self.pending_title_change is not None: diff --git a/kitty/line-buf.c b/kitty/line-buf.c index 0ff69573d..4f9150350 100644 --- a/kitty/line-buf.c +++ b/kitty/line-buf.c @@ -367,8 +367,8 @@ static PyMethodDef methods[] = { }; static PyMemberDef members[] = { - {"xnum", T_UINT, offsetof(LineBuf, xnum), 0, "xnum"}, - {"ynum", T_UINT, offsetof(LineBuf, ynum), 0, "ynum"}, + {"xnum", T_UINT, offsetof(LineBuf, xnum), READONLY, "xnum"}, + {"ynum", T_UINT, offsetof(LineBuf, ynum), READONLY, "ynum"}, {NULL} /* Sentinel */ }; diff --git a/kitty/screen.c b/kitty/screen.c index fc214dd33..4bc19fd47 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -18,8 +18,8 @@ static PyObject* new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) { Screen *self; PyObject *callbacks = Py_None; - unsigned int columns=80, lines=24; - if (!PyArg_ParseTuple(args, "|OII", &callbacks, &lines, &columns)) return NULL; + unsigned int columns=80, lines=24, scrollback=0; + if (!PyArg_ParseTuple(args, "|OIII", &callbacks, &lines, &columns, &scrollback)) return NULL; self = (Screen *)type->tp_alloc(type, 0); if (self != NULL) { @@ -35,7 +35,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) { self->main_linebuf = alloc_linebuf(lines, columns); self->alt_linebuf = alloc_linebuf(lines, columns); self->linebuf = self->main_linebuf; self->change_tracker = alloc_change_tracker(lines, columns); - self->historybuf = alloc_historybuf(lines, columns); + self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns); self->tabstops = PyMem_Calloc(self->columns, sizeof(bool)); if (self->cursor == NULL || self->main_linebuf == NULL || self->alt_linebuf == NULL || self->change_tracker == NULL || self->tabstops == NULL || self->historybuf == NULL) { Py_CLEAR(self); return NULL; @@ -82,7 +82,7 @@ static bool screen_resize(Screen *self, unsigned int lines, unsigned int columns bool is_main = self->linebuf == self->main_linebuf; int cursor_y = -1; - HistoryBuf *nh = realloc_hb(self->historybuf, lines, columns); + HistoryBuf *nh = realloc_hb(self->historybuf, self->historybuf->ynum, columns); if (nh == NULL) return false; Py_CLEAR(self->historybuf); self->historybuf = nh; LineBuf *n = realloc_lb(self->main_linebuf, lines, columns, &cursor_y, self->historybuf); @@ -110,7 +110,8 @@ static bool screen_resize(Screen *self, unsigned int lines, unsigned int columns } static bool screen_change_scrollback_size(Screen *self, unsigned int size) { - return historybuf_resize(self->historybuf, size); + if (size != self->historybuf->ynum) return historybuf_resize(self->historybuf, size); + return true; } @@ -1015,7 +1016,7 @@ static PyObject* change_scrollback_size(Screen *self, PyObject *args) { unsigned int count = 1; if (!PyArg_ParseTuple(args, "|I", &count)) return NULL; - if (!screen_change_scrollback_size(self, MAX(100, count))) return NULL; + if (!screen_change_scrollback_size(self, MAX(self->lines, count))) return NULL; Py_RETURN_NONE; } @@ -1094,13 +1095,14 @@ static PyMethodDef methods[] = { static PyMemberDef members[] = { {"callbacks", T_OBJECT_EX, offsetof(Screen, callbacks), 0, "callbacks"}, - {"cursor", T_OBJECT_EX, offsetof(Screen, cursor), 0, "cursor"}, - {"linebuf", T_OBJECT_EX, offsetof(Screen, linebuf), 0, "linebuf"}, - {"lines", T_UINT, offsetof(Screen, lines), 0, "lines"}, - {"columns", T_UINT, offsetof(Screen, columns), 0, "columns"}, - {"margin_top", T_UINT, offsetof(Screen, margin_top), 0, "margin_top"}, - {"margin_bottom", T_UINT, offsetof(Screen, margin_bottom), 0, "margin_bottom"}, - {"current_charset", T_UINT, offsetof(Screen, current_charset), 0, "current_charset"}, + {"cursor", T_OBJECT_EX, offsetof(Screen, cursor), READONLY, "cursor"}, + {"linebuf", T_OBJECT_EX, offsetof(Screen, linebuf), READONLY, "linebuf"}, + {"historybuf", T_OBJECT_EX, offsetof(Screen, historybuf), READONLY, "historybuf"}, + {"lines", T_UINT, offsetof(Screen, lines), READONLY, "lines"}, + {"columns", T_UINT, offsetof(Screen, columns), READONLY, "columns"}, + {"margin_top", T_UINT, offsetof(Screen, margin_top), READONLY, "margin_top"}, + {"margin_bottom", T_UINT, offsetof(Screen, margin_bottom), READONLY, "margin_bottom"}, + {"current_charset", T_UINT, offsetof(Screen, current_charset), READONLY, "current_charset"}, {NULL} }; diff --git a/kitty_tests/__init__.py b/kitty_tests/__init__.py index 9e1d518c7..643a10626 100644 --- a/kitty_tests/__init__.py +++ b/kitty_tests/__init__.py @@ -37,8 +37,8 @@ class BaseTest(TestCase): ae = TestCase.assertEqual - def create_screen(self, cols=5, lines=5): - return Screen(None, lines, cols) + def create_screen(self, cols=5, lines=5, scrollback=5): + return Screen(None, lines, cols, scrollback) def assertEqualAttributes(self, c1, c2): x1, y1, c1.x, c1.y = c1.x, c1.y, 0, 0 diff --git a/kitty_tests/screen.py b/kitty_tests/screen.py index d75b6ed0d..733210650 100644 --- a/kitty_tests/screen.py +++ b/kitty_tests/screen.py @@ -232,3 +232,17 @@ class TestScreen(BaseTest): self.ae(str(s.line(0)), ' ' * 5) for i in range(1, 5): self.ae(str(s.line(i)), '12345') + + def test_resize(self): + s = self.create_screen(scrollback=6) + s.draw(''.join([str(i) * s.columns for i in range(s.lines)]).encode('utf-8')) + s.resize(3, 10) + self.ae(str(s.line(0)), '0'*5 + '1'*5) + self.ae(str(s.line(1)), '2'*5 + '3'*5) + self.ae(str(s.line(2)), '4'*5 + ' '*5) + s.resize(5, 1) + self.ae(str(s.line(0)), '4') + hb = s.historybuf + for i in range(s.lines): + self.ae(str(hb.line(i)), '3') + self.ae(str(hb.line(5)), '2')