Fix turning off cursor blink via escape codes not working

Also fix cursor blink stopping after terminal reset. The default cursor
state should be blinking.

Fixes #3808

...
This commit is contained in:
Kovid Goyal 2021-07-07 20:33:29 +05:30
parent 25fb5d0ee6
commit cd6b3da665
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 20 additions and 13 deletions

View File

@ -19,6 +19,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- diff kitten: Remove limit on max line length of 4096 characters (:iss:`3806`)
- Fix turning off cursor blink via escape codes not working (:iss:`3808`)
0.21.2 [2021-06-28]
----------------------

View File

@ -523,7 +523,7 @@ collect_cursor_info(CursorRenderInfo *ans, Window *w, monotonic_t now, OSWindow
ans->is_visible = false;
if (rd->screen->scrolled_by || !screen_is_cursor_visible(rd->screen)) return;
monotonic_t time_since_start_blink = now - os_window->cursor_blink_zero_time;
bool cursor_blinking = OPT(cursor_blink_interval) > 0 && os_window->is_focused && (OPT(cursor_stop_blinking_after) == 0 || time_since_start_blink <= OPT(cursor_stop_blinking_after));
bool cursor_blinking = OPT(cursor_blink_interval) > 0 && !cursor->non_blinking && os_window->is_focused && (OPT(cursor_stop_blinking_after) == 0 || time_since_start_blink <= OPT(cursor_stop_blinking_after));
bool do_draw_cursor = true;
if (cursor_blinking) {
int t = monotonic_t_to_ms(time_since_start_blink);

View File

@ -24,7 +24,7 @@ dealloc(Cursor* self) {
#define EQ(x) (a->x == b->x)
static int __eq__(Cursor *a, Cursor *b) {
return EQ(bold) && EQ(italic) && EQ(strikethrough) && EQ(dim) && EQ(reverse) && EQ(decoration) && EQ(fg) && EQ(bg) && EQ(decoration_fg) && EQ(x) && EQ(y) && EQ(shape) && EQ(blink);
return EQ(bold) && EQ(italic) && EQ(strikethrough) && EQ(dim) && EQ(reverse) && EQ(decoration) && EQ(fg) && EQ(bg) && EQ(decoration_fg) && EQ(x) && EQ(y) && EQ(shape) && EQ(non_blinking);
}
static const char* cursor_names[NUM_OF_CURSOR_SHAPES] = { "NO_SHAPE", "BLOCK", "BEAM", "UNDERLINE" };
@ -35,7 +35,7 @@ repr(Cursor *self) {
return PyUnicode_FromFormat(
"Cursor(x=%u, y=%u, shape=%s, blink=%R, fg=#%08x, bg=#%08x, bold=%R, italic=%R, reverse=%R, strikethrough=%R, dim=%R, decoration=%d, decoration_fg=#%08x)",
self->x, self->y, (self->shape < NUM_OF_CURSOR_SHAPES ? cursor_names[self->shape] : "INVALID"),
BOOL(self->blink), self->fg, self->bg, BOOL(self->bold), BOOL(self->italic), BOOL(self->reverse), BOOL(self->strikethrough), BOOL(self->dim), self->decoration, self->decoration_fg
BOOL(!self->non_blinking), self->fg, self->bg, BOOL(self->bold), BOOL(self->italic), BOOL(self->reverse), BOOL(self->strikethrough), BOOL(self->dim), self->decoration, self->decoration_fg
);
}
@ -232,12 +232,12 @@ reset_display_attrs(Cursor *self, PyObject *a UNUSED) {
void cursor_reset(Cursor *self) {
cursor_reset_display_attrs(self);
self->x = 0; self->y = 0;
self->shape = NO_CURSOR_SHAPE; self->blink = false;
self->shape = NO_CURSOR_SHAPE; self->non_blinking = false;
}
void cursor_copy_to(Cursor *src, Cursor *dest) {
#define CCY(x) dest->x = src->x;
CCY(x); CCY(y); CCY(shape); CCY(blink);
CCY(x); CCY(y); CCY(shape); CCY(non_blinking);
CCY(bold); CCY(italic); CCY(strikethrough); CCY(dim); CCY(reverse); CCY(decoration); CCY(fg); CCY(bg); CCY(decoration_fg);
}
@ -252,7 +252,11 @@ BOOL_GETSET(Cursor, italic)
BOOL_GETSET(Cursor, reverse)
BOOL_GETSET(Cursor, strikethrough)
BOOL_GETSET(Cursor, dim)
BOOL_GETSET(Cursor, blink)
static PyObject* blink_get(Cursor *self, void UNUSED *closure) { PyObject *ans = !self->non_blinking ? Py_True : Py_False; Py_INCREF(ans); return ans; }
static int blink_set(Cursor *self, PyObject *value, void UNUSED *closure) { if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete attribute"); return -1; } self->non_blinking = PyObject_IsTrue(value) ? false : true; return 0; }
static PyMemberDef members[] = {
{"x", T_UINT, offsetof(Cursor, x), 0, "x"},

View File

@ -224,7 +224,7 @@ typedef struct {
typedef struct {
PyObject_HEAD
bool bold, italic, reverse, strikethrough, blink, dim;
bool bold, italic, reverse, strikethrough, dim, non_blinking;
unsigned int x, y;
uint8_t decoration;
CursorShape shape;

View File

@ -873,7 +873,7 @@ set_mode_from_const(Screen *self, unsigned int mode, bool val) {
}
break;
case CONTROL_CURSOR_BLINK:
self->cursor->blink = val;
self->cursor->non_blinking = !val;
break;
case SAVE_CURSOR:
screen_save_cursor(self);
@ -1679,8 +1679,8 @@ screen_set_cursor(Screen *self, unsigned int mode, uint8_t secondary) {
blink = mode % 2;
shape = (mode < 3) ? CURSOR_BLOCK : (mode < 5) ? CURSOR_UNDERLINE : (mode < 7) ? CURSOR_BEAM : NO_CURSOR_SHAPE;
}
if (shape != self->cursor->shape || blink != self->cursor->blink) {
self->cursor->shape = shape; self->cursor->blink = blink;
if (shape != self->cursor->shape || blink != !self->cursor->non_blinking) {
self->cursor->shape = shape; self->cursor->non_blinking = !blink;
}
break;
}
@ -1773,11 +1773,11 @@ screen_request_capabilities(Screen *self, char c, PyObject *q) {
case NUM_OF_CURSOR_SHAPES:
shape = 1; break;
case CURSOR_BLOCK:
shape = self->cursor->blink ? 0 : 2; break;
shape = self->cursor->non_blinking ? 2 : 0; break;
case CURSOR_UNDERLINE:
shape = self->cursor->blink ? 3 : 4; break;
shape = self->cursor->non_blinking ? 4 : 3; break;
case CURSOR_BEAM:
shape = self->cursor->blink ? 5 : 6; break;
shape = self->cursor->non_blinking ? 6 : 5; break;
}
shape = snprintf(buf, sizeof(buf), "1$r%d q", shape);
} else if (strcmp("m", query) == 0) {