mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-23 00:38:10 +02:00
Store transparent colors on ColorProfile
This will eventually allow them to be changed using remote control and escape codes.
This commit is contained in:
@@ -80,9 +80,18 @@ set_configured_colors(ColorProfile *self, PyObject *opts) {
|
||||
n(default_fg, foreground); n(default_bg, background);
|
||||
n(cursor_color, cursor); n(cursor_text_color, cursor_text_color);
|
||||
n(highlight_fg, selection_foreground); n(highlight_bg, selection_background);
|
||||
n(visual_bell_color, visual_bell_color); n(second_transparent_bg, second_transparent_bg);
|
||||
n(visual_bell_color, visual_bell_color);
|
||||
#undef n
|
||||
return true;
|
||||
memset(self->configured_transparent_colors, 0, sizeof(self->configured_transparent_colors));
|
||||
RAII_PyObject(src, PyObject_GetAttrString(opts, "transparent_background_colors"));
|
||||
if (!src) { PyErr_SetString(PyExc_TypeError, "No transparent_background_colors on opts object"); return false; }
|
||||
for (Py_ssize_t i = 0; i < MIN(PyTuple_GET_SIZE(src), (Py_ssize_t)arraysz(self->configured_transparent_colors)); i++) {
|
||||
PyObject *e = PyTuple_GET_ITEM(src, i);
|
||||
self->configured_transparent_colors[i].color = ((Color*)(PyTuple_GET_ITEM(e, 0)))->color.val & 0xffffff;
|
||||
self->configured_transparent_colors[i].opacity = (float)PyFloat_AsDouble(PyTuple_GET_ITEM(e, 1));
|
||||
self->configured_transparent_colors[i].is_set = true;
|
||||
}
|
||||
return PyErr_Occurred() ? false : true;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -162,6 +171,8 @@ copy_color_profile(ColorProfile *dest, ColorProfile *src) {
|
||||
memcpy(dest->orig_color_table, src->orig_color_table, sizeof(dest->color_table));
|
||||
memcpy(&dest->configured, &src->configured, sizeof(dest->configured));
|
||||
memcpy(&dest->overridden, &src->overridden, sizeof(dest->overridden));
|
||||
memcpy(dest->overriden_transparent_colors, src->overriden_transparent_colors, sizeof(dest->overriden_transparent_colors));
|
||||
memcpy(dest->configured_transparent_colors, src->configured_transparent_colors, sizeof(dest->configured_transparent_colors));
|
||||
dest->dirty = true;
|
||||
}
|
||||
|
||||
@@ -226,12 +237,28 @@ patch_color_profiles(PyObject *module UNUSED, PyObject *args) {
|
||||
S(foreground, default_fg); S(background, default_bg); S(cursor, cursor_color);
|
||||
S(selection_foreground, highlight_fg); S(selection_background, highlight_bg);
|
||||
S(cursor_text_color, cursor_text_color); S(visual_bell_color, visual_bell_color);
|
||||
S(second_transparent_bg, second_transparent_bg);
|
||||
#undef SI
|
||||
#undef S
|
||||
// TODO: Patch transparent_colors
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
bool
|
||||
colorprofile_to_transparent_color(const ColorProfile *self, unsigned index, color_type *color, float *opacity) {
|
||||
*color = UINT32_MAX; *opacity = 1.0;
|
||||
if (index < arraysz(self->configured_transparent_colors)) {
|
||||
if (self->overriden_transparent_colors[index].is_set) {
|
||||
*color = self->overriden_transparent_colors[index].color; *opacity = self->overriden_transparent_colors[index].opacity;
|
||||
return true;
|
||||
}
|
||||
if (self->configured_transparent_colors[index].is_set) {
|
||||
*color = self->configured_transparent_colors[index].color; *opacity = self->configured_transparent_colors[index].opacity;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DynamicColor
|
||||
colorprofile_to_color(const ColorProfile *self, DynamicColor entry, DynamicColor defval) {
|
||||
switch(entry.type) {
|
||||
@@ -295,9 +322,10 @@ as_dict(ColorProfile *self, PyObject *args UNUSED) {
|
||||
}}
|
||||
D(default_fg, foreground); D(default_bg, background);
|
||||
D(cursor_color, cursor); D(cursor_text_color, cursor_text); D(highlight_fg, selection_foreground);
|
||||
D(highlight_bg, selection_background); D(visual_bell_color, visual_bell_color); D(second_transparent_bg, second_transparent_bg);
|
||||
D(highlight_bg, selection_background); D(visual_bell_color, visual_bell_color);
|
||||
|
||||
#undef D
|
||||
// TODO: Add transparent_colors
|
||||
return ans;
|
||||
}
|
||||
|
||||
@@ -373,6 +401,8 @@ copy_color_table_to_buffer(ColorProfile *self, color_type *buf, int offset, size
|
||||
|
||||
static void
|
||||
push_onto_color_stack_at(ColorProfile *self, unsigned int i) {
|
||||
self->color_stack[i].dynamic_colors = self->overridden;
|
||||
memcpy(self->color_stack[i].transparent_colors, self->overriden_transparent_colors, sizeof(self->overriden_transparent_colors));
|
||||
self->color_stack[i].dynamic_colors = self->overridden;
|
||||
memcpy(self->color_stack[i].color_table, self->color_table, sizeof(self->color_stack->color_table));
|
||||
}
|
||||
@@ -381,6 +411,7 @@ 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));
|
||||
memcpy(self->overriden_transparent_colors, self->color_stack[i].transparent_colors, sizeof(self->overriden_transparent_colors));
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -477,7 +508,6 @@ CGETSET(cursor_text_color, true)
|
||||
CGETSET(highlight_fg, true)
|
||||
CGETSET(highlight_bg, true)
|
||||
CGETSET(visual_bell_color, true)
|
||||
CGETSET(second_transparent_bg, true)
|
||||
#undef CGETSET
|
||||
|
||||
static PyGetSetDef cp_getsetters[] = {
|
||||
@@ -488,7 +518,6 @@ static PyGetSetDef cp_getsetters[] = {
|
||||
GETSET(highlight_fg)
|
||||
GETSET(highlight_bg)
|
||||
GETSET(visual_bell_color)
|
||||
GETSET(second_transparent_bg)
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
@@ -552,7 +581,7 @@ new_color(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) {
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
color_as_int(Color *self) {
|
||||
Color_as_int(Color *self) {
|
||||
return PyLong_FromUnsignedLong(self->color.val);
|
||||
}
|
||||
|
||||
@@ -566,7 +595,7 @@ color_truediv(Color *self, PyObject *divisor) {
|
||||
}
|
||||
|
||||
static PyNumberMethods color_number_methods = {
|
||||
.nb_int = (unaryfunc)color_as_int,
|
||||
.nb_int = (unaryfunc)Color_as_int,
|
||||
.nb_true_divide = (binaryfunc)color_truediv,
|
||||
};
|
||||
|
||||
|
||||
@@ -323,15 +323,21 @@ typedef union DynamicColor {
|
||||
} DynamicColor;
|
||||
|
||||
typedef struct {
|
||||
DynamicColor default_fg, default_bg, cursor_color, cursor_text_color, highlight_fg, highlight_bg, visual_bell_color, second_transparent_bg;
|
||||
DynamicColor default_fg, default_bg, cursor_color, cursor_text_color, highlight_fg, highlight_bg, visual_bell_color;
|
||||
} DynamicColors;
|
||||
|
||||
typedef struct TransparentDynamicColor {
|
||||
color_type color; float opacity; bool is_set;
|
||||
} TransparentDynamicColor;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
bool dirty;
|
||||
uint32_t color_table[256], orig_color_table[256];
|
||||
struct { DynamicColors dynamic_colors; uint32_t color_table[256]; } *color_stack;
|
||||
TransparentDynamicColor configured_transparent_colors[8], overriden_transparent_colors[8];
|
||||
struct { DynamicColors dynamic_colors; uint32_t color_table[256]; TransparentDynamicColor transparent_colors[8]; } *color_stack;
|
||||
unsigned int color_stack_idx, color_stack_sz;
|
||||
DynamicColors configured, overridden;
|
||||
color_type mark_foregrounds[MARK_MASK+1], mark_backgrounds[MARK_MASK+1];
|
||||
@@ -403,6 +409,7 @@ bool schedule_write_to_child_python(unsigned long id, const char *prefix, PyObje
|
||||
bool set_iutf8(int, bool);
|
||||
|
||||
DynamicColor colorprofile_to_color(const ColorProfile *self, DynamicColor entry, DynamicColor defval);
|
||||
bool colorprofile_to_transparent_color(const ColorProfile *self, unsigned index, color_type *color, float *opacity);
|
||||
color_type
|
||||
colorprofile_to_color_with_fallback(ColorProfile *self, DynamicColor entry, DynamicColor defval, DynamicColor fallback, DynamicColor falback_defval);
|
||||
void copy_color_table_to_buffer(ColorProfile *self, color_type *address, int offset, size_t stride);
|
||||
|
||||
@@ -809,11 +809,6 @@ class ColorProfile:
|
||||
@visual_bell_color.setter
|
||||
def visual_bell_color(self, val: Union[None|int|Color]) -> None: ...
|
||||
|
||||
@property
|
||||
def second_transparent_bg(self) -> Optional[Color]: ...
|
||||
@second_transparent_bg.setter
|
||||
def second_transparent_bg(self, val: Union[None|int|Color]) -> None: ...
|
||||
|
||||
def __init__(self, opts: Optional[Options] = None): ...
|
||||
|
||||
def as_dict(self) -> Dict[str, Optional[int]]:
|
||||
|
||||
@@ -1527,7 +1527,7 @@ opt('background_image_linear', 'no',
|
||||
long_text='When background image is scaled, whether linear interpolation should be used.'
|
||||
)
|
||||
|
||||
opt('transparent_background_colors', '', option_type='transparent_background_colors', ctype='!transparent_background_colors', long_text='''
|
||||
opt('transparent_background_colors', '', option_type='transparent_background_colors', long_text='''
|
||||
A space separated list of upto 7 colors, with opacity. When the background color of a cell matches one of these colors,
|
||||
it is rendered semi-transparent using the specified opacity.
|
||||
|
||||
|
||||
3
kitty/options/parse.py
generated
3
kitty/options/parse.py
generated
@@ -1194,9 +1194,6 @@ class Parser:
|
||||
def scrollback_pager_history_size(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['scrollback_pager_history_size'] = scrollback_pager_history_size(val)
|
||||
|
||||
def second_transparent_bg(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['second_transparent_bg'] = to_color_or_none(val)
|
||||
|
||||
def select_by_word_characters(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['select_by_word_characters'] = str(val)
|
||||
|
||||
|
||||
15
kitty/options/to-c-generated.h
generated
15
kitty/options/to-c-generated.h
generated
@@ -850,19 +850,6 @@ convert_from_opts_background_image_linear(PyObject *py_opts, Options *opts) {
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_transparent_background_colors(PyObject *val, Options *opts) {
|
||||
transparent_background_colors(val, opts);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_transparent_background_colors(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "transparent_background_colors");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_transparent_background_colors(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_dynamic_background_opacity(PyObject *val, Options *opts) {
|
||||
opts->dynamic_background_opacity = PyObject_IsTrue(val);
|
||||
@@ -1242,8 +1229,6 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_background_image_linear(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_transparent_background_colors(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_dynamic_background_opacity(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_background_tint(py_opts, opts);
|
||||
|
||||
@@ -441,17 +441,6 @@ window_logo_scale(PyObject *src, Options *opts) {
|
||||
opts->window_logo_scale.height = PyFloat_AsFloat(PyTuple_GET_ITEM(src, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
transparent_background_colors(PyObject *src, Options *opts) {
|
||||
memset(opts->transparent_background_colors, 0, sizeof(opts->transparent_background_colors));
|
||||
for (Py_ssize_t i = 0; i < MIN(PyTuple_GET_SIZE(src), (Py_ssize_t)arraysz(opts->transparent_background_colors)); i++) {
|
||||
PyObject *e = PyTuple_GET_ITEM(src, i);
|
||||
opts->transparent_background_colors[i].color = color_as_int(PyTuple_GET_ITEM(e, 0));
|
||||
opts->transparent_background_colors[i].opacity = PyFloat_AsFloat(PyTuple_GET_ITEM(e, 1));
|
||||
opts->transparent_background_colors[i].is_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
resize_debounce_time(PyObject *src, Options *opts) {
|
||||
opts->resize_debounce_time.on_end = s_double_to_monotonic_t(PyFloat_AsDouble(PyTuple_GET_ITEM(src, 0)));
|
||||
|
||||
3
kitty/options/types.py
generated
3
kitty/options/types.py
generated
@@ -409,7 +409,6 @@ option_names = ( # {{{
|
||||
'scrollback_lines',
|
||||
'scrollback_pager',
|
||||
'scrollback_pager_history_size',
|
||||
'second_transparent_bg',
|
||||
'select_by_word_characters',
|
||||
'select_by_word_characters_forward',
|
||||
'selection_background',
|
||||
@@ -575,7 +574,6 @@ class Options:
|
||||
scrollback_lines: int = 2000
|
||||
scrollback_pager: typing.List[str] = ['less', '--chop-long-lines', '--RAW-CONTROL-CHARS', '+INPUT_LINE_NUMBER']
|
||||
scrollback_pager_history_size: int = 0
|
||||
second_transparent_bg: typing.Optional[kitty.fast_data_types.Color] = None
|
||||
select_by_word_characters: str = '@-./_~?&=%+#'
|
||||
select_by_word_characters_forward: str = ''
|
||||
selection_background: typing.Optional[kitty.fast_data_types.Color] = Color(255, 250, 205)
|
||||
@@ -1037,7 +1035,6 @@ nullable_colors = frozenset({
|
||||
'active_border_color'
|
||||
'tab_bar_background'
|
||||
'tab_bar_margin_color'
|
||||
'second_transparent_bg'
|
||||
'selection_foreground'
|
||||
'selection_background'
|
||||
})
|
||||
@@ -313,10 +313,7 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c
|
||||
rd->highlight_fg = COLOR(highlight_fg); rd->highlight_bg = COLOR(highlight_bg);
|
||||
rd->bg_colors0 = COLOR(default_bg);
|
||||
rd->bg_opacities0 = os_window->is_semi_transparent ? os_window->background_opacity : 1.0f;
|
||||
#define SETBG(which) if (OPT(transparent_background_colors)[which-1].is_set) { \
|
||||
rd->bg_colors##which = OPT(transparent_background_colors)[which-1].color; \
|
||||
rd->bg_opacities##which = OPT(transparent_background_colors)[which-1].opacity < 0 ? rd->bg_opacities0 : OPT(transparent_background_colors)[which-1].opacity; \
|
||||
} else { rd->bg_colors##which = UINT32_MAX; }
|
||||
#define SETBG(which) colorprofile_to_transparent_color(cp, which - 1, &rd->bg_colors##which, &rd->bg_opacities##which)
|
||||
SETBG(1); SETBG(2); SETBG(3); SETBG(4); SETBG(5); SETBG(6); SETBG(7);
|
||||
#undef SETBG
|
||||
// selection
|
||||
|
||||
@@ -119,7 +119,6 @@ typedef struct {
|
||||
} *entries;
|
||||
} font_features;
|
||||
struct { Animation *cursor, *visual_bell; } animation;
|
||||
struct { color_type color; float opacity; bool is_set; } transparent_background_colors[8];
|
||||
} Options;
|
||||
|
||||
typedef struct WindowLogoRenderData {
|
||||
|
||||
@@ -453,11 +453,12 @@ def color_control(cp: ColorProfile, code: int, value: Union[str, bytes, memoryvi
|
||||
responses = {}
|
||||
for rec in value.split(';'):
|
||||
key, sep, val = rec.partition('=')
|
||||
# TODO: Add transparent_colors
|
||||
attr = {
|
||||
'foreground': 'default_fg', 'background': 'default_bg',
|
||||
'selection_background': 'highlight_bg', 'selection_foreground': 'highlight_fg',
|
||||
'cursor': 'cursor_color', 'cursor_text': 'cursor_text_color',
|
||||
'visual_bell': 'visual_bell_color', 'second_transparent_background': 'second_transparent_bg',
|
||||
'visual_bell': 'visual_bell_color',
|
||||
}.get(key, '')
|
||||
colnum = -1
|
||||
with suppress(Exception):
|
||||
|
||||
Reference in New Issue
Block a user