From af8d44ecab05d01b6bc0ad4e1d331ebc93d38cba Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 4 Jan 2017 10:24:00 +0530 Subject: [PATCH] Refactor screen mode API to use get/setters --- kitty/boss.py | 2 +- kitty/char_grid.py | 2 +- kitty/screen.c | 34 +++++++++++++++++++++------------- kitty/window.py | 4 ++-- kitty_tests/__init__.py | 4 ++++ kitty_tests/screen.py | 7 +++++++ 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/kitty/boss.py b/kitty/boss.py index 191cb0fba..310d26861 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -278,7 +278,7 @@ class Boss(Thread): passthrough = f() if not passthrough: return - if window.screen.auto_repeat_enabled() or action == GLFW_PRESS: + if window.screen.auto_repeat_enabled or action == GLFW_PRESS: if window.char_grid.scrolled_by and key not in MODIFIER_KEYS: window.scroll_end() data = interpret_key_event(key, scancode, mods) diff --git a/kitty/char_grid.py b/kitty/char_grid.py index 01a21eccb..df1d1f3ee 100644 --- a/kitty/char_grid.py +++ b/kitty/char_grid.py @@ -447,7 +447,7 @@ class CharGrid: def render_cursor(self, sg, cursor_program): cursor = self.current_cursor - if self.screen.cursor_hidden() or self.scrolled_by: + if not self.screen.cursor_visible or self.scrolled_by: return def width(w=2, vert=True): diff --git a/kitty/screen.c b/kitty/screen.c index d9a97bc72..d5e5761df 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1025,12 +1025,14 @@ WRAP1E(cursor_back, 1, -1) WRAP1B(erase_in_line, 0) WRAP1B(erase_in_display, 0) -#define MODE_GETTER(name, uname) \ - static PyObject* name(Screen *self) { PyObject *ans = self->modes.m##uname ? Py_True : Py_False; Py_INCREF(ans); return ans; } +#define MODE_GETSET(name, uname) \ + static PyObject* name##_get(Screen *self, void UNUSED *closure) { PyObject *ans = self->modes.m##uname ? Py_True : Py_False; Py_INCREF(ans); return ans; } \ + static int name##_set(Screen *self, PyObject *val, void UNUSED *closure) { if (val == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete attribute"); return -1; } set_mode_from_const(self, uname, PyObject_IsTrue(val) ? true : false); return 0; } -MODE_GETTER(in_bracketed_paste_mode, BRACKETED_PASTE) -MODE_GETTER(focus_tracking_enabled, FOCUS_TRACKING) -MODE_GETTER(auto_repeat_enabled, DECARM) +MODE_GETSET(in_bracketed_paste_mode, BRACKETED_PASTE) +MODE_GETSET(focus_tracking_enabled, FOCUS_TRACKING) +MODE_GETSET(auto_repeat_enabled, DECARM) +MODE_GETSET(cursor_visible, DECTCEM) static PyObject* mouse_tracking_mode(Screen *self) { @@ -1160,10 +1162,9 @@ is_main_linebuf(Screen *self) { } static PyObject* -cursor_hidden(Screen *self) { - PyObject *ret = self->modes.mDECTCEM ? Py_False : Py_True; - Py_INCREF(ret); - return ret; +toggle_alt_screen(Screen *self) { + screen_toggle_screen_buffer(self); + Py_RETURN_NONE; } WRAP2(cursor_position, 1, 1) @@ -1180,6 +1181,7 @@ COUNT_WRAP(cursor_down1) COUNT_WRAP(cursor_forward) #define MND(name, args) {#name, (PyCFunction)name, args, #name}, +#define MODEFUNC(name) MND(name, METH_NOARGS) MND(set_##name, METH_O) static PyMethodDef methods[] = { MND(line, METH_O) @@ -1202,7 +1204,6 @@ static PyMethodDef methods[] = { MND(change_scrollback_size, METH_VARARGS) MND(erase_characters, METH_VARARGS) MND(cursor_up, METH_VARARGS) - MND(cursor_hidden, METH_NOARGS) MND(mouse_tracking_mode, METH_NOARGS) MND(mouse_tracking_protocol, METH_NOARGS) MND(cursor_up1, METH_VARARGS) @@ -1223,15 +1224,21 @@ static PyMethodDef methods[] = { MND(set_margins, METH_VARARGS) MND(set_scroll_cell_data, METH_VARARGS) MND(apply_selection, METH_VARARGS) - MND(in_bracketed_paste_mode, METH_NOARGS) - MND(auto_repeat_enabled, METH_NOARGS) - MND(focus_tracking_enabled, METH_NOARGS) + MND(toggle_alt_screen, METH_NOARGS) {"update_cell_data", (PyCFunction)screen_update_cell_data, METH_VARARGS, ""}, {"select_graphic_rendition", (PyCFunction)_select_graphic_rendition, METH_VARARGS, ""}, {NULL} /* Sentinel */ }; +static PyGetSetDef getsetters[] = { + GETSET(in_bracketed_paste_mode) + GETSET(auto_repeat_enabled) + GETSET(focus_tracking_enabled) + GETSET(cursor_visible) + {NULL} /* Sentinel */ +}; + static PyMemberDef members[] = { {"callbacks", T_OBJECT_EX, offsetof(Screen, callbacks), 0, "callbacks"}, {"cursor", T_OBJECT_EX, offsetof(Screen, cursor), READONLY, "cursor"}, @@ -1254,6 +1261,7 @@ PyTypeObject Screen_Type = { .tp_methods = methods, .tp_members = members, .tp_new = new, + .tp_getset = getsetters, }; INIT_TYPE(Screen) diff --git a/kitty/window.py b/kitty/window.py index 74a853d31..41f5fc3f2 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -111,10 +111,10 @@ class Window: def focus_changed(self, focused): if focused: - if self.screen.focus_tracking_enabled(): + if self.screen.focus_tracking_enabled: self.write_to_child(b'\x1b[I') else: - if self.screen.focus_tracking_enabled(): + if self.screen.focus_tracking_enabled: self.write_to_child(b'\x1b[O') def title_changed(self, new_title): diff --git a/kitty_tests/__init__.py b/kitty_tests/__init__.py index 2b5324135..45d67af6d 100644 --- a/kitty_tests/__init__.py +++ b/kitty_tests/__init__.py @@ -30,9 +30,13 @@ class Callbacks: def request_capabilities(self, q): self.qbuf += q + def buf_toggled(self, is_alt): + self.is_alt = is_alt + def clear(self): self.wtcbuf = b'' self.iconbuf = self.titlebuf = self.colorbuf = self.qbuf = self.ctbuf = '' + self.is_alt = False def filled_line_buf(ynum=5, xnum=5, cursor=Cursor()): diff --git a/kitty_tests/screen.py b/kitty_tests/screen.py index 495cee3b9..afa22d447 100644 --- a/kitty_tests/screen.py +++ b/kitty_tests/screen.py @@ -332,3 +332,10 @@ class TestScreen(BaseTest): c = s.line(1).cursor_from(0) self.ae(c.fg, (5 << 8) | 1) self.ae(c.bg, 0) + + def test_cursor_hidden(self): + s = self.create_screen() + s.toggle_alt_screen() + s.cursor_visible = False + s.toggle_alt_screen() + self.assertFalse(s.cursor_visible)