Have the save/restore colors escape codes also save restore the ANSI color table
This commit is contained in:
parent
c3c5a5446f
commit
e97f1a4310
@ -180,23 +180,24 @@ rectangular region of the screen from (3, 4) to (10, 11), you use::
|
||||
<ESC>[2*x<ESC>[4;3;11;10;44$r<ESC>[*x
|
||||
|
||||
|
||||
Saving and restoring the default foreground/background/selection/cursor colors
|
||||
Saving and restoring colors
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
It is often useful for a full screen application with 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 lose 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::
|
||||
It is often useful for a full screen application with its own color themes to
|
||||
set the default foreground, background, selection and cursor colors and the
|
||||
ANSI color table. 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 lose 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::
|
||||
|
||||
<ESC>]30001<ESC>\ # push onto stack
|
||||
<ESC>]30101<ESC>\ # pop from stack
|
||||
|
||||
These escape codes save/restore the so called *dynamic colors*, default
|
||||
These escape codes save/restore the colors, default
|
||||
background, default foreground, selection background, selection foreground and
|
||||
cursor color.
|
||||
cursor color and the 256 colors of the ANSI color table.
|
||||
|
||||
|
||||
Pasting to clipboard
|
||||
|
||||
@ -318,19 +318,56 @@ 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;
|
||||
static void
|
||||
push_onto_color_stack_at(ColorProfile *self, unsigned int i) {
|
||||
self->color_stack[i].dynamic_colors = self->overridden;
|
||||
self->color_stack[i].valid = true;
|
||||
memcpy(self->color_stack[i].color_table, self->color_table, sizeof(self->color_stack->color_table));
|
||||
}
|
||||
|
||||
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 void
|
||||
copy_from_color_stack_at(ColorProfile *self, unsigned int i) {
|
||||
self->overridden = self->color_stack[i].dynamic_colors;
|
||||
memcpy(self->color_table, self->color_stack[i].color_table, sizeof(self->color_table));
|
||||
}
|
||||
|
||||
bool
|
||||
colorprofile_push_colors(ColorProfile *self, unsigned int idx) {
|
||||
if (idx == 0) {
|
||||
for (unsigned i = 0; i < arraysz(self->color_stack); i++) {
|
||||
if (!self->color_stack[i].valid) {
|
||||
push_onto_color_stack_at(self, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
memmove(self->color_stack, self->color_stack + 1, sizeof(self->color_stack) - sizeof(self->color_stack[0]));
|
||||
push_onto_color_stack_at(self, arraysz(self->color_stack) - 1);
|
||||
return true;
|
||||
}
|
||||
if (idx < arraysz(self->color_stack)) {
|
||||
push_onto_color_stack_at(self, idx);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
colorprofile_pop_colors(ColorProfile *self, unsigned int idx) {
|
||||
if (idx == 0) {
|
||||
for (unsigned i = arraysz(self->color_stack) - 1; i-- > 0; ) {
|
||||
if (self->color_stack[i].valid) {
|
||||
copy_from_color_stack_at(self, i);
|
||||
self->color_stack[i].valid = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (idx < arraysz(self->color_stack)) {
|
||||
copy_from_color_stack_at(self, idx);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
||||
@ -237,14 +237,20 @@ typedef struct {
|
||||
color_type default_fg, default_bg, cursor_color, cursor_text_color, cursor_text_uses_bg, highlight_fg, highlight_bg;
|
||||
} DynamicColor;
|
||||
|
||||
|
||||
typedef struct {
|
||||
DynamicColor dynamic_colors;
|
||||
uint32_t color_table[256];
|
||||
bool valid;
|
||||
} ColorStackEntry;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
bool dirty;
|
||||
uint32_t color_table[256];
|
||||
uint32_t orig_color_table[256];
|
||||
DynamicColor dynamic_color_stack[10];
|
||||
size_t dynamic_color_stack_idx;
|
||||
ColorStackEntry color_stack[16];
|
||||
DynamicColor configured, overridden;
|
||||
color_type mark_foregrounds[MARK_MASK+1], mark_backgrounds[MARK_MASK+1];
|
||||
} ColorProfile;
|
||||
@ -304,8 +310,8 @@ bool set_iutf8(int, bool);
|
||||
color_type colorprofile_to_color(ColorProfile *self, color_type entry, color_type defval);
|
||||
float cursor_text_as_bg(ColorProfile *self);
|
||||
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*);
|
||||
bool colorprofile_push_colors(ColorProfile*, unsigned int);
|
||||
bool colorprofile_pop_colors(ColorProfile*, unsigned int);
|
||||
|
||||
void set_mouse_cursor(MouseShape);
|
||||
void enter_event(void);
|
||||
|
||||
@ -414,11 +414,11 @@ dispatch_osc(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
|
||||
END_DISPATCH
|
||||
case 30001:
|
||||
REPORT_COMMAND(screen_push_dynamic_colors);
|
||||
screen_push_dynamic_colors(screen);
|
||||
screen_push_colors(screen, 0);
|
||||
break;
|
||||
case 30101:
|
||||
REPORT_COMMAND(screen_pop_dynamic_colors);
|
||||
screen_pop_dynamic_colors(screen);
|
||||
screen_pop_colors(screen, 0);
|
||||
break;
|
||||
default:
|
||||
REPORT_ERROR("Unknown OSC code: %u", code);
|
||||
|
||||
@ -1594,13 +1594,13 @@ screen_handle_cmd(Screen *self, PyObject *cmd) {
|
||||
}
|
||||
|
||||
void
|
||||
screen_push_dynamic_colors(Screen *self) {
|
||||
colorprofile_push_dynamic_colors(self->color_profile);
|
||||
screen_push_colors(Screen *self, unsigned int idx) {
|
||||
colorprofile_push_colors(self->color_profile, idx);
|
||||
}
|
||||
|
||||
void
|
||||
screen_pop_dynamic_colors(Screen *self) {
|
||||
colorprofile_pop_dynamic_colors(self->color_profile);
|
||||
screen_pop_colors(Screen *self, unsigned int idx) {
|
||||
colorprofile_pop_colors(self->color_profile, idx);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -179,8 +179,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_push_colors(Screen *, unsigned int);
|
||||
void screen_pop_colors(Screen *, unsigned int);
|
||||
void screen_handle_print(Screen *, PyObject *cmd);
|
||||
void screen_designate_charset(Screen *, uint32_t which, uint32_t as);
|
||||
void screen_use_latin1(Screen *, bool);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user