Skip to content

Add vertical tab bars on the left and right#9855

Open
bvolpato wants to merge 2 commits into
kovidgoyal:masterfrom
bvolpato:bvolpato/vertical-tab-bar-side
Open

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

Conversation

@bvolpato
Copy link
Copy Markdown

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
Copy link
Copy Markdown
Author

bvolpato commented Apr 25, 2026

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
Copy link
Copy Markdown
Author

bvolpato commented May 5, 2026

[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.

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.

2 participants