mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 16:37:27 +00:00
Start work on specifying a color for extra cursors
This commit is contained in:
parent
3239cec409
commit
da641982e2
3 changed files with 76 additions and 17 deletions
|
|
@ -174,7 +174,7 @@ static Line* range_line_(Screen *self, int y);
|
|||
void
|
||||
screen_reset(Screen *self) {
|
||||
screen_pause_rendering(self, false, 0);
|
||||
self->extra_cursors.count = 0;
|
||||
self->extra_cursors.count = 0; zero_at_ptr(&self->extra_cursors.color); self->extra_cursors.dirty = true;
|
||||
self->main_pointer_shape_stack.count = 0; self->alternate_pointer_shape_stack.count = 0;
|
||||
if (self->linebuf == self->alt_linebuf) screen_toggle_screen_buffer(self, true, true);
|
||||
if (screen_is_overlay_active(self)) {
|
||||
|
|
@ -191,10 +191,6 @@ screen_reset(Screen *self) {
|
|||
self->last_graphic_char = 0;
|
||||
self->main_savepoint.is_valid = false;
|
||||
self->alt_savepoint.is_valid = false;
|
||||
if (self->extra_cursors.count) {
|
||||
self->extra_cursors.count = 0;
|
||||
self->extra_cursors.dirty = true;
|
||||
}
|
||||
linebuf_clear(self->linebuf, BLANK_CHAR);
|
||||
historybuf_clear(self->historybuf);
|
||||
clear_hyperlink_pool(self->hyperlink_pool);
|
||||
|
|
@ -2870,8 +2866,9 @@ void
|
|||
screen_multi_cursor(Screen *self, int queried_shape, int *params, unsigned num_params) {
|
||||
// printf("%d;", queried_shape); for (unsigned i = 0; i < num_params; i++) {printf("%d:", params[i]);} printf("\n");
|
||||
if (!num_params) {
|
||||
#define pr(...) { int n = snprintf(p, sz - (p - buf), __VA_ARGS__); if (n >= 0 && (unsigned)n <= (sz - (p - buf))) p += n; }
|
||||
if (params == NULL) {
|
||||
write_escape_code_to_child(self, ESC_CSI, ">-2;-1;1;2;3 q");
|
||||
write_escape_code_to_child(self, ESC_CSI, ">-5;-4;-3;-2;-1;1;2;3 q");
|
||||
} else if (queried_shape == -2) {
|
||||
size_t sz = self->extra_cursors.count * 32 + 64;
|
||||
RAII_ALLOC(char, buf, malloc(sz)); sz -= 4;
|
||||
|
|
@ -2880,14 +2877,48 @@ screen_multi_cursor(Screen *self, int queried_shape, int *params, unsigned num_p
|
|||
for (unsigned i = 0; i < self->extra_cursors.count; i++) {
|
||||
index_type cell = self->extra_cursors.locations[i].cell, shape = self->extra_cursors.locations[i].shape;
|
||||
index_type y = cell / self->columns, x = cell - (y * self->columns);
|
||||
int n = snprintf(p, sz - (p - buf), "%d:2:%u:%u;", shape > 3 ? -1 : (int)shape, y+1, x+1);
|
||||
if (n < 0 || (unsigned)n > (sz - (p - buf))) break;
|
||||
p += n;
|
||||
pr("%d:2:%u:%u;", shape > 3 ? -1 : (int)shape, y+1, x+1);
|
||||
}
|
||||
if (*(p-1) == ';') p--;
|
||||
*(p++) = ' '; *(p++) = 'q'; *(p++) = 0;
|
||||
write_escape_code_to_child(self, ESC_CSI, buf);
|
||||
}
|
||||
} else if (queried_shape == -5) {
|
||||
char buf[64], *p = buf; size_t sz = sizeof(buf);
|
||||
pr(">-5;-3:"); ExtraCursorColor ecc = self->extra_cursors.color.cursor;
|
||||
#define o() { \
|
||||
if (ecc.is_set) { \
|
||||
if (ecc.is_none) { pr("1"); } \
|
||||
else { \
|
||||
if (ecc.is_lookup) { pr("5:%u", ecc.color & 0xff); } \
|
||||
else { pr("2:%u:%u:%u", (ecc.color >> 16) & 0xff, (ecc.color >> 8) & 0xff, ecc.color & 0xff); } \
|
||||
} \
|
||||
} else pr("0"); }
|
||||
|
||||
o(); pr(";-4:"); ecc = self->extra_cursors.color.text; o();
|
||||
#undef o
|
||||
pr(" q");
|
||||
write_escape_code_to_child(self, ESC_CSI, buf);
|
||||
}
|
||||
return;
|
||||
#undef pr
|
||||
}
|
||||
if (queried_shape == -3 || queried_shape == -4) {
|
||||
ExtraCursorColor *ecc = queried_shape == -3 ? &self->extra_cursors.color.cursor : &self->extra_cursors.color.text;
|
||||
self->extra_cursors.dirty = true;
|
||||
switch (params[0]) {
|
||||
case 0: zero_at_ptr(ecc); break;
|
||||
case 1: zero_at_ptr(ecc); ecc->is_set = true; ecc->is_none = true; break;
|
||||
case 2: if (num_params > 3) {
|
||||
zero_at_ptr(ecc);
|
||||
ecc->is_set = true;
|
||||
ecc->color = ((params[1] & 0xff) << 16) | ((params[2] & 0xff) << 8) | (params[3] & 0xff);
|
||||
} break;
|
||||
case 5: if (num_params > 1) {
|
||||
zero_at_ptr(ecc);
|
||||
ecc->is_set = true; ecc->is_lookup = true;
|
||||
ecc->color = params[1] & 0xff;
|
||||
} break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,9 +92,15 @@ typedef struct ExtraCursor {
|
|||
index_type cell;
|
||||
} ExtraCursor;
|
||||
|
||||
typedef struct ExtraCursorColor {
|
||||
color_type color;
|
||||
bool is_set, is_none, is_lookup;
|
||||
} ExtraCursorColor;
|
||||
|
||||
typedef struct ExtraCursors {
|
||||
ExtraCursor *locations;
|
||||
unsigned count, capacity;
|
||||
struct { ExtraCursorColor cursor, text; } color;
|
||||
bool dirty;
|
||||
} ExtraCursors;
|
||||
|
||||
|
|
|
|||
|
|
@ -1594,13 +1594,15 @@ class TestScreen(BaseTest):
|
|||
s = self.create_screen()
|
||||
c = s.callbacks
|
||||
# Test detection
|
||||
parse_bytes(s, b'\x1b[> q') # ]
|
||||
self.ae(c.wtcbuf, b'\x1b[>-2;-1;1;2;3 q') # ]
|
||||
def ec(payload=''):
|
||||
return f'\x1b[>{payload} q'.encode() # ]
|
||||
parse_bytes(s, ec())
|
||||
self.ae(c.wtcbuf, ec('-5;-4;-3;-2;-1;1;2;3'))
|
||||
|
||||
def current() -> dict[int, tuple[int, int]]:
|
||||
ans = {}
|
||||
c.clear()
|
||||
parse_bytes(s, '\x1b[>-2 q'.encode()) # ]
|
||||
parse_bytes(s, ec('-2'))
|
||||
for entry in c.wtcbuf[6:-2].decode().split(';'):
|
||||
if entry:
|
||||
which, _, y, x = map(int, entry.split(':'))
|
||||
|
|
@ -1615,10 +1617,10 @@ class TestScreen(BaseTest):
|
|||
parse_bytes(s, ''.join(buf).encode() + b' q')
|
||||
if region:
|
||||
if region is True:
|
||||
parse_bytes(s, f'\x1b[>{which};4 q'.encode()) # ]
|
||||
parse_bytes(s, ec(f'{which};4'))
|
||||
else:
|
||||
left, top, right, bottom = region
|
||||
parse_bytes(s, f'\x1b[>{which};4:{top+1}:{left+1}:{bottom+1}:{right+1} q'.encode()) # ]
|
||||
parse_bytes(s, ec(f'{which};4:{top+1}:{left+1}:{bottom+1}:{right+1}'))
|
||||
return current()
|
||||
|
||||
self.ae(a(1, region=True), {1:{(x, y) for x in range(s.columns) for y in range(s.lines)}})
|
||||
|
|
@ -1628,13 +1630,33 @@ class TestScreen(BaseTest):
|
|||
self.ae(a(0, (1, 2), (2, 3)), {-1: {(2, 2)}, 2: {(1, 3)}})
|
||||
self.ae(a(0, region=True), {})
|
||||
s.cursor.x, s.cursor.y = 1, 2
|
||||
parse_bytes(s, b'\x1b[>3;0 q') # ]
|
||||
parse_bytes(s, ec('3;0'))
|
||||
self.ae(current(), {3: {(1, 2)}})
|
||||
parse_bytes(s, b'\x1b[>3;2:3 q') # ]
|
||||
parse_bytes(s, ec('3;2:3'))
|
||||
self.ae(current(), {3: {(1, 2)}})
|
||||
parse_bytes(s, b'\x1b[>0;4:3:1:4 q') # ]
|
||||
parse_bytes(s, ec('0;4:3:1:4'))
|
||||
self.ae(current(), {})
|
||||
|
||||
def sc(op, r=0, g=0, b=0, slot=-3):
|
||||
parse_bytes(s, ec(f'{slot};{op}:{r}:{g}:{b}'))
|
||||
c.clear()
|
||||
parse_bytes(s, ec('-5'))
|
||||
for x in c.wtcbuf[3:-2].decode().split(';')[1:]:
|
||||
parts = x.split(':')
|
||||
if int(parts[0]) == slot:
|
||||
if op < 2:
|
||||
self.ae(op, int(parts[1]))
|
||||
elif op == 2:
|
||||
self.ae((op, r, g, b), tuple(map(int, parts[1:])))
|
||||
else:
|
||||
self.ae((op, r), tuple(map(int, parts[1:])))
|
||||
break
|
||||
for slot in (-3, -4):
|
||||
sc(0, slot=slot)
|
||||
sc(1, slot=slot)
|
||||
sc(2, 1, 2, 3, slot=slot)
|
||||
sc(5, 13, slot=slot)
|
||||
|
||||
|
||||
def detect_url(self, scale=1):
|
||||
s = self.create_screen(cols=30 * scale)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue