An ergonomic, race-condition-free Quickshell Alt+Tab window switcher with home-row workspace navigation, native Hyprland grouped window tabs, dynamic multi-row overflow, and spatial miniature desktop layout for Omarchy.
Spatial desktop switching in action โ miniature workspace previews, home-row jumping, native window group tabs, and real-time app outlines.
Features โข Visual Tour โข Controls โข Installation โข Makefile Reference โข Architecture โข Testing
Most Linux Wayland task switchers either blindly iterate windows in an unstructured linear strip or trigger frantic focus changes on each keystroke. omalt-tab re-engineers window switching from first principles:
- โก Atomic, Race-Condition-Free Focus: Clients and workspaces are snapshotted once in RAM when the overlay opens. Cycling through tasks updates only internal selection states โ window focus history is never mutated mid-cycle. Focus is dispatched atomically only when you release Alt (or press Enter).
- ๐ Native Hyprland Grouped Windows (Tabs): Full first-class support for Hyprland tabbed window groups. Renders an interactive tab bar atop grouped window tiles showing app icons for each tab member, preserves active tab focus, and enables seamless intra-group tab navigation via arrow keys.
- ๐ Dynamic Multi-Row Overflow (> 6 Workspaces):
Workspaces dynamically overflow into a balanced two-row layout when more than 6 workspaces are active (
count > 6), comfortably fitting all 10 desktops without horizontal squishing or microscopic preview cards. - ๐งฑ Organic Staggered Row Arrangement (Brickwork Pattern):
Multi-row layouts are arranged in an organic brickwork / keyboard stagger (offset by half a card width,
$0.5 \times \text{stepSize}$ ), ensuring cards in Row 2 are never positioned directly beneath Row 1 while maintaining screen-centered symmetry. - ๐ฏ 1.1x Sweet-Spot Sizing & Centralized Design Tokens (
js/Dimensions.js): Layout, spacing, padding, badges, and typography are decoupled into pure metrics tokens scaled to the 1.1x "sweet spot" (~285px card width). Workspaces retain this ideal size regardless of whether 1, 6, 8, or 10 workspaces are active. - โจ Home-Row Workspace Jumping (
Aโ;): Skip tedious sequential cycling. Every workspace (1through10) is mapped straight across your keyboard's home row (A,S,D,F,G,H,J,K,L,;). Press one key to jump across your desktop instantly. - ๐ข Direct Window Focus Badges (
1โ9): Every window within each workspace card renders a distinct numbered badge styled to match your active Omarchy theme. Hit1โ9to immediately jump focus to that exact window without navigating. - ๐ Miniature Desktop Spatial Previews: Workspaces render miniature cards matching your display's true aspect ratio (16:9, 16:10, ultrawide). Window outlines reflect their genuine screen positions and sizes, with compensation for reserved top bars.
- ๐ฅ Multi-Monitor Intelligent Placement: Automatically resolves the currently active monitor and attaches the switcher overlay directly to that screen, normalizing window coordinates per monitor bounds.
- ๐ Hardened Security & Text Sanitization (
js/Utils.js): Centralized defense against CVE Unicode bidirectional override spoofing (CVE RTL-override: U+200E, U+200F, U+202AโU+202E, U+2066โU+2069), control character injection, and rich-text disruption across all UI sinks with explicitPlainTextformatting. - ๐ก Recursion-Safe Lifecycle Engine:
Guarded dismissal architecture (
isDismissing) preventing mutual recursion between overlay closing and Omarchy shell hides. Window focus is safely dispatched viaQtObjectandQuickshell.execDetachedbefore surface teardown. - ๐ Empty Workspace Traversal:
Unpopulated workspaces between active desktops are automatically detected and presented as cleanly styled empty cards. Jump to an empty desktop with a single keystroke and release
Altto land directly on it. - ๐จ Reactive Omarchy Theme Binding:
Inherits active palette colors (
Color.menu,Color.accent,Color.foreground), background scrim dimming, active typography (Style.font.*), and corner rounding (Style.cornerRadius) on the fly. - ๐ Sub-Millisecond UNIX Domain Socket:
Communicates over a dedicated socket (
$XDG_RUNTIME_DIR/omalt-tab.sock) with automatic fallback to Omarchy shell IPC for instant response times. - ๐ Zero-Dirty Git Developer Mode:
Developer mode toggles dynamically via a gitignored
.devflag file. Switch between development and production without dirtying tracked files or triggering git diffs.
- Header Bar: Displays active shortcut hints, jump keymaps, and dev badges.
- Workspace Cards: Scaled miniatures of each desktop containing proportional window outlines, high-res FreeDesktop application icons, and numbered badges (
1โ9). - Grouped Windows: Windows sharing a Hyprland group render integrated tab bars with icons for each member, highlighting the active tab with accent borders.
- Footer Bar: Displays the currently focused window title (sanitized plain-text), executable class name, and switching action hint.
When 7 to 10 workspaces are active, the switcher automatically splits into two rows:
- Row 1: Upper workspaces (e.g. 1โ5).
-
Row 2: Lower workspaces (e.g. 6โ10), offset by a half-step (
$0.5 \times \text{stepSize}$ ) in an organic brickwork pattern so cards are never stacked rigidly on top of each other. - 2D Spatial Traversal: Pressing โ and โ navigates smoothly between rows.
The background is gracefully dimmed with Omarchy's menu scrim, maintaining focus entirely on your task navigation.
| Input | Action |
|---|---|
| Alt + Tab | Cycle next window in MRU (Most Recently Used) order |
| Alt + Shift + Tab | Cycle previous window in MRU order |
| Release Alt | Commit selection and focus window immediately (Production mode) |
| Enter / Space | Commit and focus selected window (Required in Dev mode; supported in both) |
| Esc / Click outside | Cancel switcher without changing window focus |
| Key | Target |
|---|---|
| A | Jump to Workspace 1 |
| S | Jump to Workspace 2 |
| D | Jump to Workspace 3 |
| F | Jump to Workspace 4 |
| G | Jump to Workspace 5 |
| H | Jump to Workspace 6 |
| J | Jump to Workspace 7 |
| K | Jump to Workspace 8 |
| L | Jump to Workspace 9 |
| ; | Jump to Workspace 10 |
| 1 โ 9 | Select window index 1 through 9 (or active group tab) in active workspace |
| Input | Action |
|---|---|
| โ / โ | Spatial navigation left / right across adjacent windows, workspaces, and intra-group tabs |
| โ / โ | Spatial navigation up / down across stacked windows, intra-group tabs, and between Row 1 & Row 2 |
| Home / End | Jump to first / last window in the MRU sequence |
| Left Click Window | Immediately focus and switch to clicked window |
| Left Click Workspace | Immediately jump to clicked workspace |
Install and enable omalt-tab directly from git:
omarchy plugin add https://github.com/codesmith28/omalt-tab.git --enableFor development, testing, or customizing:
git clone https://github.com/codesmith28/omalt-tab.git ~/Projects/omalt-tab
cd ~/Projects/omalt-tab
make devmake dev sets up:
- A development symlink in
~/.config/omarchy/plugins/io.github.codesmith28.omalt-tab. - A gitignored
.devflag that enables Dev Mode (switcher stays open after releasingAlt, requiringEnterto switch, and showing the headerDEVbadge). - Automatic client binary symlinks and binding loader integration.
To install or restore standard release-to-switch behavior:
make prodVerify active mode, symlink targets, Omarchy plugin registration, and socket health anytime:
make statusTo fully uninstall omalt-tab, including keybindings and helper symlinks:
omarchy plugin remove io.github.codesmith28.omalt-tabOr from the project directory for a complete cleanup (uses omarchy plugin remove under the hood):
make uninstallPlugins in Omarchy live in ~/.config/omarchy/plugins/. Ensure your Omarchy keybindings configuration (~/.config/hypr/bindings.lua) includes the plugin loader:
Automatically loads bindings.lua from all installed Omarchy plugins:
-- Auto-load keybindings from installed Omarchy plugins (~/.config/omarchy/plugins/*/hypr/bindings.lua)
local plugins_dir = os.getenv("HOME") .. "/.config/omarchy/plugins"
local p = io.popen("find " .. plugins_dir .. " -maxdepth 3 -name 'bindings.lua' 2>/dev/null")
if p then
for file in p:lines() do
dofile(file)
end
p:close()
endSource omalt-tab specifically from its installed directory:
local omalt_tab = os.getenv("HOME") .. "/.config/omarchy/plugins/io.github.codesmith28.omalt-tab/hypr/bindings.lua"
local f = io.open(omalt_tab, "r")
if f then
f:close()
dofile(omalt_tab)
endomalt-tab includes a comprehensive Makefile for lifecycle management:
| Command | Action |
|---|---|
make dev |
Links project into Omarchy plugins, enables .dev mode, and reloads shell |
make prod |
Installs clean copy in standard production mode (release Alt to switch) |
make mode-dev |
Enables Dev Mode flag (.dev, gitignored) without touching tracked files |
make mode-prod |
Removes .dev flag file, restoring production mode |
make status |
Displays active mode, installation symlink state, socket status, and keybindings |
make test |
Executes automated Node.js unit tests for model, spatial logic, and navigation |
make validate |
Runs unit tests, manifest validation, client bash syntax, and lua syntax checks |
make restart |
Restarts Omarchy shell and reloads keybindings |
make update |
Syncs latest code changes and reloads the active environment |
make uninstall |
Runs omarchy plugin remove, cleans keybindings, and removes helper symlinks |
The codebase follows a clean separation of concerns across presentation, core algorithms, shell integration, and testing:
omalt-tab/
โโโ components/ # Modular QML visual presentation layer
โโโ js/ # Decoupled core logic, design tokens, & security
โโโ hypr/ # Keybinding submaps & IPC client script
โโโ tests/ # Automated regression and logic unit tests (19 tests)
โโโ scripts/ # Management scripts for install, link, and validation
โโโ demo/ # Showcase recordings and high-resolution media
โโโ AltTabOverlay.qml # Main shell overlay entry point & IPC coordinator
โโโ manifest.json # Omarchy plugin manifest contract
-
components/(Presentation Layer): Modular QML components handling all UI layout and styling. Houses miniature desktop cards (WorkspaceCard), proportional window tiles with selection glow and tab bars (WindowTile), shortcut hint headers (HeaderBar), and window metadata footers with plain-text sinks (FooterBar). -
js/(Core Logic Engine & Design System): Framework-agnostic JavaScript business logic decoupled from Qt Quick:WindowModel.js: Snapshot parser with top menu bar compensation and Hyprland grouped window member detection.Navigation.js: 2D spatial traversal across windows, intra-group tabs, multi-row workspaces, and MRU cycler.Dimensions.js: Centralized layout tokens locked to the 1.1x sweet spot (~285px card width).Utils.js: Centralized security utilities stripping Unicode direction overrides and control characters.Icons.js: Dynamic FreeDesktop candidate generator and Web App / PWA desktop file resolver.Config.js: Dynamic options for dev mode, badges, and debug logging.
-
hypr/(Keybindings & IPC Integration): Desktop hooks and IPC dispatching. Contains the Omarchy keybinding submap configuration with dynamic Alt-release watcher (bindings.lua) and the sub-millisecond UNIX domain socket client (omalt-tab-client). -
tests/(Verification Suite): Modular automated Node.js regression test suites validating coordinate normalization math, monitor scaling, spatial traversal algorithms, empty workspace handling, icon resolution fallbacks, grouped window tabs, multi-row overflow & stagger math, security sanitization, and dismissal recursion safety. -
demo/(Showcase Media): High-resolution media assets including the lossless showcase animation (demo.gif) and desktop screenshots.
All core snapshot parsing, empty workspace detection, home-row jumping, grouped window tabs, multi-row overflow, staggered row offsets, security sanitization, and lifecycle safety algorithms are rigorously unit-tested:
make testtest_window_model.js(Snapshot & Geometry): Usable geometry normalization, monitor scaling factors (1.25x, 1.5x, 2.0x), menu-bar exclusion, multi-monitor bounds, and Hyprland grouped window tab models.test_navigation.js(Spatial Navigation): 2D arrow traversal across windows, home-row letter jumping, intra-group tab navigation, and row-to-row jumping (> 6 workspaces).test_icons.js(Icons & Resolvers): FreeDesktop candidate lookup, Web Apps, PWAs, DesktopEntries, path traversal rejection, and untrusted metadata icon security sanitization.test_overlay_lifecycle.js(Lifecycle, Tokens & Safety): Circular recursion prevention onshell.hide(), atomicfocusWindow()dispatching, CVE BiDi control character stripping, plain-text sinks, and pure token separation inDimensions.js.test_integration_scripts.js(Integration & Packaging): Install notification flow,scripts/uninstall.shsafe execution ordering, andMakefileuninstall target safety.
To run the full validation suite (manifest validation, bash syntax checks, lua syntax checks, unit tests):
make validateDistributed under the Apache-2.0 License.
Created and maintained by Sarthak Siddhpura.


