From 98daddc39a8e09d2dac29d73256b40c43f8b8d4a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 10 Sep 2017 14:13:51 +0530 Subject: [PATCH] Move selection render tracking into the Screen class --- kitty/char_grid.py | 6 +----- kitty/data-types.h | 9 +++++++-- kitty/screen.c | 18 ++++++++++-------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/kitty/char_grid.py b/kitty/char_grid.py index 6e5154b82..172e67073 100644 --- a/kitty/char_grid.py +++ b/kitty/char_grid.py @@ -96,7 +96,6 @@ class CharGrid: def __init__(self, screen, opts): self.vao_id = None self.screen_reversed = False - self.last_rendered_selection = None self.render_data = None self.data_buffer_size = None self.screen = screen @@ -239,12 +238,9 @@ class CharGrid: if self.screen.scroll_changed or self.screen.is_dirty: self.update_cell_data(cell_program) sg = self.render_data - sel = self.screen.selection_limits() - selection_changed = sel != self.last_rendered_selection - if selection_changed: + if self.screen.is_selection_dirty(): with cell_program.mapped_vertex_data(self.vao_id, self.selection_buffer_size, bufnum=1) as address: self.screen.apply_selection(address, self.selection_buffer_size) - self.last_rendered_selection = sel return sg def render_cells(self, sg, cell_program, sprites, invert_colors=False): diff --git a/kitty/data-types.h b/kitty/data-types.h index 2165466fe..cc44effc1 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -220,6 +220,10 @@ typedef struct { #define PARSER_BUF_SZ (8 * 1024) #define READ_BUF_SZ (1024*1024) +typedef struct { + unsigned int x, y; +} SelectionBoundary; + typedef struct { unsigned int start_x, start_y, start_scrolled_by, end_x, end_y, end_scrolled_by; bool in_progress; @@ -228,10 +232,11 @@ typedef struct { typedef struct { PyObject_HEAD - unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by; + unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by, last_selection_scrolled_by; uint32_t utf8_state, utf8_codepoint, *g0_charset, *g1_charset, *g_charset; Selection selection; - bool use_latin1; + SelectionBoundary last_rendered_selection_start, last_rendered_selection_end; + bool use_latin1, selection_updated_once; Cursor *cursor; SavepointBuffer main_savepoints, alt_savepoints; PyObject *callbacks, *is_dirty, *cursor_changed, *scroll_changed; diff --git a/kitty/screen.c b/kitty/screen.c index c4e0bf08c..c71931760 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1247,10 +1247,6 @@ is_selection_empty(Screen *self, unsigned int start_x, unsigned int start_y, uns return (start_x >= self->columns || start_y >= self->lines || end_x >= self->columns || end_y >= self->lines || (start_x == end_x && start_y == end_y)) ? true : false; } -typedef struct { - unsigned int x, y; -} SelectionBoundary; - static inline void selection_coord(Screen *self, unsigned int x, unsigned int y, unsigned int ydelta, SelectionBoundary *ans) { if (y + self->scrolled_by < ydelta) { @@ -1278,11 +1274,14 @@ static PyObject* apply_selection(Screen *self, PyObject *args) { unsigned int size; PyObject *l; - SelectionBoundary start, end; +#define start (self->last_rendered_selection_start) +#define end (self->last_rendered_selection_end) if (!PyArg_ParseTuple(args, "O!I", &PyLong_Type, &l, &size)) return NULL; float *data = PyLong_AsVoidPtr(l); memset(data, 0, size); selection_limits_(self, &start, &end); + self->last_selection_scrolled_by = self->scrolled_by; + self->selection_updated_once = true; if (is_selection_empty(self, start.x, start.y, end.x, end.y)) { Py_RETURN_NONE; } for (index_type y = start.y; y <= end.y; y++) { Line *line = visual_line_(self, y); @@ -1292,6 +1291,8 @@ apply_selection(Screen *self, PyObject *args) { for (index_type x = (y == start.y ? start.x : 0); x < xlimit; x++) line_start[x] = 1.0; } Py_RETURN_NONE; +#undef start +#undef end } static PyObject* @@ -1403,10 +1404,11 @@ is_selection_in_progress(Screen *self) { } static PyObject* -selection_limits(Screen *self) { +is_selection_dirty(Screen *self) { SelectionBoundary start, end; selection_limits_(self, &start, &end); - return Py_BuildValue("(II)(II)", start.x, start.y, end.x, end.y); + if (self->last_selection_scrolled_by != self->scrolled_by || start.x != self->last_rendered_selection_start.x || start.y != self->last_rendered_selection_start.y || end.x != self->last_rendered_selection_end.x || end.y != self->last_rendered_selection_end.y || !self->selection_updated_once) { Py_RETURN_TRUE; } + Py_RETURN_FALSE; } static PyObject* @@ -1519,7 +1521,7 @@ static PyMethodDef methods[] = { MND(text_for_selection, METH_NOARGS) MND(clear_selection, METH_NOARGS) MND(is_selection_in_progress, METH_NOARGS) - MND(selection_limits, METH_NOARGS) + MND(is_selection_dirty, METH_NOARGS) MND(start_selection, METH_VARARGS) MND(update_selection, METH_VARARGS) MND(scroll, METH_VARARGS)