A lightweight, keyboard-driven window switcher for macOS. Tabbs replaces the system app switcher with a fast way to move between individual windows across Spaces, without thumbnails or persistent visual clutter.
Tabbs is built natively with AppKit and Carbon. It does not use Electron or SwiftUI.
Tabbs requires macOS 13 or later.
- Download the latest
Tabbs.dmgfrom GitHub Releases. - Open the DMG and drag Tabbs to Applications.
- Launch Tabbs and complete the permission walkthrough.
The public build is signed with Developer ID, notarized by Apple, and distributed outside the Mac App Store.
Tabbs needs Accessibility access to discover, focus, and manage windows. Because the default shortcut replaces macOS's reserved Command-Tab switcher, the default setup also needs Input Monitoring access. If you change the shortcut to a non-reserved combination, Input Monitoring is not required.
Tabbs does not capture the screen, generate window thumbnails, or require Screen Recording permission.
The optional Ghostty 1.3+ and cmux tab integrations use Apple Events. macOS may show an Automation prompt the first time either integration is used. Tabbs uses that access only to enumerate, select, and close terminal tabs.
- Command-Tab — open the switcher or move forward
- Command-Shift-Tab — open the switcher in reverse or move backward
- Arrow keys — navigate the current layout
- Down Arrow on a group — enter its child-window or terminal-tab selector
- Up Arrow — leave the child selector in the horizontal layout
- 1–9 — jump directly to an entry in the active selector
- Hold the shortcut modifier without navigating — open fuzzy search after the configured delay (1.5 seconds by default)
- Escape — dismiss without switching
- Release Command — focus the selected window
The main list and child selectors wrap in both directions. The shortcut is customizable in Settings; the modifier shown above changes with it.
- W — close the selected window or supported terminal tab
- Q — quit the selected application
- M — minimize the selected window
- H — hide the selected application
- F — toggle fullscreen for the selected window
Tabbs lists regular application windows, including minimized and hidden windows and windows on other Spaces. Applications are ordered by recent activity; windows within an application retain their window order. Finder is excluded by default.
Two layouts are available:
- Horizontal icon flow (default) — application icons in a grid with an optional title capsule for the selected window
- Vertical list — application icon, application name, and window title in rows
Settings include layout sizing, visual material and opacity, corner and border styling, accent color, typography, animation duration, switcher position, stale-window indicators, delayed-search behavior, shortcut recording, per-screen filtering, and an application exclusion list. The switcher follows macOS light/dark appearance and respects Reduce Motion and Increase Contrast.
On multi-monitor setups, the switcher appears on the display containing the pointer. The optional Filter by screen setting limits the list to windows on that display.
Building requires macOS 13 or later and Xcode Command Line Tools with a Swift toolchain compatible with Swift Package Manager 5.9.
Development builds use a stable self-signed Tabbs Dev identity so macOS keeps
Accessibility permission across rebuilds:
make setup-codesign # one-time setup
make run # release build, bundle, and launch
make dev # debug build, bundle, and launch
make test # run the Swift test suite
make stop # stop a running instance
make install # install the local build in /Applications
make clean # remove local build artifactsOther useful development targets include make fg, make logs, make watch,
make check-ax, and make debug-dump-windows. make watch additionally requires
fswatch.
Public distribution uses a Developer ID Application certificate, hardened runtime, notarization, and stapling. Configure it once:
make check-dist-signing
make setup-notary APPLE_ID=you@example.com
make check-notaryThen build and verify both distributable formats:
make release-distOutputs:
.build/dist/Tabbs.dmg.build/dist/Tabbs.zip
If multiple Developer ID identities are installed, provide the exact identity:
make release-dist DIST_SIGN_IDENTITY='Developer ID Application: Name (TEAMID)'If Team ID auto-detection fails during notary setup, provide it explicitly:
make setup-notary APPLE_ID=you@example.com TEAM_ID=YOURTEAMIDWindow discovery combines Core Graphics, Accessibility, and private WindowServer APIs. Core Graphics and CGS supply cross-Space window data; Accessibility maps windows to actionable elements for focusing, minimizing, closing, and fullscreen operations. A cached activity tracker supplies app-level recent-use ordering.
Ghostty and cmux expose tabs through AppleScript rather than Accessibility. Tabbs maintains a short-lived background cache for those integrations so normal switcher use does not wait on Apple Events.
Key source files:
Sources/Tabbs/
├── AppDelegate.swift # App lifecycle and switcher orchestration
├── HotkeyManager.swift # Carbon hotkeys, Command-Tab event tap, actions
├── WindowManager.swift # Window discovery, ordering, and activation
├── WindowActivityTracker.swift # Persistent app-level activity history
├── WindowGrouping.swift # Window and terminal-tab groups
├── TerminalTabs.swift # Ghostty/cmux AppleScript integration
├── SwitcherPanel.swift # Main panel and horizontal child selector
├── VerticalChildListPanel.swift # Vertical child selector
├── HorizontalIconsContentView.swift # Horizontal renderer
├── VerticalListContentView.swift # Vertical renderer
├── OnboardingWindow.swift # First-run permission flow
├── SettingsWindow.swift # Settings UI
├── Shortcuts.swift # Shortcut persistence and defaults
├── AppearanceConfig.swift # Appearance and behavior persistence
└── CGSPrivate.swift # Private WindowServer declarations
- Stage Manager behavior is not yet verified.
- There is no per-Space filter; cross-Space windows are intentionally included.
- Recent-use ordering is tracked at application level. Windows within the same application use their existing window order.
- Cross-Space discovery and precise activation rely partly on undocumented macOS APIs, which may change in future macOS releases.
- Ghostty/cmux integration depends on those applications' scripting interfaces and may show slightly stale tab data while its short cache refreshes.