From 6f7ea490081a594fafba190f315c7ea2579c91fb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 15 Jun 2018 15:21:46 +0530 Subject: [PATCH] Switch to high number OSC codes instead of DCS string codes for dynamic color push/pop --- docs/protocol-extensions.rst | 19 +++++++++++++++++++ kittens/tui/operations.py | 4 ++-- kitty/parser.c | 24 ++++++++---------------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/docs/protocol-extensions.rst b/docs/protocol-extensions.rst index a70b7935e..20478d35c 100644 --- a/docs/protocol-extensions.rst +++ b/docs/protocol-extensions.rst @@ -165,3 +165,22 @@ For example, to set the background color to blue in a rectangular region of the screen from (3, 4) to (10, 11), you use:: [2*x[4;3;11;10;44$r[*x + + +Saving and restoring the default foreground/background/selection/cursor colors +--------------------------------------------------------------------------------- + +It is often useful for a full screen application that has its own color themes +to set the default foreground, background, selection and cursor colors. This +allows for various performance optimizations when drawing the screen. The +problem is that if the user previously used the escape codes to change these +colors herself, then running the full screen application will overwrite her +changes even after it exits. To avoid this, kitty introduces a new pair of +*OSC* escape codes to push and pop the current color values from a stack:: + + ]30001\ # push onto stack + ]30101\ # pop from stack + +These escape codes save/restore the so called *dynamic colors*, default +background, default foreground, selection background, selection foreground and +cursor color. diff --git a/kittens/tui/operations.py b/kittens/tui/operations.py index 5b75cf906..19738388b 100644 --- a/kittens/tui/operations.py +++ b/kittens/tui/operations.py @@ -193,7 +193,7 @@ def init_state(alternate_screen=True): 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]30001\033\\' + '\033[*x' # reset DECSACE to default region select ) if alternate_screen: @@ -208,7 +208,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\\' + ans += '\033]30101\033\\' return ans diff --git a/kitty/parser.c b/kitty/parser.c index 3ef6ae785..9ff85f555 100644 --- a/kitty/parser.c +++ b/kitty/parser.c @@ -344,6 +344,14 @@ dispatch_osc(Screen *screen, PyObject DUMP_UNUSED *dump_callback) { case 52: DISPATCH_OSC(clipboard_control); break; + case 30001: + REPORT_COMMAND(screen_push_dynamic_colors); + screen_push_dynamic_colors(screen); + break; + case 30101: + REPORT_COMMAND(screen_pop_dynamic_colors); + screen_pop_dynamic_colors(screen); + break; default: REPORT_ERROR("Unknown OSC code: %u", code); break; @@ -767,16 +775,6 @@ 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; @@ -804,12 +802,6 @@ 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));