8000 GitHub - nixfred/swish: macOS Cmd+Tab for Omarchy/Hyprland: hold SUPER, tab through glass workspace cards with live preview, release to switch. hyprshell + a small patch. · GitHub
[go: up one dir, main page]

Skip to content
nixfredPublic

About

macOS Cmd+Tab for Omarchy/Hyprland: hold SUPER, tab through glass workspace cards with live preview, release to switch. hyprshell + a small patch.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

Swish workspace groups displayed as stable numbered glass cards above a live Hyprland desktop preview

Swish

macOS ⌘-Tab for Omarchy / Hyprland — hold, tab, release.

Stock Omarchy binds SUPER+Tab to D398 next workspace, so it walks you 1 → 2 → 3 → 4 like a slideshow. Swish turns SUPER+Tab into the thing your Mac muscle memory expects: a glass bar of cards pops up, you tap Tab to move, the desktop behind it switches live so you can see where you're about to land, and letting go of SUPER commits. Esc bails and puts you back exactly where you were.

Cards are grouped by workspace, in numeric order, always. They never shuffle by recency — a card is where you left it, so your hands learn it.

flowchart LR
    H[Hold SUPER] --> O[Open glass<br/>workspace bar]
    O --> T[Tap Tab<br/>or backtick]
    T --> P[Preview highlighted<br/>workspace live]
    P --> M{Keep moving?}
    M -->|yes| T
    M -->|release SUPER| C[Commit highlighted<br/>workspace]
    M -->|Esc| R[Restore exact<br/>origin]

    classDef input fill:#101921,stroke:#7aa8ab,color:#eef8fa
    classDef preview fill:#17202a,stroke:#a48ec9,color:#f8f2ff
    classDef outcome fill:#14231c,stroke:#75c88a,color:#effff3
    class H,O,T input
    class P,M preview
    class C,R outcome
Loading

v0.1.1 — Mac back-and-forth

A quick SUPER+Tab tap now toggles between your last two workspaces, exactly like Cmd+Tab: on open, the switcher pre-selects the most recently used other workspace (by Hyprland focus history) while the cards stay in numeric order. Keep tapping to walk right; SUPER+Shift+Tab still walks left from the numeric previous.

What you get

