The cursor visible (DECTCEM) property should be global, not affected by save/restore of cursor or alternate screens
This commit is contained in:
parent
7c76e907c2
commit
b4af2ff314
@ -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):
|
||||||
|
|||||||
@ -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 */
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user