Skip to content

Add vertical tab bars on the left and right#9855

Merged
kovidgoyal merged 2 commits into
kovidgoyal:masterfrom
bvolpato:bvolpato/vertical-tab-bar-side
Jun 21, 2026
Merged

Add vertical tab bars on the left and right#9855
kovidgoyal merged 2 commits into
kovidgoyal:masterfrom
bvolpato:bvolpato/vertical-tab-bar-side

Conversation

@bvolpato

Copy link
Copy Markdown
Contributor

Summary

Add real side tab bars by teaching tab_bar_edge about left and right and rendering tabs as a vertical sidebar.

Changes

  • add left and right values to tab_bar_edge
  • allocate left/right tab bar regions in native window geometry
  • render side tabs as a vertical multi-line tab bar with row-based hit testing
  • route tab drag/drop targeting through the vertical axis when the tab bar is on the side
  • add focused tests for config parsing and vertical tab bar hit testing

Testing

  • python3 -m py_compile kitty/tab_bar.py kitty/tabs.py kitty/boss.py kitty/options/utils.py kitty/options/definition.py kitty_tests/options.py kitty_tests/tab_bar.py
  • attempted ./dev.sh build --debug, but this environment does not have the Linux X11/OpenGL development headers needed for kitty's native build (x11.pc and related headers were missing)

Repro / Manual Check

Use a config like:

 tab_bar_edge left
 tab_bar_style separator
 tab_bar_show_new_tab_button yes

Open several tabs and verify:

  • tabs render in a left sidebar
  • clicking anywhere on a sidebar row activates the tab
  • dragging tabs reorders them vertically
  • dragging a window onto a sidebar row moves it into that tab

Refs #2305

@kovidgoyal

Copy link
Copy Markdown
Owner

Will review actual code when I have more time. Just as an initial comment,
the intent of tab_bar_align is to align tabs at the start, center or
end. It should have the same semantics for vertical tab bars. Make the
accepted values start, center, end, left, right (with left and right
being synonyms for start, end. And have the vertical tabs drawn at the
top/middle/bottom accordingly. I dont really think a setting for
controlling halign is needed.

Also, at a more meta level, for vertical tabs it should be possible to
render them in two or more lines, the number of lines being reduced as
more tabs are added and just as in the horizontal case tabs are made
narrower as the number increases.

From a UI perspective, it might make sense to leave a blank line between
tabs to separate them. I dont know if you do that already havent
actually tested it yet.

Teach tab_bar_edge about left and right sidebars and route tab layout,
hit-testing, and drag/drop through the vertical axis when needed.
@bvolpato bvolpato force-pushed the bvolpato/vertical-tab-bar-side branch from 72bd0c9 to 8d93548 Compare April 25, 2026 19:22
@bvolpato

bvolpato commented Apr 25, 2026

Copy link
Copy Markdown
Contributor Author

addressed the initial feedback in 8d935486e:

  • tab_bar_align now accepts start, center, end, with left/right kept as aliases for start/end
  • vertical tab bars use the same align semantics now: top, middle, bottom
  • removed the per-title horizontal alignment behavior for vertical tabs
  • vertical tabs now use up to two rows per tab when there is room, dropping back to one row as tab count grows, which leaves visual separation between sparse tabs

local validation:

  • ./kitty/launcher/kitty +launch test.py --module tab_bar
  • ./kitty/launcher/kitty +launch test.py --module options
  • PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig:$PKG_CONFIG_PATH ./dev.sh build
image

@bvolpato bvolpato marked this pull request as ready for review April 26, 2026 04:06
@bvolpato

bvolpato commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

[review-prs-verification]
Head: 8d93548
Ready to merge: yes
Files reviewed.

  • kitty/boss.py
  • kitty/mouse.c
  • kitty/options/definition.py
  • kitty/options/parse.py
  • kitty/options/to-c-generated.h
  • kitty/options/types.py
  • kitty/options/utils.py
  • kitty/state.c
  • kitty/state.h
  • kitty/tab_bar.py
  • kitty/tabs.py
  • kitty_tests/options.py
  • kitty_tests/tab_bar.py
    Tests/checks run and results.
  • python3 -m py_compile kitty/tab_bar.py kitty/tabs.py kitty/boss.py kitty/options/utils.py kitty/options/definition.py kitty/options/parse.py kitty/options/types.py kitty_tests/options.py kitty_tests/tab_bar.py: PASS
  • PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig: ./dev.sh build: PASS
  • PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig: ./kitty/launcher/kitty +launch test.py --module tab_bar: PASS (2 tests)
  • PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig: ./kitty/launcher/kitty +launch test.py --module options: PASS (3 tests)
  • PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig: ./kitty/launcher/kitty +launch test.py --module mouse: PASS (1 test)
  • PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig: ./kitty/launcher/kitty +launch test.py --module layout: PASS (5 tests)
  • PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig: ./kitty/launcher/kitty +launch test.py --module datatypes: PASS (22 tests)
  • PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig: ./kitty/launcher/kitty +launch test.py --module dnd: PASS (133 tests)
  • gh pr checks 9855 --repo kovidgoyal/kitty --watch --interval 10: no checks reported on branch
    Fixes committed/pushed, if any.
  • None.
    Final CI status.
  • No status checks reported for head branch.

@kovidgoyal

Copy link
Copy Markdown
Owner

It's going to be a little while before I can review this as I am swamped with other work.

fawolfmann added a commit to fawolfmann/kitty that referenced this pull request Jun 7, 2026
Builds on top of kovidgoyal#9855 (vertical tab bars on left/right). When tab_bar_edge
is left or right and tab_bar_background is unset, derive a panel colour from
the theme (window background blended towards the foreground) so the sidebar
reads as a distinct panel rather than blending into the window content.
Overridable by setting tab_bar_background explicitly.

Also fill the area around the cell grid with the tab bar background instead
of the terminal background, so the panel stays one uniform colour to the
edges (no seam below/around the tabs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fawolfmann

fawolfmann commented Jun 8, 2026

Copy link
Copy Markdown

Build and Run Locally

Prerequisites: install a C compiler and Go. On Linux, also install the X11/OpenGL development libraries required by kitty.

Build from the repo root:

./dev.sh build

Run the locally built kitty binary:

kitty/launcher/kitty

To try this feature without editing your main kitty config:

kitty/launcher/kitty -o tab_bar_edge=left -o tab_bar_style=separator -o tab_bar_show_new_tab_button=yes

The sidebar width is currently controlled by the existing title-length setting:

kitty/launcher/kitty -o tab_bar_edge=left -o tab_title_max_length=12

@ioj

ioj commented Jun 17, 2026

Copy link
Copy Markdown

Thanks for your work, @bvolpato, and thanks for this brief instruction, @fawolfmann! I've been using this branch of kitty for a week without any problems.

@kovidgoyal kovidgoyal merged commit 54a7841 into kovidgoyal:master Jun 21, 2026
@harshv5094

Copy link
Copy Markdown

Thanks @bvolpato! Needed this feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants