The cursor visible (DECTCEM) property should be global, not affected by save/restore of cursor or alternate screens

This commit is contained in:
Kovid Goyal 2017-01-04 10:02:39 +05:30
parent 7c76e907c2
commit b4af2ff314
5 changed files with 21 additions and 21 deletions

View File

@ -16,7 +16,7 @@ from .fast_data_types import (
CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, DATA_CELL_SIZE CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, DATA_CELL_SIZE
) )
Cursor = namedtuple('Cursor', 'x y hidden shape color blink') Cursor = namedtuple('Cursor', 'x y shape color blink')
if DATA_CELL_SIZE % 3: if DATA_CELL_SIZE % 3:
raise ValueError('Incorrect data cell size, must be a multiple of 3') raise ValueError('Incorrect data cell size, must be a multiple of 3')
@ -245,7 +245,7 @@ class CharGrid:
self.default_fg = color_as_int(self.original_fg) self.default_fg = color_as_int(self.original_fg)
self.dpix, self.dpiy = get_logical_dpi() self.dpix, self.dpiy = get_logical_dpi()
self.opts = opts self.opts = opts
self.default_cursor = self.current_cursor = Cursor(0, 0, False, opts.cursor_shape, opts.cursor, opts.cursor_blink_interval > 0) self.default_cursor = self.current_cursor = Cursor(0, 0, opts.cursor_shape, opts.cursor, opts.cursor_blink_interval > 0)
self.opts = opts self.opts = opts
self.original_bg = opts.background self.original_bg = opts.background
self.original_fg = opts.foreground self.original_fg = opts.foreground
@ -312,7 +312,7 @@ class CharGrid:
self.render_buf_is_dirty = True self.render_buf_is_dirty = True
if cursor_changed: if cursor_changed:
c = self.screen.cursor c = self.screen.cursor
self.current_cursor = Cursor(c.x, c.y, c.hidden, c.shape, c.color, c.blink) self.current_cursor = Cursor(c.x, c.y, c.shape, c.color, c.blink)
def cell_for_pos(self, x, y): def cell_for_pos(self, x, y):
x, y = int(x // cell_size.width), int(y // cell_size.height) x, y = int(x // cell_size.width), int(y // cell_size.height)
@ -447,7 +447,7 @@ class CharGrid:
def render_cursor(self, sg, cursor_program): def render_cursor(self, sg, cursor_program):
cursor = self.current_cursor cursor = self.current_cursor
if cursor.hidden or self.scrolled_by: if self.screen.cursor_hidden() or self.scrolled_by:
return return
def width(w=2, vert=True): def width(w=2, vert=True):

View File

@ -24,15 +24,15 @@ dealloc(Cursor* self) {
#define EQ(x) (a->x == b->x) #define EQ(x) (a->x == b->x)
static int __eq__(Cursor *a, Cursor *b) { static int __eq__(Cursor *a, Cursor *b) {
return EQ(bold) && EQ(italic) && EQ(strikethrough) && EQ(reverse) && EQ(decoration) && EQ(fg) && EQ(bg) && EQ(decoration_fg) && EQ(x) && EQ(y) && EQ(shape) && EQ(blink) && EQ(color) && EQ(hidden); return EQ(bold) && EQ(italic) && EQ(strikethrough) && EQ(reverse) && EQ(decoration) && EQ(fg) && EQ(bg) && EQ(decoration_fg) && EQ(x) && EQ(y) && EQ(shape) && EQ(blink) && EQ(color);
} }
#define BOOL(x) ((x) ? Py_True : Py_False) #define BOOL(x) ((x) ? Py_True : Py_False)
static PyObject * static PyObject *
repr(Cursor *self) { repr(Cursor *self) {
return PyUnicode_FromFormat( return PyUnicode_FromFormat(
"Cursor(x=%u, y=%u, shape=%d, blink=%R, hidden=%R, color=#%08x, fg=#%08x, bg=#%08x, bold=%R, italic=%R, reverse=%R, strikethrough=%R, decoration=%d, decoration_fg=#%08x)", "Cursor(x=%u, y=%u, shape=%d, blink=%R, color=#%08x, fg=#%08x, bg=#%08x, bold=%R, italic=%R, reverse=%R, strikethrough=%R, decoration=%d, decoration_fg=#%08x)",
self->x, self->y, self->shape, BOOL(self->blink), BOOL(self->hidden), self->color, self->fg, self->bg, BOOL(self->bold), BOOL(self->italic), BOOL(self->reverse), BOOL(self->strikethrough), self->decoration, self->decoration_fg self->x, self->y, self->shape, BOOL(self->blink), self->color, self->fg, self->bg, BOOL(self->bold), BOOL(self->italic), BOOL(self->reverse), BOOL(self->strikethrough), self->decoration, self->decoration_fg
); );
} }
@ -52,12 +52,12 @@ void cursor_reset(Cursor *self) {
cursor_reset_display_attrs(self); cursor_reset_display_attrs(self);
self->x = 0; self->y = 0; self->x = 0; self->y = 0;
self->shape = 0; self->blink = false; self->shape = 0; self->blink = false;
self->color = 0; self->hidden = false; self->color = 0;
} }
void cursor_copy_to(Cursor *src, Cursor *dest) { void cursor_copy_to(Cursor *src, Cursor *dest) {
#define CCY(x) dest->x = src->x; #define CCY(x) dest->x = src->x;
CCY(x); CCY(y); CCY(shape); CCY(blink); CCY(color); CCY(hidden); CCY(x); CCY(y); CCY(shape); CCY(blink); CCY(color);
CCY(bold); CCY(italic); CCY(strikethrough); CCY(reverse); CCY(decoration); CCY(fg); CCY(bg); CCY(decoration_fg); CCY(bold); CCY(italic); CCY(strikethrough); CCY(reverse); CCY(decoration); CCY(fg); CCY(bg); CCY(decoration_fg);
} }
@ -76,7 +76,6 @@ BOOL_GETSET(Cursor, bold)
BOOL_GETSET(Cursor, italic) BOOL_GETSET(Cursor, italic)
BOOL_GETSET(Cursor, reverse) BOOL_GETSET(Cursor, reverse)
BOOL_GETSET(Cursor, strikethrough) BOOL_GETSET(Cursor, strikethrough)
BOOL_GETSET(Cursor, hidden)
BOOL_GETSET(Cursor, blink) BOOL_GETSET(Cursor, blink)
static PyMemberDef members[] = { static PyMemberDef members[] = {
@ -96,7 +95,6 @@ static PyGetSetDef getseters[] = {
GETSET(italic) GETSET(italic)
GETSET(reverse) GETSET(reverse)
GETSET(strikethrough) GETSET(strikethrough)
GETSET(hidden)
GETSET(blink) GETSET(blink)
{"color", (getter) color_get, NULL, "color", NULL}, {"color", (getter) color_get, NULL, "color", NULL},
{NULL} /* Sentinel */ {NULL} /* Sentinel */

View File

@ -185,7 +185,7 @@ PyTypeObject HistoryBuf_Type;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
bool bold, italic, reverse, strikethrough, blink, hidden; bool bold, italic, reverse, strikethrough, blink;
unsigned int x, y; unsigned int x, y;
uint8_t decoration, shape; uint8_t decoration, shape;
unsigned long fg, bg, decoration_fg, color; unsigned long fg, bg, decoration_fg, color;
@ -256,7 +256,7 @@ typedef struct {
uint32_t utf8_state, *g0_charset, *g1_charset, *g_charset; uint32_t utf8_state, *g0_charset, *g1_charset, *g_charset;
bool use_latin1; bool use_latin1;
Cursor cursor; Cursor cursor;
bool mDECOM, mDECAWM, mDECSCNM, mDECTCEM; bool mDECOM, mDECAWM, mDECSCNM;
} Savepoint; } Savepoint;

View File

@ -401,10 +401,7 @@ set_mode_from_const(Screen *self, unsigned int mode, bool val) {
break; // we ignore these modes break; // we ignore these modes
case DECTCEM: case DECTCEM:
self->modes.mDECTCEM = val; self->modes.mDECTCEM = val;
if (val == self->cursor->hidden) { tracker_cursor_changed(self->change_tracker);
self->cursor->hidden = !val;
tracker_cursor_changed(self->change_tracker);
}
break; break;
case DECSCNM: case DECSCNM:
// Render screen in reverse video // Render screen in reverse video
@ -641,7 +638,6 @@ screen_save_cursor(Screen *self) {
sp->mDECOM = self->modes.mDECOM; sp->mDECOM = self->modes.mDECOM;
sp->mDECAWM = self->modes.mDECAWM; sp->mDECAWM = self->modes.mDECAWM;
sp->mDECSCNM = self->modes.mDECSCNM; sp->mDECSCNM = self->modes.mDECSCNM;
sp->mDECTCEM = self->modes.mDECTCEM;
COPY_CHARSETS(self, sp); COPY_CHARSETS(self, sp);
} }
@ -655,13 +651,11 @@ screen_restore_cursor(Screen *self) {
screen_reset_mode(self, DECOM); screen_reset_mode(self, DECOM);
RESET_CHARSETS; RESET_CHARSETS;
screen_reset_mode(self, DECSCNM); screen_reset_mode(self, DECSCNM);
screen_set_mode(self, DECTCEM);
} else { } else {
COPY_CHARSETS(sp, self); COPY_CHARSETS(sp, self);
set_mode_from_const(self, DECOM, sp->mDECOM); set_mode_from_const(self, DECOM, sp->mDECOM);
set_mode_from_const(self, DECAWM, sp->mDECAWM); set_mode_from_const(self, DECAWM, sp->mDECAWM);
set_mode_from_const(self, DECSCNM, sp->mDECSCNM); set_mode_from_const(self, DECSCNM, sp->mDECSCNM);
set_mode_from_const(self, DECTCEM, sp->mDECTCEM);
cursor_copy_to(&(sp->cursor), self->cursor); cursor_copy_to(&(sp->cursor), self->cursor);
screen_ensure_bounds(self, false); screen_ensure_bounds(self, false);
} }
@ -1165,6 +1159,13 @@ is_main_linebuf(Screen *self) {
return ans; return ans;
} }
static PyObject*
cursor_hidden(Screen *self) {
PyObject *ret = self->modes.mDECTCEM ? Py_False : Py_True;
Py_INCREF(ret);
return ret;
}
WRAP2(cursor_position, 1, 1) WRAP2(cursor_position, 1, 1)
#define COUNT_WRAP(name) WRAP1(name, 1) #define COUNT_WRAP(name) WRAP1(name, 1)
@ -1201,6 +1202,7 @@ static PyMethodDef methods[] = {
MND(change_scrollback_size, METH_VARARGS) MND(change_scrollback_size, METH_VARARGS)
MND(erase_characters, METH_VARARGS) MND(erase_characters, METH_VARARGS)
MND(cursor_up, METH_VARARGS) MND(cursor_up, METH_VARARGS)
MND(cursor_hidden, METH_NOARGS)
MND(mouse_tracking_mode, METH_NOARGS) MND(mouse_tracking_mode, METH_NOARGS)
MND(mouse_tracking_protocol, METH_NOARGS) MND(mouse_tracking_protocol, METH_NOARGS)
MND(cursor_up1, METH_VARARGS) MND(cursor_up1, METH_VARARGS)

View File

@ -165,7 +165,7 @@ class TestDataTypes(BaseTest):
c2, c3 = c.copy(), c.copy() c2, c3 = c.copy(), c.copy()
self.ae(repr(c), repr(c2)) self.ae(repr(c), repr(c2))
self.ae(c, c2) self.ae(c, c2)
c2.bold = c2.hidden = False c2.bold = False
self.assertNotEqual(c, c2) self.assertNotEqual(c, c2)
l.set_text(t, 0, len(t), C()) l.set_text(t, 0, len(t), C())
l.apply_cursor(c2, 3) l.apply_cursor(c2, 3)