Hold / tap / release Hold SUPER, tap Tab (or `) to move right, SUPER+Shift+Tab to move left. Release SUPER to switch. Esc cancels and restores your original window.
Live preview Every tap actually focuses the highlighted window / workspace underneath the overlay. No guessing — you watch the desktop change with the dimmed cards still on top.
Stable workspace groups One glass panel per workspace, 1 2 3 4 …, each holding its app cards. Same order every time. Add or close an app and only that card changes.
Liquid glass Frosted dark bar, blurred, with a cyan glow on the selected card — tuned to Omarchy's Japan Night palette, easy to retune to yours (it's CSS).
Fast ~110 ms pop-in, 140–160 ms selection transitions. No waiting on it, ever.
SUPER+q while open Kills the highlighted window without leaving the switcher.

How it works

Swish is hyprshell (the excellent GTK4 switcher/launcher for Hyprland by @h3rmt, MIT) plus a ~100-line patch and an opinionated config:

swish-workspace-preview.patch   ← the behaviour
config/config.ron               ← switch-only, workspace groups, global (no monitor/workspace filter)
config/styles.css               ← the glass
hypr/swish.lua                  ← frees SUPER+Tab, enables blur for the overlay layer
PKGBUILD                        ← builds `hyprshell-swish` (replaces hyprshell / hyprshell-bin)
install.sh                      ← does all of the above

The patch changes three things in hyprshell's switch mode:

  1. Numeric order. Upstream sorts workspace groups by most-recently-used. Swish sorts them by position/ID when switch_workspaces = true (plain client mode keeps upstream MRU).
  2. Live preview. navigate() now focuses the highlighted client/workspace immediately (preview_active()), instead of only on close. The overlay is a layer-shell surface, so it stays on top while the desktop changes behind it.
  3. Esc restores origin. The switcher remembers where you were when it opened and CloseSwitch(false) jumps back there.

Everything else — hold/release detection, the socket protocol, icons, theming — is upstream hyprshell, unchanged. Upstream's own config editor (hyprshell config edit) still works.

flowchart TB
    U[Upstream hyprshell<br/>4.10.8] --> P[Swish patch<br/>root.rs]
    P --> N[Numeric workspace<br/>group order]
    P --> M[MRU other workspace<br/>on forward open]
    P --> L[Live focus<br/>preview]
    P --> E[Esc origin<br/>restore]
    N --> S[hyprshell-swish]
    M --> S
    L --> S
    E --> S

    classDef upstream fill:#17202a,stroke:#8a929f,color:#f1f3f5
    classDef patch fill:#101921,stroke:#7aa8ab,color:#eef8fa
    classDef behavior fill:#211b29,stroke:#a48ec9,color:#f8f2ff
    class U upstream
    class P,S patch
    class N,M,L,E behavior
Loading

Install (Omarchy / Arch)

Requirements: Hyprland ≥ 0.55 with the Lua config (Omarchy 4.x has this), cargo, makepkg.

git clone https://github.com/nixfred/swish ~/Projects/swish
cd ~/Projects/swish
./install.sh

That will:

  • build and install the hyprshell-swish package (first build ≈ 3–4 min; it conflicts with hyprshell / hyprshell-bin and replaces them cleanly),
  • drop config.ron + styles.css into ~/.config/hyprshell/ (backing up anything already there),
  • copy hypr/swish.lua into ~/.config/hypr/ and add require("hypr.swish") to your hyprland.lua (after require("hypr.bindings"), so it wins),
  • enable + start the hyprshell user service and verify SUPER+Tab is registered.

Then: hold SUPER, tap Tab. That's it.

flowchart LR
    I[install.sh] --> B[makepkg builds<br/>patched package]
    B --> C[Back up and install<br/>hyprshell config]
    C --> L[Copy swish.lua<br/>and wire require]
    L --> H[Reload<br/>Hyprland]
    H --> D[Enable and start<br/>user service]
    D --> V[Verify SUPER+Tab<br/>binding]

    classDef install fill:#101921,stroke:#7aa8ab,color:#eef8fa
    classDef system fill:#17202a,stroke:#a48ec9,color:#f8f2ff
    classDef verify fill:#14231c,stroke:#75c88a,color:#effff3
    class I,B,C install
    class L,H,D system
    class V verify
Loading

Uninstall

./install.sh --uninstall     # removes package, hypr/swish.lua, the require line; leaves ~/.config/hyprshell/

Keys

Keys Does
SUPER + Tab open / move right
SUPER + Shift + Tab, SUPER + ` move left
← → ↑ ↓ / h j k l move (while open)
release SUPER switch to highlighted
Esc cancel — back to where you were
SUPER + q / Delete close the highlighted window, stay in the switcher

Stock SUPER+Ctrl+Tab (former workspace), SUPER+1..9, and Omarchy's swipe gestures are untouched. Only SUPER+Tab / SUPER+Shift+Tab are re-bound.

stateDiagram-v2
    [*] --> Closed
    Closed --> Open: SUPER + Tab
    Open --> Previewing: preselect MRU other
    Previewing --> Previewing: Tab / arrows / hjkl
    Previewing --> Previewing: SUPER + q closes client
    Previewing --> Committed: release SUPER
    Previewing --> Cancelled: Esc
    Committed --> Closed
    Cancelled --> OriginRestored
    OriginRestored --> Closed
Loading

Tuning

All live-reload (hyprshell watches both files):

  • Size of the cards — config/config.ron → scale (smaller number = bigger cards), items_per_row.
  • Colours / glow / radius — config/styles.css → the :root block. The glass is plain GTK4 CSS; the cyan is Japan Night's bright_cyan #7aa8ab, swap it for your theme's accent.
  • Want MRU order back? Set switch_workspaces: false — you'll get one flat row of cards in most-recently-used order (upstream's default feel), still with live preview.
  • Don't want blur? Comment the hl.config({ decoration = { blur … } }) line in hypr/swish.lua. The bar goes flat-dark instead of frosted.
  • Only current monitor / workspace? filter_by: [current_monitor] etc. in config.ron (upstream options).

Test it without touching the keyboard (handy when scripting / screenshotting):

hyprshell socat '{"OpenSwitch":{"reverse":false}}'   # open / tab
hyprshell socat '{"CloseSwitch":{"switch":false}}'   # esc
grim shot.png

Why not just …

  • cyclenext / focuscurrentorlast? Native, instant, no UI — but no visual and cyclenext hist bounces between two windows because focus history updates on every hop. Fine for a quick flip, not a switcher.
  • Upstream hyprshell as-is? Close! But the groups reorder by recency every time you open it ("when you move them I can't find them"), and it doesn't move until you let go. Swish fixes exactly those two.
  • hyprexpo? Great for an overview (Omarchy maps it to F3), not for ⌘-Tab flow.

Updating upstream

PKGBUILD pins an upstream tag (_upstream=4.10.8). To bump: change it, run makepkg -sif, and if the patch stops applying, the touch points are all in crates/windows-lib/src/switch/root.rs (open_switch, navigate, close_switch, SwitchData). The patch is small on purpose.

Credits

  • hyprshell by h3rmt — the whole switcher. Swish is a thin layer on top. MIT.
  • Omarchy by DHH & contributors — the desktop this is made for.
  • Built on vic by Fred Nix with Larry, 2026-08-21. Part of the "make Omarchy feel like my Mac" series alongside rift and plonk.

MIT — see LICENSE.

About

macOS Cmd+Tab for Omarchy/Hyprland: hold SUPER, tab through glass workspace cards with live preview, release to switch. hyprshell + a small patch.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

0