Skip to content

Commit 54a7841

Browse files
committed
Merge branch 'bvolpato/vertical-tab-bar-side' of https://github.com/bvolpato/kitty
2 parents 42d3cb2 + 8d93548 commit 54a7841

13 files changed

Lines changed: 397 additions & 78 deletions

File tree

kitty/boss.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2017,7 +2017,7 @@ def on_drop(self, os_window_id: int, drop: dict[str, bytes] | int, from_self: bo
20172017
window.on_drop(drop)
20182018
break
20192019
elif tab_bar.left <= x < tab_bar.right and tab_bar.top <= y < tab_bar.bottom:
2020-
if (tab_id := tm.tab_bar.tab_id_at(x)) and (tab := self.tab_for_id(tab_id)) and (w := tab.active_window):
2020+
if (tab_id := tm.tab_bar.tab_id_at(x, y)) and (tab := self.tab_for_id(tab_id)) and (w := tab.active_window):
20212021
w.on_drop(drop)
20222022

20232023
def on_drag_source_finished(

kitty/mouse.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,8 @@ mouse_region(bool detect_borders, bool detect_title_bar) {
10101010
const bool in_central = mouse_in_region(&central);
10111011
if (!in_central) {
10121012
if (
1013+
(tab_bar.left < central.left && w->mouse_x < central.left) ||
1014+
(tab_bar.right > central.right && w->mouse_x >= central.right) ||
10131015
(tab_bar.top < central.top && w->mouse_y < central.top) ||
10141016
(tab_bar.bottom > central.bottom && w->mouse_y >= central.bottom)
10151017
) ans.in_tab_bar = true;

kitty/options/definition.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,18 +1616,22 @@
16161616

16171617
opt('tab_bar_edge', 'bottom',
16181618
option_type='tab_bar_edge', ctype='int',
1619-
long_text='The edge to show the tab bar on, :code:`top` or :code:`bottom`.'
1619+
long_text='The edge to show the tab bar on, :code:`top`, :code:`bottom`, :code:`left` or :code:`right`.'
16201620
)
16211621

16221622
opt('tab_bar_margin_width', '0.0',
16231623
option_type='positive_float',
1624-
long_text='The margin to the left and right of the tab bar (in pts).'
1624+
long_text='''
1625+
The margin perpendicular to the tab bar edge (in pts). For tab bars on the
1626+
top or bottom this is the margin to the left and right. For tab bars on the
1627+
left or right this is the margin above and below.
1628+
'''
16251629
)
16261630

16271631
opt('tab_bar_margin_height', '0.0 0.0',
16281632
option_type='tab_bar_margin_height', ctype='!tab_bar_margin_height',
16291633
long_text='''
1630-
The margin above and below the tab bar (in pts). The first number is the margin
1634+
The margin along the tab bar edge (in pts). The first number is the margin
16311635
between the edge of the OS Window and the tab bar. The second number is the
16321636
margin between the tab bar and the contents of the current tab.
16331637
'''
@@ -1675,11 +1679,12 @@
16751679
are automatically restricted to work only on matching tabs.
16761680
''')
16771681

1678-
opt('tab_bar_align', 'left',
1679-
choices=('left', 'center', 'right'),
1682+
opt('tab_bar_align', 'start',
1683+
choices=('start', 'center', 'end', 'left', 'right'),
16801684
long_text='''
1681-
The horizontal alignment of the tab bar, can be one of: :code:`left`,
1682-
:code:`center`, :code:`right`.
1685+
The alignment of the tab bar, can be one of: :code:`start`, :code:`center`,
1686+
:code:`end`, :code:`left`, :code:`right`. The values :code:`left` and
1687+
:code:`right` are aliases for :code:`start` and :code:`end` respectively.
16831688
'''
16841689
)
16851690

@@ -1746,10 +1751,12 @@
17461751
)
17471752

17481753
opt('tab_title_max_length', '0',
1749-
option_type='positive_int',
1754+
option_type='positive_int', ctype='int',
17501755
long_text='''
17511756
The maximum number of cells that can be used to render the text in a tab.
1752-
A value of zero means that no limit is applied.
1757+
A value of zero means that no limit is applied. For vertical tab bars, kitty
1758+
uses a default sidebar width sized for about twenty title cells when this is
1759+
left unset.
17531760
'''
17541761
)
17551762

kitty/options/parse.py

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kitty/options/to-c-generated.h

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kitty/options/types.py

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kitty/options/utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,12 @@ def tab_separator(x: str) -> str:
751751

752752

753753
def tab_bar_edge(x: str) -> int:
754-
return {'top': defines.TOP_EDGE, 'bottom': defines.BOTTOM_EDGE}.get(x.lower(), defines.BOTTOM_EDGE)
754+
return {
755+
'left': defines.LEFT_EDGE,
756+
'top': defines.TOP_EDGE,
757+
'right': defines.RIGHT_EDGE,
758+
'bottom': defines.BOTTOM_EDGE,
759+
}.get(x.lower(), defines.BOTTOM_EDGE)
755760

756761

757762
def tab_font_style(x: str) -> tuple[bool, bool]:

kitty/state.c

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -691,29 +691,76 @@ pyset_borders_rects(PyObject *self UNUSED, PyObject *args) {
691691
}
692692

693693

694+
static unsigned
695+
vertical_tab_bar_cols(const OSWindow *os_window, long margin_outer, long margin_inner) {
696+
unsigned cell_width = MAX(1u, os_window->fonts_data->fcm.cell_width);
697+
long available_width = (long)os_window->viewport_width - margin_outer - margin_inner;
698+
if (available_width <= 0) return 0;
699+
unsigned available_cols = MAX(1u, (unsigned)available_width / cell_width);
700+
unsigned title_cols = OPT(tab_title_max_length) > 0 ? (unsigned)OPT(tab_title_max_length) : 20u;
701+
unsigned desired_cols = title_cols + 8u;
702+
unsigned soft_max = available_cols / 3u;
703+
if (soft_max < 6u) soft_max = available_cols;
704+
return MAX(1u, MIN(available_cols, MIN(desired_cols, MAX(1u, soft_max))));
705+
}
706+
694707
void
695708
os_window_regions(const OSWindow *os_window, Region *central, Region *tab_bar) {
696709
if (!OPT(tab_bar_hidden) && os_window->num_tabs && !os_window->has_too_few_tabs) {
697710
long margin_outer = pt_to_px_for_os_window(OPT(tab_bar_margin_height.outer), os_window);
698711
long margin_inner = pt_to_px_for_os_window(OPT(tab_bar_margin_height.inner), os_window);
699712
central->left = 0; central->right = os_window->viewport_width;
700-
unsigned tab_bar_height = os_window->fonts_data->fcm.cell_height + margin_inner + margin_outer;
713+
central->top = 0; central->bottom = os_window->viewport_height;
701714
switch(OPT(tab_bar_edge)) {
702-
case TOP_EDGE:
715+
case TOP_EDGE: {
716+
unsigned tab_bar_height = os_window->fonts_data->fcm.cell_height + margin_inner + margin_outer;
703717
central->top = tab_bar_height;
704718
central->bottom = os_window->viewport_height;
705719
central->top = MIN(central->top, central->bottom);
706720
tab_bar->top = margin_outer;
721+
tab_bar->left = central->left; tab_bar->right = central->right;
722+
tab_bar->bottom = tab_bar->top + os_window->fonts_data->fcm.cell_height;
723+
break;
724+
}
725+
case LEFT_EDGE: {
726+
unsigned left_cols = vertical_tab_bar_cols(os_window, margin_outer, margin_inner);
727+
if (!left_cols) {
728+
zero_at_ptr(tab_bar);
729+
return;
730+
}
731+
unsigned left_width = left_cols * os_window->fonts_data->fcm.cell_width;
732+
central->left = MIN((long)(left_width + margin_inner + margin_outer), (long)central->right);
733+
tab_bar->left = margin_outer;
734+
tab_bar->right = tab_bar->left + left_width;
735+
tab_bar->top = central->top;
736+
tab_bar->bottom = central->bottom;
707737
break;
708-
default:
738+
}
739+
case RIGHT_EDGE: {
740+
unsigned right_cols = vertical_tab_bar_cols(os_window, margin_outer, margin_inner);
741+
if (!right_cols) {
742+
zero_at_ptr(tab_bar);
743+
return;
744+
}
745+
unsigned right_width = right_cols * os_window->fonts_data->fcm.cell_width;
746+
central->right = MAX(0, (long)os_window->viewport_width - (long)(right_width + margin_inner + margin_outer));
747+
tab_bar->left = central->right + margin_inner;
748+
tab_bar->right = tab_bar->left + right_width;
749+
tab_bar->top = central->top;
750+
tab_bar->bottom = central->bottom;
751+
break;
752+
}
753+
default: {
754+
unsigned tab_bar_height = os_window->fonts_data->fcm.cell_height + margin_inner + margin_outer;
709755
central->top = 0;
710756
long bottom = os_window->viewport_height - tab_bar_height;
711757
central->bottom = MAX(0, bottom);
712758
tab_bar->top = central->bottom + margin_inner;
759+
tab_bar->left = central->left; tab_bar->right = central->right;
760+
tab_bar->bottom = tab_bar->top + os_window->fonts_data->fcm.cell_height;
713761
break;
762+
}
714763
}
715-
tab_bar->left = central->left; tab_bar->right = central->right;
716-
tab_bar->bottom = tab_bar->top + os_window->fonts_data->fcm.cell_height;
717764
} else {
718765
zero_at_ptr(tab_bar);
719766
central->left = 0; central->top = 0; central->right = os_window->viewport_width;

kitty/state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ typedef struct Options {
110110
bool dynamic_background_opacity;
111111
float inactive_text_alpha;
112112
Edge tab_bar_edge;
113+
int tab_title_max_length;
113114
DisableLigature disable_ligatures;
114115
bool force_ltr;
115116
bool resize_in_steps;

0 commit comments

Comments
 (0)