A new option to set the tab bar margin color independently

This commit is contained in:
Kovid Goyal 2021-10-25 12:21:46 +05:30
parent c0927a3643
commit 4385acd3c6
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
15 changed files with 49 additions and 15 deletions

View File

@ -109,8 +109,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- Fix various issues with changing :opt:`tab_bar_background` by remote control
(:iss:`4152`)
- All tab bar margins are now drawn using the general background color, instead
of drawing only the left and right margins with the tab bar background color
- A new option :opt:`tab_bar_margin_color` to control the color of the tab bar
margins
- Add support for OSC 777 based desktop notifications

View File

@ -1,5 +1,4 @@
# generated by gen-config.py DO NOT edit
# vim:fileencoding=utf-8
import typing
from kittens.diff.options.utils import parse_map, syntax_aliases

View File

@ -1,5 +1,4 @@
# generated by gen-config.py DO NOT edit
# vim:fileencoding=utf-8
import typing
from kitty.conf.utils import KeyAction, KittensKeyMap

View File

@ -5,6 +5,7 @@ uniform vec3 active_border_color;
uniform vec3 inactive_border_color;
uniform vec3 bell_border_color;
uniform vec3 tab_bar_bg;
uniform vec3 tab_bar_margin_color;
in uvec4 rect; // left, top, right, bottom
in uint rect_color;
out vec3 color;
@ -41,5 +42,5 @@ void main() {
gl_Position = vec4(to_opengl(rect[pos.x], rect[pos.y]), 0, 1);
int rc = int(rect_color);
vec3 window_bg = vec3(to_color(rect_color >> 24), to_color(rect_color >> 16), to_color(rect_color >> 8));
color = W(0, default_bg) + W(1, active_border_color) + W(2, inactive_border_color) + W(3, window_bg) + W(4, bell_border_color) + W(5, tab_bar_bg);
color = W(0, default_bg) + W(1, active_border_color) + W(2, inactive_border_color) + W(3, window_bg) + W(4, bell_border_color) + W(5, tab_bar_bg) + W(6, tab_bar_margin_color);
}

View File

@ -15,7 +15,7 @@ from .window_list import WindowGroup, WindowList
class BorderColor(IntFlag):
# See the border vertex shader for how these flags become actual colors
default_bg, active, inactive, window_bg, bell, tab_bar_bg = ((1 << i) for i in range(6))
default_bg, active, inactive, window_bg, bell, tab_bar_bg, tab_bar_margin_color = ((1 << i) for i in range(7))
class Border(NamedTuple):

View File

@ -1688,17 +1688,19 @@ class Boss:
window.refresh()
def patch_colors(self, spec: Dict[str, Optional[int]], configured: bool = False) -> None:
from kitty.rc.set_colors import nullable_colors
opts = get_options()
if configured:
for k, v in spec.items():
if hasattr(opts, k):
if v is None:
if k in ('cursor_text_color', 'tab_bar_background'):
if k in nullable_colors:
setattr(opts, k, None)
else:
setattr(opts, k, color_from_int(v))
for tm in self.all_tab_managers:
tm.tab_bar.patch_colors(spec)
tm.tab_bar.layout()
tm.mark_tab_bar_dirty()
patch_global_colors(spec, configured)

View File

@ -1046,6 +1046,14 @@ opt('tab_bar_background', 'none',
long_text='''
Background color for the tab bar. Defaults to using the terminal background
color.
'''
)
opt('tab_bar_margin_color', 'none',
option_type='to_color_or_none', ctype='color_or_none_as_int',
long_text='''
Color for the tab bar margin area. Defaults to using the terminal background
color.
'''
)
egr() # }}}

View File

