diff --git a/docs/changelog.rst b/docs/changelog.rst index f2f3db999..4531ee903 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -18,6 +18,9 @@ To update |kitty|, :doc:`follow the instructions `. - A new option :opt:`strip_trailing_spaces` to optionally remove trailing spaces from lines when copying to clipboard. +- A new option :opt:`tab_bar_min_tabs` to control how many tabs must be + present before the tab-bar is shown (:iss:`1382`) + - Automatically check for new releases and notify when an update is available, via the system notification facilities. Can be controlled by :opt:`update_check_interval` (:iss:`1342`) diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 5d82a8041..97628cbdf 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -571,7 +571,7 @@ prepare_to_render_os_window(OSWindow *os_window, double now, unsigned int *activ #define TD os_window->tab_bar_render_data bool needs_render = os_window->needs_render; os_window->needs_render = false; - if (TD.screen && os_window->num_tabs > 1) { + if (TD.screen && os_window->num_tabs >= OPT(tab_bar_min_tabs)) { if (!os_window->tab_bar_data_updated) { call_boss(update_tab_bar_data, "K", os_window->id); os_window->tab_bar_data_updated = true; @@ -620,7 +620,7 @@ render_os_window(OSWindow *os_window, double now, unsigned int active_window_id, Tab *tab = os_window->tabs + os_window->active_tab; BorderRects *br = &tab->border_rects; draw_borders(br->vao_idx, br->num_border_rects, br->rect_buf, br->is_dirty, os_window->viewport_width, os_window->viewport_height, active_window_bg, num_visible_windows, os_window); - if (TD.screen && os_window->num_tabs > 1) draw_cells(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, os_window, true, false); + if (TD.screen && os_window->num_tabs >= OPT(tab_bar_min_tabs)) draw_cells(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, os_window, true, false); for (unsigned int i = 0; i < tab->num_windows; i++) { Window *w = tab->windows + i; if (w->visible && WD.screen) { diff --git a/kitty/config_data.py b/kitty/config_data.py index 5f1da4d34..0a4ed10b4 100644 --- a/kitty/config_data.py +++ b/kitty/config_data.py @@ -596,6 +596,10 @@ each tab's edges fade into the background color, in the separator style, tabs ar separated by a configurable separator. ''')) +o('tab_bar_min_tabs', 2, option_type=lambda x: max(1, positive_int(x)), long_text=_(''' +The minimum number of tabs that must exist before the tab bar is shown +''')) + def tab_fade(x): return tuple(map(unit_float, x.split())) diff --git a/kitty/state.c b/kitty/state.c index 1ef4211f2..7d4ca137a 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -249,7 +249,7 @@ add_borders_rect(id_type os_window_id, id_type tab_id, uint32_t left, uint32_t t void os_window_regions(OSWindow *os_window, Region *central, Region *tab_bar) { - if (!global_state.tab_bar_hidden && os_window->num_tabs > 1) { + if (!global_state.tab_bar_hidden && os_window->num_tabs >= OPT(tab_bar_min_tabs)) { switch(OPT(tab_bar_edge)) { case TOP_EDGE: central->left = 0; central->top = os_window->fonts_data->cell_height; central->right = os_window->viewport_width - 1; @@ -395,6 +395,7 @@ PYWRAP1(set_options) { S(macos_window_resizable, PyObject_IsTrue); S(macos_hide_from_tasks, PyObject_IsTrue); S(macos_thicken_font, PyFloat_AsDouble); + S(tab_bar_min_tabs, PyLong_AsUnsignedLong); GA(tab_bar_style); global_state.tab_bar_hidden = PyUnicode_CompareWithASCIIString(ret, "hidden") == 0 ? true: false; diff --git a/kitty/state.h b/kitty/state.h index 951a209fa..ac0fc27a9 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -34,6 +34,7 @@ typedef struct { float inactive_text_alpha; float window_padding_width; Edge tab_bar_edge; + unsigned long tab_bar_min_tabs; bool sync_to_monitor; bool close_on_child_death; bool window_alert_on_bell; diff --git a/kitty/tabs.py b/kitty/tabs.py index fef567638..bce294c7a 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -409,17 +409,21 @@ class TabManager: # {{{ if not self.tab_bar_hidden: self.tab_bar.screen.refresh_sprite_positions() + @property + def tab_bar_should_be_visible(self): + return len(self.tabs) >= self.opts.tab_bar_min_tabs + def _add_tab(self, tab): - before = len(self.tabs) + visible_before = self.tab_bar_should_be_visible self.tabs.append(tab) - if len(self.tabs) > 1 and before < 2: + if not visible_before and self.tab_bar_should_be_visible: self.tabbar_visibility_changed() def _remove_tab(self, tab): - before = len(self.tabs) + visible_before = self.tab_bar_should_be_visible remove_tab(self.os_window_id, tab.id) self.tabs.remove(tab) - if len(self.tabs) < 2 and before > 1: + if visible_before and not self.tab_bar_should_be_visible: self.tabbar_visibility_changed() def _set_active_tab(self, idx): @@ -433,7 +437,7 @@ class TabManager: # {{{ glfw_post_empty_event() def mark_tab_bar_dirty(self): - if len(self.tabs) > 1 and not self.tab_bar_hidden: + if self.tab_bar_should_be_visible and not self.tab_bar_hidden: mark_tab_bar_dirty(self.os_window_id) def update_tab_bar_data(self): @@ -570,7 +574,7 @@ class TabManager: # {{{ @property def blank_rects(self): - return self.tab_bar.blank_rects if len(self.tabs) > 1 else () + return self.tab_bar.blank_rects if self.tab_bar_should_be_visible else () def destroy(self): for t in self: