Fix set-colors unable to set tab_bar_background to none
This commit is contained in:
parent
23d0db5458
commit
63e23d7fe3
@ -1687,16 +1687,16 @@ class Boss:
|
|||||||
window.screen.disable_ligatures = strategy
|
window.screen.disable_ligatures = strategy
|
||||||
window.refresh()
|
window.refresh()
|
||||||
|
|
||||||
def patch_colors(self, spec: Dict[str, int], cursor_text_color: Union[bool, int, Color], configured: bool = False) -> None:
|
def patch_colors(self, spec: Dict[str, Optional[int]], configured: bool = False) -> None:
|
||||||
opts = get_options()
|
opts = get_options()
|
||||||
if configured:
|
if configured:
|
||||||
for k, v in spec.items():
|
for k, v in spec.items():
|
||||||
if hasattr(opts, k):
|
if hasattr(opts, k):
|
||||||
|
if v is None:
|
||||||
|
if k in ('cursor_text_color', 'tab_bar_background'):
|
||||||
|
setattr(opts, k, None)
|
||||||
|
else:
|
||||||
setattr(opts, k, color_from_int(v))
|
setattr(opts, k, color_from_int(v))
|
||||||
if cursor_text_color is not False:
|
|
||||||
if isinstance(cursor_text_color, int):
|
|
||||||
cursor_text_color = color_from_int(cursor_text_color)
|
|
||||||
opts.cursor_text_color = cursor_text_color
|
|
||||||
for tm in self.all_tab_managers:
|
for tm in self.all_tab_managers:
|
||||||
tm.tab_bar.patch_colors(spec)
|
tm.tab_bar.patch_colors(spec)
|
||||||
patch_global_colors(spec, configured)
|
patch_global_colors(spec, configured)
|
||||||
|
|||||||
@ -114,7 +114,7 @@ copy_color_profile(ColorProfile *dest, ColorProfile *src) {
|
|||||||
static void
|
static void
|
||||||
patch_color_table(const char *key, PyObject *profiles, PyObject *spec, size_t which, int change_configured) {
|
patch_color_table(const char *key, PyObject *profiles, PyObject *spec, size_t which, int change_configured) {
|
||||||
PyObject *v = PyDict_GetItemString(spec, key);
|
PyObject *v = PyDict_GetItemString(spec, key);
|
||||||
if (v) {
|
if (v && PyLong_Check(v)) {
|
||||||
color_type color = PyLong_AsUnsignedLong(v);
|
color_type color = PyLong_AsUnsignedLong(v);
|
||||||
for (Py_ssize_t j = 0; j < PyTuple_GET_SIZE(profiles); j++) {
|
for (Py_ssize_t j = 0; j < PyTuple_GET_SIZE(profiles); j++) {
|
||||||
ColorProfile *self = (ColorProfile*)PyTuple_GET_ITEM(profiles, j);
|
ColorProfile *self = (ColorProfile*)PyTuple_GET_ITEM(profiles, j);
|
||||||
@ -128,7 +128,7 @@ patch_color_table(const char *key, PyObject *profiles, PyObject *spec, size_t wh
|
|||||||
|
|
||||||
#define patch_mark_color(key, profiles, spec, array, i) { \
|
#define patch_mark_color(key, profiles, spec, array, i) { \
|
||||||
PyObject *v = PyDict_GetItemString(spec, key); \
|
PyObject *v = PyDict_GetItemString(spec, key); \
|
||||||
if (v) { \
|
if (v && PyLong_Check(v)) { \
|
||||||
color_type color = PyLong_AsUnsignedLong(v); \
|
color_type color = PyLong_AsUnsignedLong(v); \
|
||||||
for (Py_ssize_t j = 0; j < PyTuple_GET_SIZE(profiles); j++) { \
|
for (Py_ssize_t j = 0; j < PyTuple_GET_SIZE(profiles); j++) { \
|
||||||
ColorProfile *self = (ColorProfile*)PyTuple_GET_ITEM(profiles, j); \
|
ColorProfile *self = (ColorProfile*)PyTuple_GET_ITEM(profiles, j); \
|
||||||
@ -139,8 +139,8 @@ patch_color_table(const char *key, PyObject *profiles, PyObject *spec, size_t wh
|
|||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
patch_color_profiles(PyObject *module UNUSED, PyObject *args) {
|
patch_color_profiles(PyObject *module UNUSED, PyObject *args) {
|
||||||
PyObject *spec, *profiles, *v; ColorProfile *self; int change_configured; PyObject *cursor_text_color;
|
PyObject *spec, *profiles, *v; ColorProfile *self; int change_configured;
|
||||||
if (!PyArg_ParseTuple(args, "O!OO!p", &PyDict_Type, &spec, &cursor_text_color, &PyTuple_Type, &profiles, &change_configured)) return NULL;
|
if (!PyArg_ParseTuple(args, "O!O!p", &PyDict_Type, &spec, &PyTuple_Type, &profiles, &change_configured)) return NULL;
|
||||||
char key[32] = {0};
|
char key[32] = {0};
|
||||||
for (size_t i = 0; i < arraysz(FG_BG_256); i++) {
|
for (size_t i = 0; i < arraysz(FG_BG_256); i++) {
|
||||||
snprintf(key, sizeof(key) - 1, "color%zu", i);
|
snprintf(key, sizeof(key) - 1, "color%zu", i);
|
||||||
@ -153,7 +153,7 @@ patch_color_profiles(PyObject *module UNUSED, PyObject *args) {
|
|||||||
}
|
}
|
||||||
#define S(config_name, profile_name) { \
|
#define S(config_name, profile_name) { \
|
||||||
v = PyDict_GetItemString(spec, #config_name); \
|
v = PyDict_GetItemString(spec, #config_name); \
|
||||||
if (v) { \
|
if (v && PyLong_Check(v)) { \
|
||||||
color_type color = PyLong_AsUnsignedLong(v); \
|
color_type color = PyLong_AsUnsignedLong(v); \
|
||||||
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(profiles); i++) { \
|
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(profiles); i++) { \
|
||||||
self = (ColorProfile*)PyTuple_GET_ITEM(profiles, i); \
|
self = (ColorProfile*)PyTuple_GET_ITEM(profiles, i); \
|
||||||
@ -166,12 +166,13 @@ patch_color_profiles(PyObject *module UNUSED, PyObject *args) {
|
|||||||
S(foreground, default_fg); S(background, default_bg); S(cursor, cursor_color);
|
S(foreground, default_fg); S(background, default_bg); S(cursor, cursor_color);
|
||||||
S(selection_foreground, highlight_fg); S(selection_background, highlight_bg);
|
S(selection_foreground, highlight_fg); S(selection_background, highlight_bg);
|
||||||
#undef S
|
#undef S
|
||||||
if (cursor_text_color != Py_False) {
|
PyObject *cursor_text_color = PyDict_GetItemString(spec, "cursor_text_color");
|
||||||
|
if (cursor_text_color) {
|
||||||
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(profiles); i++) {
|
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(profiles); i++) {
|
||||||
self = (ColorProfile*)PyTuple_GET_ITEM(profiles, i);
|
self = (ColorProfile*)PyTuple_GET_ITEM(profiles, i);
|
||||||
self->overridden.cursor_text_color = 0x111111;
|
self->overridden.cursor_text_color = 0x111111;
|
||||||
self->overridden.cursor_text_uses_bg = 3;
|
self->overridden.cursor_text_uses_bg = 3;
|
||||||
if (cursor_text_color != Py_None) {
|
if (PyLong_Check(cursor_text_color)) {
|
||||||
self->overridden.cursor_text_color = (PyLong_AsUnsignedLong(cursor_text_color) << 8) | 2;
|
self->overridden.cursor_text_color = (PyLong_AsUnsignedLong(cursor_text_color) << 8) | 2;
|
||||||
self->overridden.cursor_text_uses_bg = 1;
|
self->overridden.cursor_text_uses_bg = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -614,7 +614,7 @@ def safe_pipe(nonblock: bool = True) -> Tuple[int, int]:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def patch_global_colors(spec: Dict[str, int], configured: bool) -> None:
|
def patch_global_colors(spec: Dict[str, Optional[int]], configured: bool) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -647,8 +647,7 @@ class ColorProfile:
|
|||||||
|
|
||||||
|
|
||||||
def patch_color_profiles(
|
def patch_color_profiles(
|
||||||
spec: Dict[str, int], cursor_text_color: Optional[Union[bool, int]],
|
spec: Dict[str, Optional[int]], profiles: Tuple[ColorProfile, ...], change_configured: bool
|
||||||
profiles: Tuple[ColorProfile, ...], change_configured: bool
|
|
||||||
) -> None:
|
) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -281,9 +281,9 @@ class LaunchKwds(TypedDict):
|
|||||||
|
|
||||||
def apply_colors(window: Window, spec: Sequence[str]) -> None:
|
def apply_colors(window: Window, spec: Sequence[str]) -> None:
|
||||||
from kitty.rc.set_colors import parse_colors
|
from kitty.rc.set_colors import parse_colors
|
||||||
colors, cursor_text_color = parse_colors(spec)
|
colors = parse_colors(spec)
|
||||||
profiles = window.screen.color_profile,
|
profiles = window.screen.color_profile,
|
||||||
patch_color_profiles(colors, cursor_text_color, profiles, True)
|
patch_color_profiles(colors, profiles, True)
|
||||||
|
|
||||||
|
|
||||||
def launch(
|
def launch(
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from typing import TYPE_CHECKING, Dict, Iterable, Optional, Tuple, Union
|
from typing import TYPE_CHECKING, Dict, Iterable, Optional
|
||||||
|
|
||||||
from kitty.config import parse_config
|
from kitty.config import parse_config
|
||||||
from kitty.fast_data_types import patch_color_profiles
|
from kitty.fast_data_types import patch_color_profiles
|
||||||
@ -18,24 +18,29 @@ if TYPE_CHECKING:
|
|||||||
from kitty.cli_stub import SetColorsRCOptions as CLIOptions
|
from kitty.cli_stub import SetColorsRCOptions as CLIOptions
|
||||||
|
|
||||||
|
|
||||||
def parse_colors(args: Iterable[str]) -> Tuple[Dict[str, int], Optional[Union[int, bool]]]:
|
def parse_colors(args: Iterable[str]) -> Dict[str, Optional[int]]:
|
||||||
colors: Dict[str, Optional[Color]] = {}
|
colors: Dict[str, Optional[Color]] = {}
|
||||||
|
nullable_colors: Dict[str, Optional[int]] = {}
|
||||||
for spec in args:
|
for spec in args:
|
||||||
if '=' in spec:
|
if '=' in spec:
|
||||||
colors.update(parse_config((spec.replace('=', ' '),)))
|
colors.update(parse_config((spec.replace('=', ' '),)))
|
||||||
else:
|
else:
|
||||||
with open(os.path.expanduser(spec), encoding='utf-8', errors='replace') as f:
|
with open(os.path.expanduser(spec), encoding='utf-8', errors='replace') as f:
|
||||||
colors.update(parse_config(f))
|
colors.update(parse_config(f))
|
||||||
q = colors.pop('cursor_text_color', False)
|
for k in ('cursor_text_color', 'tab_bar_background'):
|
||||||
ctc = int(q) if isinstance(q, Color) else (False if q is False else None)
|
q = colors.pop(k, False)
|
||||||
return {k: int(v) for k, v in colors.items() if isinstance(v, Color)}, ctc
|
if q is not False:
|
||||||
|
val = int(q) if isinstance(q, Color) else None
|
||||||
|
nullable_colors[k] = val
|
||||||
|
ans: Dict[str, Optional[int]] = {k: int(v) for k, v in colors.items() if isinstance(v, Color)}
|
||||||
|
ans.update(nullable_colors)
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class SetColors(RemoteCommand):
|
class SetColors(RemoteCommand):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
colors+: An object mapping names to colors as 24-bit RGB integers
|
colors+: An object mapping names to colors as 24-bit RGB integers or null for nullable colors
|
||||||
cursor_text_color: A 24-bit color for text under the cursor, or null to use background.
|
|
||||||
match_window: Window to change colors in
|
match_window: Window to change colors in
|
||||||
match_tab: Tab to change colors in
|
match_tab: Tab to change colors in
|
||||||
all: Boolean indicating change colors everywhere or not
|
all: Boolean indicating change colors everywhere or not
|
||||||
@ -72,35 +77,28 @@ this option, any color arguments are ignored and --configured and --all are impl
|
|||||||
args_completion = {'files': ('CONF files', ('*.conf',))}
|
args_completion = {'files': ('CONF files', ('*.conf',))}
|
||||||
|
|
||||||
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
|
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
|
||||||
final_colors: Dict[str, int] = {}
|
final_colors: Dict[str, Optional[int]] = {}
|
||||||
cursor_text_color: Optional[Union[int, bool]] = False
|
|
||||||
if not opts.reset:
|
if not opts.reset:
|
||||||
try:
|
try:
|
||||||
final_colors, cursor_text_color = parse_colors(args)
|
final_colors = parse_colors(args)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
raise ParsingOfArgsFailed(str(err)) from err
|
raise ParsingOfArgsFailed(str(err)) from err
|
||||||
ans = {
|
ans = {
|
||||||
'match_window': opts.match, 'match_tab': opts.match_tab,
|
'match_window': opts.match, 'match_tab': opts.match_tab,
|
||||||
'all': opts.all or opts.reset, 'configured': opts.configured or opts.reset,
|
'all': opts.all or opts.reset, 'configured': opts.configured or opts.reset,
|
||||||
'colors': final_colors, 'reset': opts.reset, 'dummy': 0
|
'colors': final_colors, 'reset': opts.reset,
|
||||||
}
|
}
|
||||||
if cursor_text_color is not False:
|
|
||||||
ans['cursor_text_color'] = cursor_text_color
|
|
||||||
del ans['dummy']
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
||||||
windows = self.windows_for_payload(boss, window, payload_get)
|
windows = self.windows_for_payload(boss, window, payload_get)
|
||||||
colors = payload_get('colors')
|
colors: Dict[str, Optional[int]] = payload_get('colors')
|
||||||
cursor_text_color = payload_get('cursor_text_color', missing=False)
|
|
||||||
if payload_get('reset'):
|
if payload_get('reset'):
|
||||||
colors = {k: int(v) for k, v in boss.startup_colors.items()}
|
colors = {k: int(v) for k, v in boss.startup_colors.items()}
|
||||||
cursor_text_color = boss.startup_cursor_text_color
|
colors['cursor_text_color'] = None if boss.startup_cursor_text_color is None else int(boss.startup_cursor_text_color)
|
||||||
profiles = tuple(w.screen.color_profile for w in windows)
|
profiles = tuple(w.screen.color_profile for w in windows)
|
||||||
if isinstance(cursor_text_color, (tuple, list, Color)):
|
patch_color_profiles(colors, profiles, payload_get('configured'))
|
||||||
cursor_text_color = int(Color(*cursor_text_color))
|
boss.patch_colors(colors, payload_get('configured'))
|
||||||
patch_color_profiles(colors, cursor_text_color, profiles, payload_get('configured'))
|
|
||||||
boss.patch_colors(colors, cursor_text_color, payload_get('configured'))
|
|
||||||
default_bg_changed = 'background' in colors
|
default_bg_changed = 'background' in colors
|
||||||
for w in windows:
|
for w in windows:
|
||||||
if default_bg_changed:
|
if default_bg_changed:
|
||||||
|
|||||||
@ -942,13 +942,14 @@ PYWRAP1(patch_global_colors) {
|
|||||||
if (!PyArg_ParseTuple(args, "Op", &spec, &configured)) return NULL;
|
if (!PyArg_ParseTuple(args, "Op", &spec, &configured)) return NULL;
|
||||||
#define P(name) { \
|
#define P(name) { \
|
||||||
PyObject *val = PyDict_GetItemString(spec, #name); \
|
PyObject *val = PyDict_GetItemString(spec, #name); \
|
||||||
if (val && PyLong_Check(val)) { \
|
if (val) { \
|
||||||
OPT(name) = PyLong_AsLong(val); \
|
if (val == Py_None) OPT(name) = 0; \
|
||||||
|
else if (PyLong_Check(val)) OPT(name) = PyLong_AsLong(val); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
P(active_border_color); P(inactive_border_color); P(bell_border_color);
|
P(active_border_color); P(inactive_border_color); P(bell_border_color); P(tab_bar_background);
|
||||||
if (configured) {
|
if (configured) {
|
||||||
P(background); P(url_color); P(tab_bar_background);
|
P(background); P(url_color);
|
||||||
P(mark1_background); P(mark1_foreground); P(mark2_background); P(mark2_foreground);
|
P(mark1_background); P(mark1_foreground); P(mark2_background); P(mark2_foreground);
|
||||||
P(mark3_background); P(mark3_foreground);
|
P(mark3_background); P(mark3_foreground);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -457,32 +457,40 @@ class TabBar:
|
|||||||
else:
|
else:
|
||||||
self.align = lambda: None
|
self.align = lambda: None
|
||||||
|
|
||||||
def patch_colors(self, spec: Dict[str, Any]) -> None:
|
def patch_colors(self, spec: Dict[str, Optional[int]]) -> None:
|
||||||
if 'active_tab_foreground' in spec:
|
|
||||||
self.active_fg = (spec['active_tab_foreground'] << 8) | 2
|
|
||||||
self.draw_data = self.draw_data._replace(active_fg=color_from_int(spec['active_tab_foreground']))
|
|
||||||
if 'active_tab_background' in spec:
|
|
||||||
self.active_bg = (spec['active_tab_background'] << 8) | 2
|
|
||||||
self.draw_data = self.draw_data._replace(active_bg=color_from_int(spec['active_tab_background']))
|
|
||||||
if 'inactive_tab_background' in spec:
|
|
||||||
self.draw_data = self.draw_data._replace(inactive_bg=color_from_int(spec['inactive_tab_background']))
|
|
||||||
if 'tab_bar_background' in spec:
|
|
||||||
self.draw_data = self.draw_data._replace(default_bg=color_from_int(spec['tab_bar_background']))
|
|
||||||
opts = get_options()
|
opts = get_options()
|
||||||
fg = spec.get('inactive_tab_foreground', color_as_int(opts.inactive_tab_foreground))
|
atf = spec.get('active_tab_foreground')
|
||||||
|
if isinstance(atf, int):
|
||||||
|
self.active_fg = (atf << 8) | 2
|
||||||
|
self.draw_data = self.draw_data._replace(active_fg=color_from_int(atf))
|
||||||
|
atb = spec.get('active_tab_background')
|
||||||
|
if isinstance(atb, int):
|
||||||
|
self.active_bg = (atb << 8) | 2
|
||||||
|
self.draw_data = self.draw_data._replace(active_bg=color_from_int(atb))
|
||||||
|
itb = spec.get('inactive_tab_background')
|
||||||
|
if isinstance(itb, int):
|
||||||
|
self.draw_data = self.draw_data._replace(inactive_bg=color_from_int(itb))
|
||||||
|
if 'tab_bar_background' in spec:
|
||||||
|
val = spec['tab_bar_background']
|
||||||
|
if val is None:
|
||||||
|
val = color_as_int(opts.background)
|
||||||
|
self.draw_data = self.draw_data._replace(default_bg=color_from_int(val))
|
||||||
bg = spec.get('tab_bar_background', False)
|
bg = spec.get('tab_bar_background', False)
|
||||||
if bg is None:
|
if bg is None:
|
||||||
bg = color_as_int(opts.background)
|
bg = color_as_int(opts.background)
|
||||||
elif bg is False:
|
elif bg is False:
|
||||||
bg = color_as_int(opts.tab_bar_background or opts.background)
|
bg = color_as_int(opts.tab_bar_background or opts.background)
|
||||||
|
fg = spec.get('inactive_tab_foreground')
|
||||||
|
if fg is None:
|
||||||
|
fg = color_as_int(opts.inactive_tab_foreground)
|
||||||
self.screen.color_profile.set_configured_colors(fg, bg)
|
self.screen.color_profile.set_configured_colors(fg, bg)
|
||||||
|
|
||||||
def update_blank_rects(self) -> None:
|
def update_blank_rects(self) -> None:
|
||||||
opts = get_options()
|
opts = get_options()
|
||||||
central, tab_bar, vw, vh, cell_width, cell_height = viewport_for_window(self.os_window_id)
|
central, tab_bar, vw, vh, cell_width, cell_height = viewport_for_window(self.os_window_id)
|
||||||
blank_rects: List[Border] = []
|
blank_rects: List[Border] = []
|
||||||
if opts.tab_bar_margin_height:
|
|
||||||
bg = BorderColor.default_bg
|
bg = BorderColor.default_bg
|
||||||
|
if opts.tab_bar_margin_height:
|
||||||
if opts.tab_bar_edge == 3: # bottom
|
if opts.tab_bar_edge == 3: # bottom
|
||||||
if opts.tab_bar_margin_height.outer:
|
if opts.tab_bar_margin_height.outer:
|
||||||
blank_rects.append(Border(0, tab_bar.bottom + 1, vw, vh, bg))
|
blank_rects.append(Border(0, tab_bar.bottom + 1, vw, vh, bg))
|
||||||
@ -496,7 +504,6 @@ class TabBar:
|
|||||||
g = self.window_geometry
|
g = self.window_geometry
|
||||||
if g.left > 0:
|
if g.left > 0:
|
||||||
viewport_width = max(4 * cell_width, tab_bar.width - 2 * self.margin_width)
|
viewport_width = max(4 * cell_width, tab_bar.width - 2 * self.margin_width)
|
||||||
bg = BorderColor.default_bg
|
|
||||||
blank_rects.append(Border(0, g.top, g.left, g.bottom + 1, bg))
|
blank_rects.append(Border(0, g.top, g.left, g.bottom + 1, bg))
|
||||||
blank_rects.append(Border(g.right - 1, g.top, viewport_width, g.bottom + 1, bg))
|
blank_rects.append(Border(g.right - 1, g.top, viewport_width, g.bottom + 1, bg))
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user