@ -1174,6 +1174,9 @@ class Parser:
def tab_bar_edge(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['tab_bar_edge'] = tab_bar_edge(val)
def tab_bar_margin_color(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['tab_bar_margin_color'] = to_color_or_none(val)
def tab_bar_margin_height(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['tab_bar_margin_height'] = tab_bar_margin_height(val)

View File

@ -616,6 +616,19 @@ convert_from_opts_tab_bar_background(PyObject *py_opts, Options *opts) {
Py_DECREF(ret);
}
static void
convert_from_python_tab_bar_margin_color(PyObject *val, Options *opts) {
opts->tab_bar_margin_color = color_or_none_as_int(val);
}
static void
convert_from_opts_tab_bar_margin_color(PyObject *py_opts, Options *opts) {
PyObject *ret = PyObject_GetAttrString(py_opts, "tab_bar_margin_color");
if (ret == NULL) return;
convert_from_python_tab_bar_margin_color(ret, opts);
Py_DECREF(ret);
}
static void
convert_from_python_foreground(PyObject *val, Options *opts) {
opts->foreground = color_as_int(val);
@ -1024,6 +1037,8 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
if (PyErr_Occurred()) return false;
convert_from_opts_tab_bar_background(py_opts, opts);
if (PyErr_Occurred()) return false;
convert_from_opts_tab_bar_margin_color(py_opts, opts);
if (PyErr_Occurred()) return false;
convert_from_opts_foreground(py_opts, opts);
if (PyErr_Occurred()) return false;
convert_from_opts_background(py_opts, opts);

View File

@ -411,6 +411,7 @@ option_names = ( # {{{
'tab_bar_align',
'tab_bar_background',
'tab_bar_edge',
'tab_bar_margin_color',
'tab_bar_margin_height',
'tab_bar_margin_width',
'tab_bar_min_tabs',
@ -548,6 +549,7 @@ class Options:
tab_bar_align: choices_for_tab_bar_align = 'left'
tab_bar_background: typing.Optional[kitty.rgb.Color] = None
tab_bar_edge: int = 3
tab_bar_margin_color: typing.Optional[kitty.rgb.Color] = None
tab_bar_margin_height: TabBarMarginHeight = TabBarMarginHeight(outer=0, inner=0)
tab_bar_margin_width: float = 0
tab_bar_min_tabs: int = 2

View File

@ -18,22 +18,25 @@ if TYPE_CHECKING:
from kitty.cli_stub import SetColorsRCOptions as CLIOptions
nullable_colors = ('cursor_text_color', 'tab_bar_background', 'tab_bar_margin_color')
def parse_colors(args: Iterable[str]) -> Dict[str, Optional[int]]:
colors: Dict[str, Optional[Color]] = {}
nullable_colors: Dict[str, Optional[int]] = {}
nullable_color_map: Dict[str, Optional[int]] = {}
for spec in args:
if '=' in spec:
colors.update(parse_config((spec.replace('=', ' '),)))
else:
with open(os.path.expanduser(spec), encoding='utf-8', errors='replace') as f:
colors.update(parse_config(f))
for k in ('cursor_text_color', 'tab_bar_background'):
for k in nullable_colors:
q = colors.pop(k, False)
if q is not False:
val = int(q) if isinstance(q, Color) else None
nullable_colors[k] = val
nullable_color_map[k] = val
ans: Dict[str, Optional[int]] = {k: int(v) for k, v in colors.items() if isinstance(v, Color)}
ans.update(nullable_colors)
ans.update(nullable_color_map)
return ans

View File

@ -790,7 +790,7 @@ draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GL
// }}}
// Borders {{{
enum BorderUniforms { BORDER_viewport, BORDER_background_opacity, BORDER_default_bg, BORDER_active_border_color, BORDER_inactive_border_color, BORDER_bell_border_color, BORDER_tab_bar_bg, NUM_BORDER_UNIFORMS };
enum BorderUniforms { BORDER_viewport, BORDER_background_opacity, BORDER_default_bg, BORDER_active_border_color, BORDER_inactive_border_color, BORDER_bell_border_color, BORDER_tab_bar_bg, BORDER_tab_bar_margin_color, NUM_BORDER_UNIFORMS };
static GLint border_uniform_locations[NUM_BORDER_UNIFORMS] = {0};
static void
@ -803,6 +803,7 @@ init_borders_program(void) {
SET_LOC(inactive_border_color)
SET_LOC(bell_border_color)
SET_LOC(tab_bar_bg)
SET_LOC(tab_bar_margin_color)
#undef SET_LOC
}
@ -843,6 +844,7 @@ draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_bu
glUniform3f(border_uniform_locations[BORDER_inactive_border_color], CV3(OPT(inactive_border_color)));
glUniform3f(border_uniform_locations[BORDER_bell_border_color], CV3(OPT(bell_border_color)));
glUniform3f(border_uniform_locations[BORDER_tab_bar_bg], CV3(OPT(tab_bar_background)));
glUniform3f(border_uniform_locations[BORDER_tab_bar_margin_color], CV3(OPT(tab_bar_margin_color)));
glUniform2ui(border_uniform_locations[BORDER_viewport], viewport_width, viewport_height);
color_type default_bg = (num_visible_windows > 1 && !all_windows_have_same_bg) ? OPT(background) : active_window_bg;
glUniform3f(border_uniform_locations[BORDER_default_bg], CV3(default_bg));

View File

@ -947,7 +947,7 @@ PYWRAP1(patch_global_colors) {
else if (PyLong_Check(val)) OPT(name) = PyLong_AsLong(val); \
} \
}
P(active_border_color); P(inactive_border_color); P(bell_border_color); P(tab_bar_background);
P(active_border_color); P(inactive_border_color); P(bell_border_color); P(tab_bar_background); P(tab_bar_margin_color);
if (configured) {
P(background); P(url_color);
P(mark1_background); P(mark1_foreground); P(mark2_background); P(mark2_foreground);

View File

@ -31,7 +31,7 @@ typedef struct {
unsigned int scrollback_pager_history_size;
bool scrollback_fill_enlarged_window;
char_type *select_by_word_characters;
color_type url_color, background, foreground, active_border_color, inactive_border_color, bell_border_color, tab_bar_background;
color_type url_color, background, foreground, active_border_color, inactive_border_color, bell_border_color, tab_bar_background, tab_bar_margin_color;
color_type mark1_foreground, mark1_background, mark2_foreground, mark2_background, mark3_foreground, mark3_background;
monotonic_t repaint_delay, input_delay;
bool focus_follows_mouse;

View File

@ -488,7 +488,7 @@ class TabBar:
def update_blank_rects(self, central: Region, tab_bar: Region, vw: int, vh: int) -> None:
opts = get_options()
blank_rects: List[Border] = []
bg = BorderColor.default_bg
bg = BorderColor.tab_bar_margin_color if opts.tab_bar_margin_color is not None else BorderColor.default_bg
if opts.tab_bar_margin_height:
if opts.tab_bar_edge == 3: # bottom
if opts.tab_bar_margin_height.outer: