Skip to content

Tab groups with a tab strip drawn like the system tab bar - #2

Merged
Zedyas merged 4 commits into
masterfrom
tab-groups-custom
Sep 28, 2026
Merged

Zedyas merged 4 commits into
masterfrom
tab-groups-custom

Conversation

@Zedyas

@Zedyas Zedyas commented Sep 28, 2026

Copy link
Copy Markdown
Owner

Summary

Adds Chrome-style tab groups. The system window tab bar cannot show a clickable group chip, hide tabs, or take clicks on its labels, so each window now draws its own tab strip, measured to match the system bar.

  • Tabs: each window holds its tabs (ReaderTab, one per document) and shows one. Menu and toolbar commands pass on to the shown tab through the responder chain.
  • Strip: equal-width tabs on a band that darkens the window color. The shown tab stays clear so it joins the page. Titles are centered, the close button appears at the left on hover, and a new tab button sits at the right end. It follows light, dark, and inactive windows.
  • Groups: a group has an optional name and a color from the app's own palette. Its chip is a tinted segment before its tabs, and a line in its color runs under them.
    • Click the chip to collapse or expand the group; a collapsed chip shows a tab count.
    • Right-click the chip to rename, recolor, add a tab, ungroup, close, or move the group to a new window.
    • Right-click a tab to add it to a group or take it out.
  • Dragging: a tab or chip follows the pointer along the strip while the other tabs slide aside. Pulled away from the strip, it drags to another window's strip, or opens a new window when released outside every window.
  • Sessions: groups, including collapsed ones, are saved and restored with the session. Sessions saved before this change still load.
  • Shortcuts: ⌘W closes a tab and ⇧⌘W the window. ⇧⌘[ ⇧⌘], ⌃⇥ ⌃⇧⇥, and ⌘1–⌘9 skip tabs hidden in collapsed groups. View > Always Show Tab Bar (⇧⌘T).

Testing

  • 21 Swift tests pass. They cover strip order and drop slots, keeping groups together, session filtering and decoding of older sessions, and moves and closes that keep the shown tab and collapsed groups.
  • Checked by mouse in a test copy with its own saved data:
    • Hover and close.
    • The new tab button, including with tabs overflowing a narrow window.
    • Creating, naming, collapsing, and recoloring a group.
    • Dragging a tab into a group's end and its middle, and dragging a group by its chip.
    • Tearing a tab off into a new window, and dropping a tab onto another window's strip.
    • ⌘W while dragging, and 15 tabs in one window.
    • Quitting and relaunching with groups.
  • The strip's colors were compared pixel by pixel with the system tab bar in light and dark.

Replaces the native window tabs with the app's own strip under the
toolbar. Tabs can be grouped under a colored chip with an optional name;
clicking the chip collapses the group, and tabs or whole groups drag to
reorder, move between windows, or open a new window. Groups are saved
with the session.

Each window controller now holds its tabs (ReaderTab, one per document)
and shows one at a time; menu commands reach the shown tab through the
responder chain.
Control-Tab and Control-Shift-Tab switch tabs again: the window used them
for keyboard focus before the menu saw them, so a key monitor catches them.
The group editor keeps its margins, new groups start blue instead of grey,
and the shortcuts page and README describe groups.
…essions

Taking tabs out of a window no longer picks a replacement on the spot,
which could pick a tab hidden in a collapsed group and expand it. A tab
moved within its window stays shown, a group moved to another window
keeps its shown tab, and a window that loses its shown tab shows the
nearest visible tab, or a new tab when every tab left is in a collapsed
group, the same rule collapsing uses.

While a tab is dragged, every window shows its tab strip, so a window
with a single tab can take the drop. The drag state is one value.

Sessions saved before tab groups have no groups key; they load again
instead of being dropped.
The strip copies the measures and colors of the tab bar AppKit draws: equal
tabs on a band that darkens the window color, the shown tab left clear so
the desktop tint shows through, centered titles, the close button at the
left on hover, dividers, and a new tab segment at the right end. It moves
from a title bar accessory into the top of the content view, because AppKit
draws a separator over accessories that only its own tab bar can hide.

A pressed tab or group chip now follows the pointer along the strip while
the others slide aside, and becomes a drag to another window or a new one
once pulled away from the strip. Drop slots are picked by the nearest gap,
with a margin at a group's end so a tab leaves the group only on purpose.
@Zedyas
Zedyas merged commit 25bb0fb into master Sep 28, 2026
1 check passed
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.

1 participant