diff --git a/kittens/tui/operations.py b/kittens/tui/operations.py index 920bcd364..e77c2c28d 100644 --- a/kittens/tui/operations.py +++ b/kittens/tui/operations.py @@ -182,10 +182,11 @@ def init_state(alternate_screen=True): reset_mode('IRM') + reset_mode('DECKM') + reset_mode('DECSCNM') + set_mode('DECARM') + reset_mode('DECOM') + set_mode('DECAWM') + set_mode('DECTCEM') + reset_mode('MOUSE_BUTTON_TRACKING') + - reset_mode('MOUSE_MOTION_TRACKING') + reset_mode('MOUSE_MOVE_TRACKING') - + reset_mode('FOCUS_TRACKING') + reset_mode('MOUSE_UTF8_MODE') + + reset_mode('MOUSE_MOTION_TRACKING') + reset_mode('MOUSE_MOVE_TRACKING') + + reset_mode('FOCUS_TRACKING') + reset_mode('MOUSE_UTF8_MODE') + reset_mode('MOUSE_SGR_MODE') + reset_mode('MOUSE_UTF8_MODE') + set_mode('BRACKETED_PASTE') + set_mode('EXTENDED_KEYBOARD') + + '\033P@kitty-push-dynamic-colors\033\\' + '\033[*x' # reset DECSACE to default region select ) if alternate_screen: @@ -200,6 +201,7 @@ def reset_state(normal_screen=True): ans += reset_mode('ALTERNATE_SCREEN') ans += RESTORE_PRIVATE_MODE_VALUES ans += RESTORE_CURSOR + ans += '\033P@kitty-pop-dynamic-colors\033\\' return ans diff --git a/kitty/colors.c b/kitty/colors.c index 4ce8dfb8d..96514455d 100644 --- a/kitty/colors.c +++ b/kitty/colors.c @@ -220,6 +220,21 @@ copy_color_table_to_buffer(ColorProfile *self, color_type *buf, int offset, size self->dirty = false; } +void +colorprofile_push_dynamic_colors(ColorProfile *self) { + if (self->dynamic_color_stack_idx >= arraysz(self->dynamic_color_stack)) { + memmove(self->dynamic_color_stack, self->dynamic_color_stack + 1, sizeof(self->dynamic_color_stack) - sizeof(self->dynamic_color_stack[0])); + self->dynamic_color_stack_idx = arraysz(self->dynamic_color_stack) - 1; + } + self->dynamic_color_stack[self->dynamic_color_stack_idx++] = self->overridden; +} + +void +colorprofile_pop_dynamic_colors(ColorProfile *self) { + if (!self->dynamic_color_stack_idx) return; + self->overridden = self->dynamic_color_stack[--(self->dynamic_color_stack_idx)]; +} + static PyObject* color_table_address(ColorProfile *self, PyObject *a UNUSED) { #define color_table_address_doc "Pointer address to start of color table" diff --git a/kitty/data-types.h b/kitty/data-types.h index 47a915bcf..b7912c414 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -211,6 +211,8 @@ typedef struct { bool dirty; uint32_t color_table[256]; uint32_t orig_color_table[256]; + DynamicColor dynamic_color_stack[10]; + size_t dynamic_color_stack_idx; DynamicColor configured, overridden; } ColorProfile; @@ -275,6 +277,8 @@ bool set_iutf8(int, bool); color_type colorprofile_to_color(ColorProfile *self, color_type entry, color_type defval); void copy_color_table_to_buffer(ColorProfile *self, color_type *address, int offset, size_t stride); +void colorprofile_push_dynamic_colors(ColorProfile*); +void colorprofile_pop_dynamic_colors(ColorProfile*); void set_mouse_cursor(MouseShape); void mouse_event(int, int); diff --git a/kitty/parser.c b/kitty/parser.c index 47a56faa2..3ef6ae785 100644 --- a/kitty/parser.c +++ b/kitty/parser.c @@ -767,6 +767,16 @@ startswith(const uint32_t *string, size_t sz, const char *prefix) { return true; } +static inline bool +is_equal(const uint32_t *string, size_t sz, const char *prefix) { + size_t l = strlen(prefix); + if (sz != l) return false; + for (size_t i = 0; i < l; i++) { + if (string[i] != (unsigned char)prefix[i]) return false; + } + return true; +} + static inline void dispatch_dcs(Screen *screen, PyObject DUMP_UNUSED *dump_callback) { if (screen->parser_buf_pos < 2) return; @@ -794,6 +804,12 @@ dispatch_dcs(Screen *screen, PyObject DUMP_UNUSED *dump_callback) { Py_DECREF(cmd); } else PyErr_Clear(); #undef CMD_PREFIX + } else if (is_equal(screen->parser_buf + 1, screen->parser_buf_pos - 1, "kitty-push-dynamic-colors")) { + REPORT_COMMAND(screen_push_dynamic_colors); + screen_push_dynamic_colors(screen); + } else if (is_equal(screen->parser_buf + 1, screen->parser_buf_pos - 1, "kitty-pop-dynamic-colors")) { + REPORT_COMMAND(screen_pop_dynamic_colors); + screen_pop_dynamic_colors(screen); #define PRINT_PREFIX "kitty-print|" } else if (startswith(screen->parser_buf + 1, screen->parser_buf_pos - 1, PRINT_PREFIX)) { PyObject *msg = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, screen->parser_buf + sizeof(PRINT_PREFIX), screen->parser_buf_pos - sizeof(PRINT_PREFIX)); diff --git a/kitty/screen.c b/kitty/screen.c index 0eb0ee458..5ea900548 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1264,6 +1264,16 @@ screen_handle_cmd(Screen *self, PyObject *cmd) { CALLBACK("handle_remote_cmd", "O", cmd); } +void +screen_push_dynamic_colors(Screen *self) { + colorprofile_push_dynamic_colors(self->color_profile); +} + +void +screen_pop_dynamic_colors(Screen *self) { + colorprofile_pop_dynamic_colors(self->color_profile); +} + void screen_handle_print(Screen *self, PyObject *msg) { CALLBACK("handle_remote_print", "O", msg); diff --git a/kitty/screen.h b/kitty/screen.h index 0d79147db..80d4e5bac 100644 --- a/kitty/screen.h +++ b/kitty/screen.h @@ -139,6 +139,8 @@ void screen_erase_characters(Screen *self, unsigned int count); void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom); void screen_change_charset(Screen *, uint32_t to); void screen_handle_cmd(Screen *, PyObject *cmd); +void screen_push_dynamic_colors(Screen *); +void screen_pop_dynamic_colors(Screen *); void screen_handle_print(Screen *, PyObject *cmd); void screen_designate_charset(Screen *, uint32_t which, uint32_t as); void screen_use_latin1(Screen *, bool);