Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion kitty/boss.py
Original file line number Diff line number Diff line change
Expand Up @@ -2001,7 +2001,7 @@ def on_drop(self, os_window_id: int, drop: dict[str, bytes] | int, from_self: bo
window.on_drop(drop)
break
elif tab_bar.left <= x < tab_bar.right and tab_bar.top <= y < tab_bar.bottom:
if (tab_id := tm.tab_bar.tab_id_at(x)) and (tab := self.tab_for_id(tab_id)) and (w := tab.active_window):
if (tab_id := tm.tab_bar.tab_id_at(x, y)) and (tab := self.tab_for_id(tab_id)) and (w := tab.active_window):
w.on_drop(drop)

def on_drag_source_finished(
Expand Down
2 changes: 2 additions & 0 deletions kitty/mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,8 @@ mouse_region(bool detect_borders, bool detect_title_bar) {
const bool in_central = mouse_in_region(&central);
if (!in_central) {
if (
(tab_bar.left < central.left && w->mouse_x < central.left) ||
(tab_bar.right > central.right && w->mouse_x >= central.right) ||
(tab_bar.top < central.top && w->mouse_y < central.top) ||
(tab_bar.bottom > central.bottom && w->mouse_y >= central.bottom)
) ans.in_tab_bar = true;
Expand Down
25 changes: 16 additions & 9 deletions kitty/options/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -1616,18 +1616,22 @@

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

opt('tab_bar_margin_width', '0.0',
option_type='positive_float',
long_text='The margin to the left and right of the tab bar (in pts).'
long_text='''
The margin perpendicular to the tab bar edge (in pts). For tab bars on the
top or bottom this is the margin to the left and right. For tab bars on the
left or right this is the margin above and below.
'''
)

opt('tab_bar_margin_height', '0.0 0.0',
option_type='tab_bar_margin_height', ctype='!tab_bar_margin_height',
long_text='''
The margin above and below the tab bar (in pts). The first number is the margin
The margin along the tab bar edge (in pts). The first number is the margin
between the edge of the OS Window and the tab bar. The second number is the
margin between the tab bar and the contents of the current tab.
'''
Expand Down Expand Up @@ -1675,11 +1679,12 @@
are automatically restricted to work only on matching tabs.
''')

opt('tab_bar_align', 'left',
choices=('left', 'center', 'right'),
opt('tab_bar_align', 'start',
choices=('start', 'center', 'end', 'left', 'right'),
long_text='''
The horizontal alignment of the tab bar, can be one of: :code:`left`,
:code:`center`, :code:`right`.
The alignment of the tab bar, can be one of: :code:`start`, :code:`center`,
:code:`end`, :code:`left`, :code:`right`. The values :code:`left` and
:code:`right` are aliases for :code:`start` and :code:`end` respectively.
'''
)

Expand Down Expand Up @@ -1746,10 +1751,12 @@
)

opt('tab_title_max_length', '0',
option_type='positive_int',
option_type='positive_int', ctype='int',
long_text='''
The maximum number of cells that can be used to render the text in a tab.
A value of zero means that no limit is applied.
A value of zero means that no limit is applied. For vertical tab bars, kitty
uses a default sidebar width sized for about twenty title cells when this is
left unset.
'''
)

Expand Down
4 changes: 2 additions & 2 deletions kitty/options/parse.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions kitty/options/to-c-generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions kitty/options/types.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion kitty/options/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,12 @@ def tab_separator(x: str) -> str:


def tab_bar_edge(x: str) -> int:
return {'top': defines.TOP_EDGE, 'bottom': defines.BOTTOM_EDGE}.get(x.lower(), defines.BOTTOM_EDGE)
return {
'left': defines.LEFT_EDGE,
'top': defines.TOP_EDGE,
'right': defines.RIGHT_EDGE,
'bottom': defines.BOTTOM_EDGE,
}.get(x.lower(), defines.BOTTOM_EDGE)


def tab_font_style(x: str) -> tuple[bool, bool]:
Expand Down
57 changes: 52 additions & 5 deletions kitty/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,29 +691,76 @@ pyset_borders_rects(PyObject *self UNUSED, PyObject *args) {
}


static unsigned
vertical_tab_bar_cols(const OSWindow *os_window, long margin_outer, long margin_inner) {
unsigned cell_width = MAX(1u, os_window->fonts_data->fcm.cell_width);
long available_width = (long)os_window->viewport_width - margin_outer - margin_inner;
if (available_width <= 0) return 0;
unsigned available_cols = MAX(1u, (unsigned)available_width / cell_width);
unsigned title_cols = OPT(tab_title_max_length) > 0 ? (unsigned)OPT(tab_title_max_length) : 20u;
unsigned desired_cols = title_cols + 8u;
unsigned soft_max = available_cols / 3u;
if (soft_max < 6u) soft_max = available_cols;
return MAX(1u, MIN(available_cols, MIN(desired_cols, MAX(1u, soft_max))));
}

void
os_window_regions(const OSWindow *os_window, Region *central, Region *tab_bar) {
if (!OPT(tab_bar_hidden) && os_window->num_tabs && !os_window->has_too_few_tabs) {
long margin_outer = pt_to_px_for_os_window(OPT(tab_bar_margin_height.outer), os_window);
long margin_inner = pt_to_px_for_os_window(OPT(tab_bar_margin_height.inner), os_window);
central->left = 0; central->right = os_window->viewport_width;
unsigned tab_bar_height = os_window->fonts_data->fcm.cell_height + margin_inner + margin_outer;
central->top = 0; central->bottom = os_window->viewport_height;
switch(OPT(tab_bar_edge)) {
case TOP_EDGE:
case TOP_EDGE: {
unsigned tab_bar_height = os_window->fonts_data->fcm.cell_height + margin_inner + margin_outer;
central->top = tab_bar_height;
central->bottom = os_window->viewport_height;
central->top = MIN(central->top, central->bottom);
tab_bar->top = margin_outer;
tab_bar->left = central->left; tab_bar->right = central->right;
tab_bar->bottom = tab_bar->top + os_window->fonts_data->fcm.cell_height;
break;
}
case LEFT_EDGE: {
unsigned left_cols = vertical_tab_bar_cols(os_window, margin_outer, margin_inner);
if (!left_cols) {
zero_at_ptr(tab_bar);
return;
}
unsigned left_width = left_cols * os_window->fonts_data->fcm.cell_width;
central->left = MIN((long)(left_width + margin_inner + margin_outer), (long)central->right);
tab_bar->left = margin_outer;
tab_bar->right = tab_bar->left + left_width;
tab_bar->top = central->top;
tab_bar->bottom = central->bottom;
break;
default:
}
case RIGHT_EDGE: {
unsigned right_cols = vertical_tab_bar_cols(os_window, margin_outer, margin_inner);
if (!right_cols) {
zero_at_ptr(tab_bar);
return;
}
unsigned right_width = right_cols * os_window->fonts_data->fcm.cell_width;
central->right = MAX(0, (long)os_window->viewport_width - (long)(right_width + margin_inner + margin_outer));
tab_bar->left = central->right + margin_inner;
tab_bar->right = tab_bar->left + right_width;
tab_bar->top = central->top;
tab_bar->bottom = central->bottom;
break;
}
default: {
unsigned tab_bar_height = os_window->fonts_data->fcm.cell_height + margin_inner + margin_outer;
central->top = 0;
long bottom = os_window->viewport_height - tab_bar_height;
central->bottom = MAX(0, bottom);
tab_bar->top = central->bottom + margin_inner;
tab_bar->left = central->left; tab_bar->right = central->right;
tab_bar->bottom = tab_bar->top + os_window->fonts_data->fcm.cell_height;
break;
}
}
tab_bar->left = central->left; tab_bar->right = central->right;
tab_bar->bottom = tab_bar->top + os_window->fonts_data->fcm.cell_height;
} else {
zero_at_ptr(tab_bar);
central->left = 0; central->top = 0; central->right = os_window->viewport_width;
Expand Down
1 change: 1 addition & 0 deletions kitty/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ typedef struct Options {
bool dynamic_background_opacity;
float inactive_text_alpha;
Edge tab_bar_edge;
int tab_title_max_length;
DisableLigature disable_ligatures;
bool force_ltr;
bool resize_in_steps;
Expand Down
Loading