Merge branch 'pane-title-bar' of https://github.com/mcrmck/kitty
This commit is contained in:
commit
b66703ec85
14 changed files with 881 additions and 299 deletions
|
|
@ -787,7 +787,6 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int *
|
|||
set_maximum_wait(OPT(cursor_trail) - now + WD.screen->cursor->position_changed_by_client_at);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (WD.screen->cursor_render_info.render_even_when_unfocused) {
|
||||
if (collect_cursor_info(&WD.screen->cursor_render_info, w, now, os_window)) needs_render = true;
|
||||
|
|
@ -812,6 +811,12 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int *
|
|||
}
|
||||
if (send_cell_data_to_gpu(WD.vao_idx, WD.screen, os_window)) needs_render = true;
|
||||
if (WD.screen->start_visual_bell_at != 0) needs_render = true;
|
||||
// Prepare window title bar screen data for GPU
|
||||
WindowRenderData *trd = &w->window_title_render_data;
|
||||
if (trd->screen) {
|
||||
trd->screen->cursor_render_info.is_visible = false;
|
||||
if (send_cell_data_to_gpu(trd->vao_idx, trd->screen, os_window)) needs_render = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return needs_render || was_previously_rendered_with_layers != os_window->needs_layers;
|
||||
|
|
@ -872,6 +877,9 @@ render_prepared_os_window(OSWindow *os_window, unsigned int active_window_id, co
|
|||
if (is_active_window) active_window = w;
|
||||
draw_cells(&WD, os_window, is_active_window, false, num_of_visible_windows == 1, w);
|
||||
if (WD.screen->start_visual_bell_at != 0) set_maximum_wait(ANIMATION_SAMPLE_WAIT);
|
||||
WindowRenderData *trd = &w->window_title_render_data;
|
||||
if (trd->screen && num_visible_windows > 1 && trd->geometry.right > trd->geometry.left && trd->geometry.bottom > trd->geometry.top)
|
||||
draw_cells(trd, os_window, i == tab->active_window, true, false, NULL);
|
||||
}
|
||||
}
|
||||
setup_os_window_for_rendering(os_window, tab, active_window, false);
|
||||
|
|
|
|||
|
|
@ -1404,6 +1404,13 @@ def set_tab_bar_render_data(
|
|||
pass
|
||||
|
||||
|
||||
def set_window_title_bar_render_data(
|
||||
os_window_id: int, tab_id: int, window_id: int, screen: Screen,
|
||||
left: int, top: int, right: int, bottom: int
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def set_window_render_data(
|
||||
os_window_id: int, tab_id: int, window_id: int, screen: Screen,
|
||||
left: int, top: int, right: int, bottom: int,
|
||||
|
|
|
|||
|
|
@ -368,6 +368,14 @@ def __call__(self, all_windows: WindowList) -> None:
|
|||
self._set_dimensions(all_windows)
|
||||
self.update_visibility(all_windows)
|
||||
self.blank_rects = []
|
||||
# Set show_title_bar flag on each visible window before layout
|
||||
opts = get_options()
|
||||
min_windows = opts.window_title_bar_min_windows
|
||||
visible_groups = list(all_windows.iter_all_layoutable_groups(only_visible=True))
|
||||
num_visible = len(visible_groups)
|
||||
for wg in visible_groups:
|
||||
for w in wg.windows:
|
||||
w.show_title_bar = min_windows > 0 and num_visible >= min_windows
|
||||
self.do_layout(all_windows)
|
||||
|
||||
def layout_single_window_group(self, wg: WindowGroup, add_blank_rects: bool = True) -> None:
|
||||
|
|
|
|||
|
|
@ -1466,6 +1466,81 @@
|
|||
actually resize the window itself, but instead, the layout row/column/slot, which can result
|
||||
in multiple windows getting resized.
|
||||
''')
|
||||
|
||||
opt('window_title_bar', 'top',
|
||||
choices=('top', 'bottom'),
|
||||
long_text='''
|
||||
Control the position of the window title bar relative to the window content.
|
||||
Use :opt:`window_title_bar_min_windows` to control when title bars are shown.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('window_title_bar_min_windows', '0',
|
||||
option_type='positive_int',
|
||||
long_text='''
|
||||
The minimum number of visible windows in a tab before window title bars
|
||||
are shown. A value of :code:`0` means never show. :code:`1` means always
|
||||
show. :code:`2` or more means show only when at least that many windows
|
||||
are visible. Similar to :opt:`tab_bar_min_tabs` for the tab bar.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('window_title_template', '"{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.window}{progress_percent}{title}"',
|
||||
option_type='tab_title_template',
|
||||
long_text='''
|
||||
A template to render the window title bar text. Uses the same template syntax as
|
||||
:opt:`tab_title_template`. Available variables include: :code:`{title}`,
|
||||
:code:`{bell_symbol}`, :code:`{activity_symbol}`, :code:`{progress_percent}`,
|
||||
:code:`{custom}`, :code:`{fmt}`, :code:`{is_active}`.
|
||||
You can also provide a custom :code:`draw_window_title(data)` function in
|
||||
:file:`window_title_bar.py` in the kitty config directory, exposed as :code:`{custom}`.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('active_window_title_template', 'none',
|
||||
option_type='tab_title_template',
|
||||
long_text='''
|
||||
Template to use for the active window title bar. If not set (the value
|
||||
:code:`none`), the :opt:`window_title_template` is used.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('window_title_bar_active_foreground', 'none',
|
||||
option_type='to_color_or_none', ctype='color_or_none_as_int',
|
||||
long_text='''
|
||||
Foreground color for the active window title bar. Defaults to
|
||||
the corresponding tab bar color (:code:`active_tab_foreground`) when set to :code:`none`.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('window_title_bar_active_background', 'none',
|
||||
option_type='to_color_or_none', ctype='color_or_none_as_int',
|
||||
long_text='''
|
||||
Background color for the active window title bar. Defaults to
|
||||
the corresponding tab bar color (:code:`active_tab_background`) when set to :code:`none`.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('window_title_bar_inactive_foreground', 'none',
|
||||
option_type='to_color_or_none', ctype='color_or_none_as_int',
|
||||
long_text='''
|
||||
Foreground color for inactive window title bars. Defaults to
|
||||
the corresponding tab bar color (:code:`inactive_tab_foreground`) when set to :code:`none`.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('window_title_bar_inactive_background', 'none',
|
||||
option_type='to_color_or_none', ctype='color_or_none_as_int',
|
||||
long_text='''
|
||||
Background color for inactive window title bars. Defaults to
|
||||
the corresponding tab bar color (:code:`inactive_tab_background`) when set to :code:`none`.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('window_title_bar_align', 'center',
|
||||
choices=('left', 'center', 'right'),
|
||||
long_text='Horizontal alignment of the text in window title bars.'
|
||||
)
|
||||
egr() # }}}
|
||||
|
||||
|
||||
|
|
|
|||
37
kitty/options/parse.py
generated
37
kitty/options/parse.py
generated
|
|
@ -48,6 +48,9 @@ def active_tab_foreground(self, val: str, ans: dict[str, typing.Any]) -> None:
|
|||
def active_tab_title_template(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['active_tab_title_template'] = active_tab_title_template(val)
|
||||
|
||||
def active_window_title_template(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['active_window_title_template'] = tab_title_template(val)
|
||||
|
||||
def allow_cloning(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_allow_cloning:
|
||||
|
|
@ -1504,6 +1507,40 @@ def window_resize_step_cells(self, val: str, ans: dict[str, typing.Any]) -> None
|
|||
def window_resize_step_lines(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['window_resize_step_lines'] = positive_int(val)
|
||||
|
||||
def window_title_bar(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_window_title_bar:
|
||||
raise ValueError(f"The value {val} is not a valid choice for window_title_bar")
|
||||
ans["window_title_bar"] = val
|
||||
|
||||
choices_for_window_title_bar = frozenset(('top', 'bottom'))
|
||||
|
||||
def window_title_bar_min_windows(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['window_title_bar_min_windows'] = positive_int(val)
|
||||
|
||||
def window_title_bar_active_background(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['window_title_bar_active_background'] = to_color_or_none(val)
|
||||
|
||||
def window_title_bar_active_foreground(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['window_title_bar_active_foreground'] = to_color_or_none(val)
|
||||
|
||||
def window_title_bar_align(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_window_title_bar_align:
|
||||
raise ValueError(f"The value {val} is not a valid choice for window_title_bar_align")
|
||||
ans["window_title_bar_align"] = val
|
||||
|
||||
choices_for_window_title_bar_align = choices_for_tab_bar_align
|
||||
|
||||
def window_title_bar_inactive_background(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['window_title_bar_inactive_background'] = to_color_or_none(val)
|
||||
|
||||
def window_title_bar_inactive_foreground(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['window_title_bar_inactive_foreground'] = to_color_or_none(val)
|
||||
|
||||
def window_title_template(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['window_title_template'] = tab_title_template(val)
|
||||
|
||||
def x11_hide_window_decorations(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
deprecated_hide_window_decorations_aliases('x11_hide_window_decorations', val, ans)
|
||||
|
||||
|
|
|
|||
60
kitty/options/to-c-generated.h
generated
60
kitty/options/to-c-generated.h
generated
|
|
@ -993,6 +993,58 @@ convert_from_opts_window_drag_tolerance(PyObject *py_opts, Options *opts) {
|
|||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_window_title_bar_active_foreground(PyObject *val, Options *opts) {
|
||||
opts->window_title_bar_active_foreground = color_or_none_as_int(val);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_window_title_bar_active_foreground(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "window_title_bar_active_foreground");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_window_title_bar_active_foreground(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_window_title_bar_active_background(PyObject *val, Options *opts) {
|
||||
opts->window_title_bar_active_background = color_or_none_as_int(val);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_window_title_bar_active_background(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "window_title_bar_active_background");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_window_title_bar_active_background(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_window_title_bar_inactive_foreground(PyObject *val, Options *opts) {
|
||||
opts->window_title_bar_inactive_foreground = color_or_none_as_int(val);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_window_title_bar_inactive_foreground(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "window_title_bar_inactive_foreground");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_window_title_bar_inactive_foreground(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_window_title_bar_inactive_background(PyObject *val, Options *opts) {
|
||||
opts->window_title_bar_inactive_background = color_or_none_as_int(val);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_window_title_bar_inactive_background(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "window_title_bar_inactive_background");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_window_title_bar_inactive_background(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_tab_bar_edge(PyObject *val, Options *opts) {
|
||||
opts->tab_bar_edge = PyLong_AsLong(val);
|
||||
|
|
@ -1550,6 +1602,14 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
|
|||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_window_drag_tolerance(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_window_title_bar_active_foreground(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_window_title_bar_active_background(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_window_title_bar_inactive_foreground(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_window_title_bar_inactive_background(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_tab_bar_edge(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_tab_bar_margin_height(py_opts, opts);
|
||||
|
|
|
|||
24
kitty/options/types.py
generated
24
kitty/options/types.py
generated
|
|
@ -37,6 +37,8 @@
|
|||
choices_for_undercurl_style = typing.Literal['thin-sparse', 'thin-dense', 'thick-sparse', 'thick-dense']
|
||||
choices_for_underline_hyperlinks = typing.Literal['hover', 'always', 'never']
|
||||
choices_for_window_logo_position = choices_for_placement_strategy
|
||||
choices_for_window_title_bar = typing.Literal['top', 'bottom']
|
||||
choices_for_window_title_bar_align = choices_for_tab_bar_align
|
||||
|
||||
option_names = (
|
||||
'action_alias',
|
||||
|
|
@ -45,6 +47,7 @@
|
|||
'active_tab_font_style',
|
||||
'active_tab_foreground',
|
||||
'active_tab_title_template',
|
||||
'active_window_title_template',
|
||||
'allow_cloning',
|
||||
'allow_hyperlinks',
|
||||
'allow_remote_control',
|
||||
|
|
@ -497,6 +500,14 @@
|
|||
'window_padding_width',
|
||||
'window_resize_step_cells',
|
||||
'window_resize_step_lines',
|
||||
'window_title_bar',
|
||||
'window_title_bar_min_windows',
|
||||
'window_title_bar_active_background',
|
||||
'window_title_bar_active_foreground',
|
||||
'window_title_bar_align',
|
||||
'window_title_bar_inactive_background',
|
||||
'window_title_bar_inactive_foreground',
|
||||
'window_title_template',
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -506,6 +517,7 @@ class Options:
|
|||
active_tab_font_style: tuple[bool, bool] = (True, True)
|
||||
active_tab_foreground: Color = Color(0, 0, 0)
|
||||
active_tab_title_template: str | None = None
|
||||
active_window_title_template: str = 'none'
|
||||
allow_cloning: choices_for_allow_cloning = 'ask'
|
||||
allow_hyperlinks: int = 1
|
||||
allow_remote_control: choices_for_allow_remote_control = 'no'
|
||||
|
|
@ -689,6 +701,14 @@ class Options:
|
|||
window_padding_width: FloatEdges = FloatEdges(left=0, top=0, right=0, bottom=0)
|
||||
window_resize_step_cells: int = 2
|
||||
window_resize_step_lines: int = 2
|
||||
window_title_bar: choices_for_window_title_bar = 'top'
|
||||
window_title_bar_min_windows: int = 0
|
||||
window_title_bar_active_background: kitty.fast_data_types.Color | None = None
|
||||
window_title_bar_active_foreground: kitty.fast_data_types.Color | None = None
|
||||
window_title_bar_align: choices_for_window_title_bar_align = 'center'
|
||||
window_title_bar_inactive_background: kitty.fast_data_types.Color | None = None
|
||||
window_title_bar_inactive_foreground: kitty.fast_data_types.Color | None = None
|
||||
window_title_template: str = '{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.window}{progress_percent}{title}'
|
||||
action_alias: dict[str, str] = {}
|
||||
env: dict[str, str] = {}
|
||||
exe_search_path: dict[str, str] = {}
|
||||
|
|
@ -1111,6 +1131,10 @@ def __setattr__(self, key: str, val: typing.Any) -> typing.Any:
|
|||
'cursor_trail_color',
|
||||
'visual_bell_color',
|
||||
'active_border_color',
|
||||
'window_title_bar_active_foreground',
|
||||
'window_title_bar_active_background',
|
||||
'window_title_bar_inactive_foreground',
|
||||
'window_title_bar_inactive_background',
|
||||
'tab_bar_background',
|
||||
'tab_bar_margin_color',
|
||||
'selection_foreground',
|
||||
|
|
|
|||
|
|
@ -255,12 +255,16 @@ add_tab(id_type os_window_id) {
|
|||
static void
|
||||
create_gpu_resources_for_window(Window *w) {
|
||||
w->render_data.vao_idx = create_cell_vao();
|
||||
w->window_title_render_data.vao_idx = create_cell_vao();
|
||||
}
|
||||
|
||||
static void
|
||||
release_gpu_resources_for_window(Window *w) {
|
||||
if (w->render_data.vao_idx > -1) remove_vao(w->render_data.vao_idx);
|
||||
w->render_data.vao_idx = -1;
|
||||
if (w->window_title_render_data.vao_idx > -1) remove_vao(w->window_title_render_data.vao_idx);
|
||||
w->window_title_render_data.vao_idx = -1;
|
||||
Py_CLEAR(w->window_title_render_data.screen);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -860,6 +864,17 @@ PYWRAP1(set_tab_bar_render_data) {
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PYWRAP1(set_window_title_bar_render_data) {
|
||||
WindowGeometry g;
|
||||
id_type os_window_id, tab_id, window_id;
|
||||
Screen *screen;
|
||||
PA("KKKOIIII", &os_window_id, &tab_id, &window_id, &screen, &g.left, &g.top, &g.right, &g.bottom);
|
||||
WITH_WINDOW(os_window_id, tab_id, window_id)
|
||||
init_window_render_data(&window->window_title_render_data, g, screen);
|
||||
END_WITH_WINDOW
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyTypeObject RegionType;
|
||||
static PyStructSequence_Field region_fields[] = {
|
||||
{"left", ""}, {"top", ""}, {"right", ""}, {"bottom", ""}, {"width", ""}, {"height", ""}, {NULL, NULL}
|
||||
|
|
@ -1597,6 +1612,7 @@ static PyMethodDef module_methods[] = {
|
|||
MW(reorder_tabs, METH_VARARGS),
|
||||
MW(set_borders_rects, METH_VARARGS),
|
||||
MW(set_tab_bar_render_data, METH_VARARGS),
|
||||
MW(set_window_title_bar_render_data, METH_VARARGS),
|
||||
MW(set_window_render_data, METH_VARARGS),
|
||||
MW(set_window_padding, METH_VARARGS),
|
||||
MW(viewport_for_window, METH_VARARGS),
|
||||
|
|
|
|||
|
|
@ -62,7 +62,8 @@ typedef struct Options {
|
|||
bool scrollback_fill_enlarged_window;
|
||||
char_type *select_by_word_characters;
|
||||
char_type *select_by_word_characters_forward;
|
||||
color_type url_color, background, foreground, active_border_color, inactive_border_color, bell_border_color, tab_bar_background, tab_bar_margin_color;
|
||||
color_type url_color, background, foreground, active_border_color, inactive_border_color, bell_border_color, tab_bar_background, tab_bar_margin_color,
|
||||
window_title_bar_active_foreground, window_title_bar_active_background, window_title_bar_inactive_foreground, window_title_bar_inactive_background;
|
||||
monotonic_t repaint_delay, input_delay;
|
||||
bool focus_follows_mouse;
|
||||
unsigned int hide_window_decorations;
|
||||
|
|
@ -208,6 +209,7 @@ typedef struct Window {
|
|||
bool visible;
|
||||
PyObject *title;
|
||||
WindowRenderData render_data;
|
||||
WindowRenderData window_title_render_data;
|
||||
WindowLogoRenderData window_logo;
|
||||
MousePosition mouse_pos;
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
from .utils import cmdline_for_hold, color_as_int, log_error, platform_window_id, resolved_shell, shlex_split, which
|
||||
from .window import CwdRequest, Watchers, Window, WindowCreationSpec, WindowDict, global_watchers
|
||||
from .window_list import WindowList
|
||||
from .window_title_bar import WindowTitleBarManager
|
||||
|
||||
P = ParamSpec('P')
|
||||
T = TypeVar('T')
|
||||
|
|
@ -170,6 +171,7 @@ def __init__(
|
|||
self.name = getattr(session_tab, 'name', '')
|
||||
self.enabled_layouts = [x.lower() for x in getattr(session_tab, 'enabled_layouts', None) or get_options().enabled_layouts]
|
||||
self.borders = Borders(self.os_window_id, self.id)
|
||||
self.window_title_bar_manager = WindowTitleBarManager(self.os_window_id, self.id)
|
||||
self.windows: WindowList = WindowList(self)
|
||||
self._last_used_layout: str | None = None
|
||||
self._current_layout_name: str | None = None
|
||||
|
|
@ -440,6 +442,7 @@ def set_title(self, title: str) -> None:
|
|||
self.mark_tab_bar_dirty()
|
||||
|
||||
def title_changed(self, window: Window) -> None:
|
||||
self.window_title_bar_manager.update(self.windows)
|
||||
if window is self.active_window:
|
||||
tm = self.tab_manager_ref()
|
||||
if tm is not None:
|
||||
|
|
@ -468,6 +471,7 @@ def relayout_borders(self) -> None:
|
|||
current_layout=ly, tab_bar_rects=tm.tab_bar_rects,
|
||||
draw_window_borders=draw_borders
|
||||
)
|
||||
self.window_title_bar_manager.update(self.windows)
|
||||
|
||||
def create_layout_object(self, name: str) -> Layout:
|
||||
return create_layout_object_for(name, self.os_window_id, self.id)
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@
|
|||
set_window_logo,
|
||||
set_window_padding,
|
||||
set_window_render_data,
|
||||
set_window_title_bar_render_data,
|
||||
update_ime_position_for_window,
|
||||
update_pointer_shape,
|
||||
update_window_title,
|
||||
|
|
@ -732,6 +733,8 @@ def __init__(
|
|||
self.tabref: Callable[[], TabType | None] = weakref.ref(tab)
|
||||
self.destroyed = False
|
||||
self.geometry: WindowGeometry = WindowGeometry(0, 0, 0, 0, 0, 0)
|
||||
self.show_title_bar: bool = False
|
||||
self._title_bar_screen: Any = None
|
||||
self.needs_layout = True
|
||||
self.is_visible_in_layout: bool = True
|
||||
self.child = child
|
||||
|
|
@ -977,13 +980,36 @@ def resize_child(self, current_pty_size: tuple[int, int, int, int]) -> bool:
|
|||
def set_geometry(self, new_geometry: WindowGeometry) -> None:
|
||||
if self.destroyed:
|
||||
return
|
||||
if self.needs_layout or new_geometry.xnum != self.screen.columns or new_geometry.ynum != self.screen.lines:
|
||||
self.screen.resize(max(0, new_geometry.ynum), max(0, new_geometry.xnum))
|
||||
# Determine if we need a title bar and compute adjusted dimensions
|
||||
opts = get_options()
|
||||
position = opts.window_title_bar
|
||||
show_tb = self.show_title_bar and new_geometry.ynum > 1
|
||||
|
||||
if show_tb:
|
||||
render_ynum = new_geometry.ynum - 1
|
||||
cell_width, cell_height = cell_size_for_window(self.os_window_id)
|
||||
if position == 'top':
|
||||
render_top = new_geometry.top + cell_height
|
||||
render_bottom = new_geometry.bottom
|
||||
tb_top = new_geometry.top
|
||||
tb_bottom = new_geometry.top + cell_height
|
||||
else:
|
||||
render_top = new_geometry.top
|
||||
render_bottom = new_geometry.bottom - cell_height
|
||||
tb_top = new_geometry.bottom - cell_height
|
||||
tb_bottom = new_geometry.bottom
|
||||
else:
|
||||
render_ynum = new_geometry.ynum
|
||||
render_top = new_geometry.top
|
||||
render_bottom = new_geometry.bottom
|
||||
|
||||
if self.needs_layout or new_geometry.xnum != self.screen.columns or render_ynum != self.screen.lines:
|
||||
self.screen.resize(max(0, render_ynum), max(0, new_geometry.xnum))
|
||||
self.needs_layout = False
|
||||
call_watchers(weakref.ref(self), 'on_resize', {'old_geometry': self.geometry, 'new_geometry': new_geometry})
|
||||
current_pty_size = (
|
||||
self.screen.lines, self.screen.columns,
|
||||
max(0, new_geometry.right - new_geometry.left), max(0, new_geometry.bottom - new_geometry.top))
|
||||
max(0, new_geometry.right - new_geometry.left), max(0, render_bottom - render_top))
|
||||
update_ime_position = False
|
||||
if current_pty_size != self.last_reported_pty_size:
|
||||
if self._pause_resize_notifications_to_child is None:
|
||||
|
|
@ -993,14 +1019,78 @@ def set_geometry(self, new_geometry: WindowGeometry) -> None:
|
|||
else:
|
||||
mark_os_window_dirty(self.os_window_id)
|
||||
|
||||
# Store original geometry for borders/padding calculations
|
||||
self.geometry = g = new_geometry
|
||||
# Set C-side render data with adjusted top/bottom for content area
|
||||
set_window_render_data(self.os_window_id, self.tab_id, self.id, self.screen,
|
||||
g.left, g.top, g.right, g.bottom,
|
||||
g.left, render_top, g.right, render_bottom,
|
||||
g.spaces.left, g.spaces.top, g.spaces.right, g.spaces.bottom)
|
||||
self.update_effective_padding()
|
||||
|
||||
# Handle title bar screen
|
||||
if show_tb:
|
||||
from .window_title_bar import WindowTitleBarScreen
|
||||
if self._title_bar_screen is None:
|
||||
self._title_bar_screen = WindowTitleBarScreen(self.os_window_id, cell_width, cell_height)
|
||||
tb_geom = WindowGeometry(
|
||||
left=g.left, top=tb_top, right=g.right, bottom=tb_bottom,
|
||||
xnum=0, ynum=1,
|
||||
)
|
||||
self._title_bar_screen.layout(tb_geom)
|
||||
set_window_title_bar_render_data(
|
||||
self.os_window_id, self.tab_id, self.id, self._title_bar_screen.screen,
|
||||
tb_geom.left, tb_geom.top, tb_geom.right, tb_geom.bottom,
|
||||
)
|
||||
elif self._title_bar_screen is not None:
|
||||
# Clear title bar render data
|
||||
set_window_title_bar_render_data(
|
||||
self.os_window_id, self.tab_id, self.id, self._title_bar_screen.screen,
|
||||
0, 0, 0, 0,
|
||||
)
|
||||
self._title_bar_screen = None
|
||||
|
||||
if update_ime_position:
|
||||
update_ime_position_for_window(self.id, True)
|
||||
|
||||
def update_title_bar(self, is_active: bool = False) -> None:
|
||||
pts = self._title_bar_screen
|
||||
if pts is None:
|
||||
return
|
||||
from .progress import ProgressState
|
||||
from .window_title_bar import WindowTitleData
|
||||
|
||||
progress_percent = ''
|
||||
if self.progress.state is not ProgressState.unset:
|
||||
if self.progress.state is ProgressState.indeterminate:
|
||||
progress_percent = '[…] '
|
||||
elif self.progress.percent > 0:
|
||||
progress_percent = f'[{self.progress.percent}%] '
|
||||
|
||||
has_activity = self.has_activity_since_last_focus
|
||||
|
||||
data = WindowTitleData(
|
||||
title=self.title or '',
|
||||
is_active=is_active,
|
||||
window_id=self.id,
|
||||
tab_id=self.tab_id,
|
||||
needs_attention=self.needs_attention,
|
||||
has_activity_since_last_focus=has_activity,
|
||||
)
|
||||
rendered_title = pts.render(data, progress_percent)
|
||||
|
||||
# If template evaluates to empty string, zero title bar geometry to hide it
|
||||
if not rendered_title:
|
||||
set_window_title_bar_render_data(
|
||||
self.os_window_id, self.tab_id, self.id, pts.screen,
|
||||
0, 0, 0, 0,
|
||||
)
|
||||
else:
|
||||
g = pts.geometry
|
||||
set_window_title_bar_render_data(
|
||||
self.os_window_id, self.tab_id, self.id, pts.screen,
|
||||
g.left, g.top, g.right, g.bottom,
|
||||
)
|
||||
|
||||
def close(self) -> None:
|
||||
get_boss().mark_window_for_close(self)
|
||||
|
||||
|
|
|
|||
243
kitty/window_title_bar.py
Normal file
243
kitty/window_title_bar.py
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
#!/usr/bin/env python
|
||||
# License: GPL v3 Copyright: 2024, kitty contributors
|
||||
|
||||
import os
|
||||
from functools import lru_cache
|
||||
from typing import Any, NamedTuple
|
||||
|
||||
from .constants import config_dir
|
||||
from .fast_data_types import (
|
||||
DECAWM,
|
||||
Screen,
|
||||
get_options,
|
||||
)
|
||||
from .rgb import color_as_sgr, color_from_int, to_color
|
||||
from .types import WindowGeometry, run_once
|
||||
from .utils import color_as_int, log_error, sgr_sanitizer_pat
|
||||
from .window_list import WindowList
|
||||
|
||||
|
||||
@lru_cache
|
||||
def _report_template_failure(template: str, e: str) -> None:
|
||||
log_error(f'Invalid window title template: "{template}" with error: {e}')
|
||||
|
||||
|
||||
@lru_cache
|
||||
def _compile_template(template: str) -> Any:
|
||||
try:
|
||||
return compile('f"""' + template + '"""', '<window_title_template>', 'eval')
|
||||
except Exception as e:
|
||||
_report_template_failure(template, str(e))
|
||||
|
||||
|
||||
safe_builtins = {
|
||||
'max': max, 'min': min, 'str': str, 'repr': repr, 'abs': abs,
|
||||
'len': len, 'chr': chr, 'ord': ord,
|
||||
}
|
||||
|
||||
|
||||
def _resolve_color(opt_val: Any, fallback_val: Any) -> Any:
|
||||
if opt_val is None:
|
||||
return fallback_val
|
||||
return opt_val
|
||||
|
||||
|
||||
class WindowTitleColorFormatter:
|
||||
is_active: bool = False
|
||||
|
||||
def __init__(self, which: str):
|
||||
self.which = which
|
||||
|
||||
def __getattr__(self, name: str) -> str:
|
||||
q = name
|
||||
if q == 'default':
|
||||
ans = '9'
|
||||
elif q == 'window':
|
||||
opts = get_options()
|
||||
if self.is_active:
|
||||
fg_color = _resolve_color(opts.window_title_bar_active_foreground, opts.active_tab_foreground)
|
||||
bg_color = _resolve_color(opts.window_title_bar_active_background, opts.active_tab_background)
|
||||
col = color_from_int(color_as_int(fg_color if self.which == '3' else bg_color))
|
||||
else:
|
||||
fg_color = _resolve_color(opts.window_title_bar_inactive_foreground, opts.inactive_tab_foreground)
|
||||
bg_color = _resolve_color(opts.window_title_bar_inactive_background, opts.inactive_tab_background)
|
||||
col = color_from_int(color_as_int(fg_color if self.which == '3' else bg_color))
|
||||
ans = f'8{color_as_sgr(col)}'
|
||||
elif q.startswith('color'):
|
||||
ans = f'8:5:{int(q[5:])}'
|
||||
else:
|
||||
if name.startswith('_'):
|
||||
q = f'#{name[1:]}'
|
||||
c = to_color(q)
|
||||
if c is None:
|
||||
raise AttributeError(f'{name} is not a valid color')
|
||||
ans = f'8{color_as_sgr(c)}'
|
||||
return f'\x1b[{self.which}{ans}m'
|
||||
|
||||
|
||||
class WindowTitleFormatter:
|
||||
reset = '\x1b[0m'
|
||||
fg = WindowTitleColorFormatter('3')
|
||||
bg = WindowTitleColorFormatter('4')
|
||||
bold = '\x1b[1m'
|
||||
nobold = '\x1b[22m'
|
||||
italic = '\x1b[3m'
|
||||
noitalic = '\x1b[23m'
|
||||
|
||||
|
||||
def _draw_attributed_string(title: str, screen: Screen) -> None:
|
||||
if '\x1b' in title:
|
||||
for x in sgr_sanitizer_pat(for_splitting=True).split(title):
|
||||
if x.startswith('\x1b') and x.endswith('m'):
|
||||
screen.apply_sgr(x[2:-1])
|
||||
else:
|
||||
screen.draw(x)
|
||||
else:
|
||||
screen.draw(title)
|
||||
|
||||
|
||||
class WindowTitleData(NamedTuple):
|
||||
title: str
|
||||
is_active: bool
|
||||
window_id: int
|
||||
tab_id: int
|
||||
needs_attention: bool = False
|
||||
has_activity_since_last_focus: bool = False
|
||||
|
||||
|
||||
@run_once
|
||||
def load_custom_window_title_bar_module() -> dict[str, Any]:
|
||||
import runpy
|
||||
import traceback
|
||||
try:
|
||||
return runpy.run_path(os.path.join(config_dir, 'window_title_bar.py'))
|
||||
except FileNotFoundError:
|
||||
return {}
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
log_error(f'Failed to load custom window_title_bar.py module with error: {e}')
|
||||
return {}
|
||||
|
||||
|
||||
def _get_custom_draw_result(data: WindowTitleData) -> str | None:
|
||||
m = load_custom_window_title_bar_module()
|
||||
func = m.get('draw_window_title')
|
||||
if func is None:
|
||||
return None
|
||||
try:
|
||||
return str(func(data))
|
||||
except Exception as e:
|
||||
log_error(f'Custom draw_window_title function failed with error: {e}')
|
||||
return None
|
||||
|
||||
|
||||
def clear_caches() -> None:
|
||||
load_custom_window_title_bar_module.clear_cached()
|
||||
|
||||
|
||||
class WindowTitleBarScreen:
|
||||
def __init__(self, os_window_id: int, cell_width: int, cell_height: int):
|
||||
self.os_window_id = os_window_id
|
||||
self.cell_width = cell_width
|
||||
self.screen = Screen(None, 1, 10, 0, cell_width, cell_height)
|
||||
self.screen.reset_mode(DECAWM)
|
||||
|
||||
def layout(self, geometry: WindowGeometry) -> None:
|
||||
ncells = max(4, (geometry.right - geometry.left) // self.cell_width)
|
||||
self.screen.resize(1, ncells)
|
||||
self.geometry = geometry
|
||||
|
||||
def render(self, data: WindowTitleData, progress_percent: str) -> str:
|
||||
opts = get_options()
|
||||
s = self.screen
|
||||
s.cursor.x = 0
|
||||
s.erase_in_line(2, False)
|
||||
|
||||
is_active = data.is_active
|
||||
if is_active:
|
||||
fg_color = _resolve_color(opts.window_title_bar_active_foreground, opts.active_tab_foreground)
|
||||
bg_color = _resolve_color(opts.window_title_bar_active_background, opts.active_tab_background)
|
||||
else:
|
||||
fg_color = _resolve_color(opts.window_title_bar_inactive_foreground, opts.inactive_tab_foreground)
|
||||
bg_color = _resolve_color(opts.window_title_bar_inactive_background, opts.inactive_tab_background)
|
||||
|
||||
s.color_profile.default_fg = fg_color
|
||||
s.color_profile.default_bg = bg_color
|
||||
fg = (color_as_int(fg_color) << 8) | 2
|
||||
bg = (color_as_int(bg_color) << 8) | 2
|
||||
|
||||
s.cursor.fg = fg
|
||||
s.cursor.bg = bg
|
||||
|
||||
template = opts.window_title_template
|
||||
if is_active and opts.active_window_title_template and opts.active_window_title_template != 'none':
|
||||
template = opts.active_window_title_template
|
||||
|
||||
WindowTitleColorFormatter.is_active = is_active
|
||||
|
||||
bell_symbol = opts.bell_on_tab if data.needs_attention else ''
|
||||
activity_symbol = opts.tab_activity_symbol if data.has_activity_since_last_focus else ''
|
||||
|
||||
custom_result = _get_custom_draw_result(data)
|
||||
|
||||
eval_locals = {
|
||||
'title': data.title,
|
||||
'is_active': is_active,
|
||||
'fmt': WindowTitleFormatter,
|
||||
'bell_symbol': bell_symbol,
|
||||
'activity_symbol': activity_symbol,
|
||||
'progress_percent': progress_percent,
|
||||
'custom': custom_result or '',
|
||||
}
|
||||
try:
|
||||
title = eval(_compile_template(template), {'__builtins__': safe_builtins}, eval_locals)
|
||||
except Exception as e:
|
||||
_report_template_failure(template, str(e))
|
||||
title = data.title
|
||||
|
||||
title_str = str(title)
|
||||
align = opts.window_title_bar_align
|
||||
|
||||
if align == 'left':
|
||||
_draw_attributed_string(title_str, s)
|
||||
else:
|
||||
# Measure the title length by drawing to cursor position 0
|
||||
# and checking where the cursor ends up
|
||||
_draw_attributed_string(title_str, s)
|
||||
title_len = s.cursor.x
|
||||
s.cursor.x = 0
|
||||
s.erase_in_line(2, False)
|
||||
s.cursor.fg = fg
|
||||
s.cursor.bg = bg
|
||||
|
||||
if align == 'center':
|
||||
pad = max(0, (s.columns - title_len) // 2)
|
||||
else: # right
|
||||
pad = max(0, s.columns - title_len)
|
||||
|
||||
for _ in range(pad):
|
||||
s.draw(' ')
|
||||
_draw_attributed_string(title_str, s)
|
||||
|
||||
# Fill remaining cells with background
|
||||
while s.cursor.x < s.columns:
|
||||
s.draw(' ')
|
||||
|
||||
return title_str
|
||||
|
||||
|
||||
class WindowTitleBarManager:
|
||||
|
||||
def __init__(self, os_window_id: int, tab_id: int):
|
||||
self.os_window_id = os_window_id
|
||||
self.tab_id = tab_id
|
||||
|
||||
def update(self, all_windows: WindowList) -> None:
|
||||
active_group = all_windows.active_group
|
||||
for wg in all_windows.iter_all_layoutable_groups(only_visible=True):
|
||||
is_active = wg is active_group
|
||||
for w in wg.windows:
|
||||
w.update_title_bar(is_active=is_active)
|
||||
|
||||
def destroy(self) -> None:
|
||||
pass
|
||||
|
|
@ -15,15 +15,19 @@ import (
|
|||
var nullable_colors = map[string]bool{
|
||||
// generated by gen-config.py do not edit
|
||||
// NULLABLE_COLORS_START
|
||||
"active_border_color": true,
|
||||
"cursor": true,
|
||||
"cursor_text_color": true,
|
||||
"cursor_trail_color": true,
|
||||
"selection_background": true,
|
||||
"selection_foreground": true,
|
||||
"tab_bar_background": true,
|
||||
"tab_bar_margin_color": true,
|
||||
"visual_bell_color": true,
|
||||
"active_border_color": true,
|
||||
"cursor": true,
|
||||
"cursor_text_color": true,
|
||||
"cursor_trail_color": true,
|
||||
"selection_background": true,
|
||||
"selection_foreground": true,
|
||||
"tab_bar_background": true,
|
||||
"tab_bar_margin_color": true,
|
||||
"visual_bell_color": true,
|
||||
"window_title_bar_active_background": true,
|
||||
"window_title_bar_active_foreground": true,
|
||||
"window_title_bar_inactive_background": true,
|
||||
"window_title_bar_inactive_foreground": true,
|
||||
// NULLABLE_COLORS_END
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,290 +35,294 @@ var _ = fmt.Print
|
|||
var AllColorSettingNames = map[string]bool{ // {{{
|
||||
// generated by gen-config.py do not edit
|
||||
// ALL_COLORS_START
|
||||
"active_border_color": true,
|
||||
"active_tab_background": true,
|
||||
"active_tab_foreground": true,
|
||||
"background": true,
|
||||
"bell_border_color": true,
|
||||
"color0": true,
|
||||
"color1": true,
|
||||
"color10": true,
|
||||
"color100": true,
|
||||
"color101": true,
|
||||
"color102": true,
|
||||
"color103": true,
|
||||
"color104": true,
|
||||
"color105": true,
|
||||
"color106": true,
|
||||
"color107": true,
|
||||
"color108": true,
|
||||
"color109": true,
|
||||
"color11": true,
|
||||
"color110": true,
|
||||
"color111": true,
|
||||
"color112": true,
|
||||
"color113": true,
|
||||
"color114": true,
|
||||
"color115": true,
|
||||
"color116": true,
|
||||
"color117": true,
|
||||
"color118": true,
|
||||
"color119": true,
|
||||
"color12": true,
|
||||
"color120": true,
|
||||
"color121": true,
|
||||
"color122": true,
|
||||
"color123": true,
|
||||
"color124": true,
|
||||
"color125": true,
|
||||
"color126": true,
|
||||
"color127": true,
|
||||
"color128": true,
|
||||
"color129": true,
|
||||
"color13": true,
|
||||
"color130": true,
|
||||
"color131": true,
|
||||
"color132": true,
|
||||
"color133": true,
|
||||
"color134": true,
|
||||
"color135": true,
|
||||
"color136": true,
|
||||
"color137": true,
|
||||
"color138": true,
|
||||
"color139": true,
|
||||
"color14": true,
|
||||
"color140": true,
|
||||
"color141": true,
|
||||
"color142": true,
|
||||
"color143": true,
|
||||
"color144": true,
|
||||
"color145": true,
|
||||
"color146": true,
|
||||
"color147": true,
|
||||
"color148": true,
|
||||
"color149": true,
|
||||
"color15": true,
|
||||
"color150": true,
|
||||
"color151": true,
|
||||
"color152": true,
|
||||
"color153": true,
|
||||
"color154": true,
|
||||
"color155": true,
|
||||
"color156": true,
|
||||
"color157": true,
|
||||
"color158": true,
|
||||
"color159": true,
|
||||
"color16": true,
|
||||
"color160": true,
|
||||
"color161": true,
|
||||
"color162": true,
|
||||
"color163": true,
|
||||
"color164": true,
|
||||
"color165": true,
|
||||
"color166": true,
|
||||
"color167": true,
|
||||
"color168": true,
|
||||
"color169": true,
|
||||
"color17": true,
|
||||
"color170": true,
|
||||
"color171": true,
|
||||
"color172": true,
|
||||
"color173": true,
|
||||
"color174": true,
|
||||
"color175": true,
|
||||
"color176": true,
|
||||
"color177": true,
|
||||
"color178": true,
|
||||
"color179": true,
|
||||
"color18": true,
|
||||
"color180": true,
|
||||
"color181": true,
|
||||
"color182": true,
|
||||
"color183": true,
|
||||
"color184": true,
|
||||
"color185": true,
|
||||
"color186": true,
|
||||
"color187": true,
|
||||
"color188": true,
|
||||
"color189": true,
|
||||
"color19": true,
|
||||
"color190": true,
|
||||
"color191": true,
|
||||
"color192": true,
|
||||
"color193": true,
|
||||
"color194": true,
|
||||
"color195": true,
|
||||
"color196": true,
|
||||
"color197": true,
|
||||
"color198": true,
|
||||
"color199": true,
|
||||
"color2": true,
|
||||
"color20": true,
|
||||
"color200": true,
|
||||
"color201": true,
|
||||
"color202": true,
|
||||
"color203": true,
|
||||
"color204": true,
|
||||
"color205": true,
|
||||
"color206": true,
|
||||
"color207": true,
|
||||
"color208": true,
|
||||
"color209": true,
|
||||
"color21": true,
|
||||
"color210": true,
|
||||
"color211": true,
|
||||
"color212": true,
|
||||
"color213": true,
|
||||
"color214": true,
|
||||
"color215": true,
|
||||
"color216": true,
|
||||
"color217": true,
|
||||
"color218": true,
|
||||
"color219": true,
|
||||
"color22": true,
|
||||
"color220": true,
|
||||
"color221": true,
|
||||
"color222": true,
|
||||
"color223": true,
|
||||
"color224": true,
|
||||
"color225": true,
|
||||
"color226": true,
|
||||
"color227": true,
|
||||
"color228": true,
|
||||
"color229": true,
|
||||
"color23": true,
|
||||
"color230": true,
|
||||
"color231": true,
|
||||
"color232": true,
|
||||
"color233": true,
|
||||
"color234": true,
|
||||
"color235": true,
|
||||
"color236": true,
|
||||
"color237": true,
|
||||
"color238": true,
|
||||
"color239": true,
|
||||
"color24": true,
|
||||
"color240": true,
|
||||
"color241": true,
|
||||
"color242": true,
|
||||
"color243": true,
|
||||
"color244": true,
|
||||
"color245": true,
|
||||
"color246": true,
|
||||
"color247": true,
|
||||
"color248": true,
|
||||
"color249": true,
|
||||
"color25": true,
|
||||
"color250": true,
|
||||
"color251": true,
|
||||
"color252": true,
|
||||
"color253": true,
|
||||
"color254": true,
|
||||
"color255": true,
|
||||
"color26": true,
|
||||
"color27": true,
|
||||
"color28": true,
|
||||
"color29": true,
|
||||
"color3": true,
|
||||
"color30": true,
|
||||
"color31": true,
|
||||
"color32": true,
|
||||
"color33": true,
|
||||
"color34": true,
|
||||
"color35": true,
|
||||
"color36": true,
|
||||
"color37": true,
|
||||
"color38": true,
|
||||
"color39": true,
|
||||
"color4": true,
|
||||
"color40": true,
|
||||
"color41": true,
|
||||
"color42": true,
|
||||
"color43": true,
|
||||
"color44": true,
|
||||
"color45": true,
|
||||
"color46": true,
|
||||
"color47": true,
|
||||
"color48": true,
|
||||
"color49": true,
|
||||
"color5": true,
|
||||
"color50": true,
|
||||
"color51": true,
|
||||
"color52": true,
|
||||
"color53": true,
|
||||
"color54": true,
|
||||
"color55": true,
|
||||
"color56": true,
|
||||
"color57": true,
|
||||
"color58": true,
|
||||
"color59": true,
|
||||
"color6": true,
|
||||
"color60": true,
|
||||
"color61": true,
|
||||
"color62": true,
|
||||
"color63": true,
|
||||
"color64": true,
|
||||
"color65": true,
|
||||
"color66": true,
|
||||
"color67": true,
|
||||
"color68": true,
|
||||
"color69": true,
|
||||
"color7": true,
|
||||
"color70": true,
|
||||
"color71": true,
|
||||
"color72": true,
|
||||
"color73": true,
|
||||
"color74": true,
|
||||
"color75": true,
|
||||
"color76": true,
|
||||
"color77": true,
|
||||
"color78": true,
|
||||
"color79": true,
|
||||
"color8": true,
|
||||
"color80": true,
|
||||
"color81": true,
|
||||
"color82": true,
|
||||
"color83": true,
|
||||
"color84": true,
|
||||
"color85": true,
|
||||
"color86": true,
|
||||
"color87": true,
|
||||
"color88": true,
|
||||
"color89": true,
|
||||
"color9": true,
|
||||
"color90": true,
|
||||
"color91": true,
|
||||
"color92": true,
|
||||
"color93": true,
|
||||
"color94": true,
|
||||
"color95": true,
|
||||
"color96": true,
|
||||
"color97": true,
|
||||
"color98": true,
|
||||
"color99": true,
|
||||
"cursor": true,
|
||||
"cursor_text_color": true,
|
||||
"cursor_trail_color": true,
|
||||
"foreground": true,
|
||||
"inactive_border_color": true,
|
||||
"inactive_tab_background": true,
|
||||
"inactive_tab_foreground": true,
|
||||
"macos_titlebar_color": true,
|
||||
"mark1_background": true,
|
||||
"mark1_foreground": true,
|
||||
"mark2_background": true,
|
||||
"mark2_foreground": true,
|
||||
"mark3_background": true,
|
||||
"mark3_foreground": true,
|
||||
"scrollbar_handle_color": true,
|
||||
"scrollbar_track_color": true,
|
||||
"selection_background": true,
|
||||
"selection_foreground": true,
|
||||
"tab_bar_background": true,
|
||||
"tab_bar_margin_color": true,
|
||||
"url_color": true,
|
||||
"visual_bell_color": true,
|
||||
"wayland_titlebar_color": true, // ALL_COLORS_END
|
||||
"active_border_color": true,
|
||||
"active_tab_background": true,
|
||||
"active_tab_foreground": true,
|
||||
"background": true,
|
||||
"bell_border_color": true,
|
||||
"color0": true,
|
||||
"color1": true,
|
||||
"color10": true,
|
||||
"color100": true,
|
||||
"color101": true,
|
||||
"color102": true,
|
||||
"color103": true,
|
||||
"color104": true,
|
||||
"color105": true,
|
||||
"color106": true,
|
||||
"color107": true,
|
||||
"color108": true,
|
||||
"color109": true,
|
||||
"color11": true,
|
||||
"color110": true,
|
||||
"color111": true,
|
||||
"color112": true,
|
||||
"color113": true,
|
||||
"color114": true,
|
||||
"color115": true,
|
||||
"color116": true,
|
||||
"color117": true,
|
||||
"color118": true,
|
||||
"color119": true,
|
||||
"color12": true,
|
||||
"color120": true,
|
||||
"color121": true,
|
||||
"color122": true,
|
||||
"color123": true,
|
||||
"color124": true,
|
||||
"color125": true,
|
||||
"color126": true,
|
||||
"color127": true,
|
||||
"color128": true,
|
||||
"color129": true,
|
||||
"color13": true,
|
||||
"color130": true,
|
||||
"color131": true,
|
||||
"color132": true,
|
||||
"color133": true,
|
||||
"color134": true,
|
||||
"color135": true,
|
||||
"color136": true,
|
||||
"color137": true,
|
||||
"color138": true,
|
||||
"color139": true,
|
||||
"color14": true,
|
||||
"color140": true,
|
||||
"color141": true,
|
||||
"color142": true,
|
||||
"color143": true,
|
||||
"color144": true,
|
||||
"color145": true,
|
||||
"color146": true,
|
||||
"color147": true,
|
||||
"color148": true,
|
||||
"color149": true,
|
||||
"color15": true,
|
||||
"color150": true,
|
||||
"color151": true,
|
||||
"color152": true,
|
||||
"color153": true,
|
||||
"color154": true,
|
||||
"color155": true,
|
||||
"color156": true,
|
||||
"color157": true,
|
||||
"color158": true,
|
||||
"color159": true,
|
||||
"color16": true,
|
||||
"color160": true,
|
||||
"color161": true,
|
||||
"color162": true,
|
||||
"color163": true,
|
||||
"color164": true,
|
||||
"color165": true,
|
||||
"color166": true,
|
||||
"color167": true,
|
||||
"color168": true,
|
||||
"color169": true,
|
||||
"color17": true,
|
||||
"color170": true,
|
||||
"color171": true,
|
||||
"color172": true,
|
||||
"color173": true,
|
||||
"color174": true,
|
||||
"color175": true,
|
||||
"color176": true,
|
||||
"color177": true,
|
||||
"color178": true,
|
||||
"color179": true,
|
||||
"color18": true,
|
||||
"color180": true,
|
||||
"color181": true,
|
||||
"color182": true,
|
||||
"color183": true,
|
||||
"color184": true,
|
||||
"color185": true,
|
||||
"color186": true,
|
||||
"color187": true,
|
||||
"color188": true,
|
||||
"color189": true,
|
||||
"color19": true,
|
||||
"color190": true,
|
||||
"color191": true,
|
||||
"color192": true,
|
||||
"color193": true,
|
||||
"color194": true,
|
||||
"color195": true,
|
||||
"color196": true,
|
||||
"color197": true,
|
||||
"color198": true,
|
||||
"color199": true,
|
||||
"color2": true,
|
||||
"color20": true,
|
||||
"color200": true,
|
||||
"color201": true,
|
||||
"color202": true,
|
||||
"color203": true,
|
||||
"color204": true,
|
||||
"color205": true,
|
||||
"color206": true,
|
||||
"color207": true,
|
||||
"color208": true,
|
||||
"color209": true,
|
||||
"color21": true,
|
||||
"color210": true,
|
||||
"color211": true,
|
||||
"color212": true,
|
||||
"color213": true,
|
||||
"color214": true,
|
||||
"color215": true,
|
||||
"color216": true,
|
||||
"color217": true,
|
||||
"color218": true,
|
||||
"color219": true,
|
||||
"color22": true,
|
||||
"color220": true,
|
||||
"color221": true,
|
||||
"color222": true,
|
||||
"color223": true,
|
||||
"color224": true,
|
||||
"color225": true,
|
||||
"color226": true,
|
||||
"color227": true,
|
||||
"color228": true,
|
||||
"color229": true,
|
||||
"color23": true,
|
||||
"color230": true,
|
||||
"color231": true,
|
||||
"color232": true,
|
||||
"color233": true,
|
||||
"color234": true,
|
||||
"color235": true,
|
||||
"color236": true,
|
||||
"color237": true,
|
||||
"color238": true,
|
||||
"color239": true,
|
||||
"color24": true,
|
||||
"color240": true,
|
||||
"color241": true,
|
||||
"color242": true,
|
||||
"color243": true,
|
||||
"color244": true,
|
||||
"color245": true,
|
||||
"color246": true,
|
||||
"color247": true,
|
||||
"color248": true,
|
||||
"color249": true,
|
||||
"color25": true,
|
||||
"color250": true,
|
||||
"color251": true,
|
||||
"color252": true,
|
||||
"color253": true,
|
||||
"color254": true,
|
||||
"color255": true,
|
||||
"color26": true,
|
||||
"color27": true,
|
||||
"color28": true,
|
||||
"color29": true,
|
||||
"color3": true,
|
||||
"color30": true,
|
||||
"color31": true,
|
||||
"color32": true,
|
||||
"color33": true,
|
||||
"color34": true,
|
||||
"color35": true,
|
||||
"color36": true,
|
||||
"color37": true,
|
||||
"color38": true,
|
||||
"color39": true,
|
||||
"color4": true,
|
||||
"color40": true,
|
||||
"color41": true,
|
||||
"color42": true,
|
||||
"color43": true,
|
||||
"color44": true,
|
||||
"color45": true,
|
||||
"color46": true,
|
||||
"color47": true,
|
||||
"color48": true,
|
||||
"color49": true,
|
||||
"color5": true,
|
||||
"color50": true,
|
||||
"color51": true,
|
||||
"color52": true,
|
||||
"color53": true,
|
||||
"color54": true,
|
||||
"color55": true,
|
||||
"color56": true,
|
||||
"color57": true,
|
||||
"color58": true,
|
||||
"color59": true,
|
||||
"color6": true,
|
||||
"color60": true,
|
||||
"color61": true,
|
||||
"color62": true,
|
||||
"color63": true,
|
||||
"color64": true,
|
||||
"color65": true,
|
||||
"color66": true,
|
||||
"color67": true,
|
||||
"color68": true,
|
||||
"color69": true,
|
||||
"color7": true,
|
||||
"color70": true,
|
||||
"color71": true,
|
||||
"color72": true,
|
||||
"color73": true,
|
||||
"color74": true,
|
||||
"color75": true,
|
||||
"color76": true,
|
||||
"color77": true,
|
||||
"color78": true,
|
||||
"color79": true,
|
||||
"color8": true,
|
||||
"color80": true,
|
||||
"color81": true,
|
||||
"color82": true,
|
||||
"color83": true,
|
||||
"color84": true,
|
||||
"color85": true,
|
||||
"color86": true,
|
||||
"color87": true,
|
||||
"color88": true,
|
||||
"color89": true,
|
||||
"color9": true,
|
||||
"color90": true,
|
||||
"color91": true,
|
||||
"color92": true,
|
||||
"color93": true,
|
||||
"color94": true,
|
||||
"color95": true,
|
||||
"color96": true,
|
||||
"color97": true,
|
||||
"color98": true,
|
||||
"color99": true,
|
||||
"cursor": true,
|
||||
"cursor_text_color": true,
|
||||
"cursor_trail_color": true,
|
||||
"foreground": true,
|
||||
"inactive_border_color": true,
|
||||
"inactive_tab_background": true,
|
||||
"inactive_tab_foreground": true,
|
||||
"macos_titlebar_color": true,
|
||||
"mark1_background": true,
|
||||
"mark1_foreground": true,
|
||||
"mark2_background": true,
|
||||
"mark2_foreground": true,
|
||||
"mark3_background": true,
|
||||
"mark3_foreground": true,
|
||||
"scrollbar_handle_color": true,
|
||||
"scrollbar_track_color": true,
|
||||
"selection_background": true,
|
||||
"selection_foreground": true,
|
||||
"tab_bar_background": true,
|
||||
"tab_bar_margin_color": true,
|
||||
"url_color": true,
|
||||
"visual_bell_color": true,
|
||||
"wayland_titlebar_color": true,
|
||||
"window_title_bar_active_background": true,
|
||||
"window_title_bar_active_foreground": true,
|
||||
"window_title_bar_inactive_background": true,
|
||||
"window_title_bar_inactive_foreground": true, // ALL_COLORS_END
|
||||
} // }}}
|
||||
|
||||
type JSONMetadata struct {
|
||||
|
|
|
|||
Loading…
Reference in a new issue