{"id":51268483,"url":"https://github.com/z20240/yabai-dockstack","last_synced_at":"2026-06-29T16:30:48.965Z","repository":{"id":368028765,"uuid":"1283142224","full_name":"z20240/yabai-dockstack","owner":"z20240","description":"Visual enhancement suite for yabai: stack indicators, cross-space window menu, and Dock window previews.","archived":false,"fork":false,"pushed_at":"2026-06-28T18:53:19.000Z","size":14337,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T19:24:08.911Z","etag":null,"topics":["dock","dockview","macos","menu-bar","screencapturekit","stackline","swift","tiling","window-manager","window-switcher","yabai"],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/z20240.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-28T15:39:35.000Z","updated_at":"2026-06-28T18:53:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/z20240/yabai-dockstack","commit_stats":null,"previous_names":["z20240/yabai-dockstack"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/z20240/yabai-dockstack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z20240%2Fyabai-dockstack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z20240%2Fyabai-dockstack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z20240%2Fyabai-dockstack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z20240%2Fyabai-dockstack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/z20240","download_url":"https://codeload.github.com/z20240/yabai-dockstack/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z20240%2Fyabai-dockstack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34935214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dock","dockview","macos","menu-bar","screencapturekit","stackline","swift","tiling","window-manager","window-switcher","yabai"],"created_at":"2026-06-29T16:30:45.579Z","updated_at":"2026-06-29T16:30:48.956Z","avatar_url":"https://github.com/z20240.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"assets/banner.png\" width=\"760\" alt=\"yabai-dockstack — visual enhancements for yabai on macOS\" /\u003e\n\n[![Release](https://img.shields.io/github/v/release/z20240/yabai-dockstack?label=release)](https://github.com/z20240/yabai-dockstack/releases)\n[![Stars](https://img.shields.io/github/stars/z20240/yabai-dockstack)](https://github.com/z20240/yabai-dockstack/stargazers)\n[![License](https://img.shields.io/github/license/z20240/yabai-dockstack)](LICENSE)\n![Platform](https://img.shields.io/badge/platform-macOS%2014%2B-lightgrey)\n\nEnglish · [繁體中文](README.zh-Hant.md)\n\n\u003csub\u003eInspired by [stackline](https://github.com/AdamWagner/stackline) and DockView ·\nkeywords: yabai, stackline, dockview, macOS window manager, tiling, stack indicator,\ndock preview, window switcher, menu bar, Mission Control alternative\u003c/sub\u003e\n\n\u003c/div\u003e\n\n---\n\n`yabai-dockstack` adds the visual layer that yabai lacks:\n\n- **Stack indicators** — a floating indicator next to each window stack so you see, at\n  a glance, which apps are stacked and in what order (inspired by **stackline**).\n- **Cross-space window menu** — every window grouped by Display → Space in the menu\n  bar; click to jump and focus.\n- **Dock window previews** — hover a Dock icon to peek an app's windows across all\n  spaces with thumbnails; click to jump (inspired by **DockView**).\n\nIt is a clean Swift rewrite — **not** a fork of stackline (which required Hammerspoon).\n\n## Demo\n\n**Stack indicators** — see at a glance which apps are stacked and where.\n\n\u003cimg src=\"assets/demo-stack-indicators.gif\" width=\"760\" alt=\"stack indicators demo\" /\u003e\n\n**Cross-space window menu** — every window grouped by Display → Space; click to jump.\n\n\u003cimg src=\"assets/demo-window-menu.gif\" width=\"760\" alt=\"cross-space window menu demo\" /\u003e\n\n**Jump \u0026 focus across spaces** — one click brings you to the window's space.\n\n\u003cimg src=\"assets/demo-jump-focus.gif\" width=\"760\" alt=\"jump and focus demo\" /\u003e\n\n**Dock window previews** — hover a Dock icon to peek an app's windows; click to jump.\n\n\u003cimg src=\"assets/demo-dock-previews.gif\" width=\"760\" alt=\"dock window previews demo\" /\u003e\n\n## Features\n\n- 🚦 One floating indicator per stack, placed at the window's outer screen edge.\n- 🅰️ **Icon mode** (default): app icons stacked top→bottom in stack-index order;\n  focused window highlighted. **Flag mode**: slim minimal markers. Toggle from\n  the menu bar.\n- 🔎 **Hover** an indicator → popover with that window's full title.\n- 🖱️ **Click** an indicator → focus that window (via yabai).\n- 🖥️ Multi-monitor, all visible spaces.\n- 🪶 No Hammerspoon. Minimal permissions (no Accessibility, no Screen Recording —\n  focus is delegated to yabai).\n\n## Requirements\n\n- macOS 14+\n- **[yabai](https://github.com/koekeishiya/yabai) — required.** yabai-dockstack is a\n  companion for yabai and does nothing on its own: every feature reads window/stack\n  state from `yabai -m query`. Without it the menu bar just shows\n  **\"yabai: not found\"**. yabai must be installed, **running**, and set up enough to\n  create stacks (see yabai's install/configuration guide).\n\n## Install\n\n### Homebrew (recommended)\n\n```sh\nbrew install --cask z20240/tap/yabai-dockstack\n```\n\nUniversal (Apple Silicon + Intel). The app is ad-hoc signed but **not\nApple-notarized**, so Gatekeeper would normally block it — the cask strips the\nquarantine attribute on install (postflight) so it opens without a prompt. If you\ndownload the release zip manually instead, run once:\n`xattr -dr com.apple.quarantine /Applications/yabai-dockstack.app` (or System\nSettings → Privacy \u0026 Security → **Open Anyway**).\n\n**yabai is required and is NOT installed automatically** (it lives in a third-party\ntap that a cask can't auto-tap). Install and start it:\n\n```sh\nbrew tap koekeishiya/formulae\nbrew install yabai\nyabai --start-service          # see yabai's docs for full setup (incl. SIP)\nopen -a yabai-dockstack\n```\n\nIf yabai isn't found on launch, the app shows a **setup guide** (Install yabai via\nTerminal · Open install guide · Set yabai path) and a red **\"yabai not found — set\nup…\"** item in the menu bar. It starts working automatically once yabai is running.\n\n### Build from source\n\n```sh\n./scripts/bundle.sh        # produces yabai-dockstack.app\nopen yabai-dockstack.app\n```\n\n\u003e **Toolchain note.** Builds with full Xcode or standalone Command Line Tools. If\n\u003e `swift build` complains about the Xcode license, run `sudo xcodebuild -license\n\u003e accept`, or build against CLT:\n\u003e `DEVELOPER_DIR=/Library/Developer/CommandLineTools ./scripts/bundle.sh`.\n\u003e The XCTest suite needs full Xcode; a toolchain-independent check is\n\u003e `swift run yst-selftest`.\n\n### First launch\n\nOn launch the app:\n\n- **auto-detects** the yabai binary (Homebrew Apple Silicon / Intel / nix, then `which`);\n- **auto-registers** the yabai signals it needs (pointing at its own path), so you\n  never edit `~/.yabairc`. This is idempotent — re-running is safe.\n\nThe menu-bar menu shows **yabai: connected ✓** when it found yabai, then a live\nlist of every window grouped by **Display → Space** (the focused window is\nchecked). Spaces show their custom yabai label if set (`yabai -m space --label`),\notherwise \"Space N\". Clicking a window jumps to its space and focuses it. It also\noffers:\n\n- **Settings…** — a window to adjust style (icon/flag), indicator size, focused/\n  unfocused opacity, flag color, background pill + color, \"keep inside window gap\",\n  full-width side, **Debounce (ms)** / **Poll interval (ms)**, **yabai path**\n  (blank = auto-detect; a manual escape hatch if detection fails), and **Start at\n  login**. Changes apply live and are saved.\n- **Re-register yabai signals** — re-applies the signals if yabai was restarted.\n\n\u003e First launch of an unsigned app: macOS Gatekeeper will block it once. Right-click\n\u003e the app → **Open**, or run `xattr -dr com.apple.quarantine yabai-dockstack.app`.\n\u003e To remove this step entirely you'd need an Apple Developer ID signature +\n\u003e notarization.\n\n\u003e Move `yabai-dockstack.app` to `/Applications` before enabling **Start at login**\n\u003e so the login item points at a stable location.\n\n### Manual setup (optional / fallback)\n\nIf you prefer to manage signals yourself (e.g. persisted in your dotfiles), the\nlegacy helpers are still provided: `examples/yabairc-signals.sh` (set `BIN`, source\nfrom `~/.yabairc`) and `examples/com.yabai-dockstack.agent.plist` (a LaunchAgent).\nYou don't need these for the default flow.\n\n## Configuration\n\nOptional config file at `~/.config/yabai-dockstack/config.json`. Any omitted key\nfalls back to its default. All keys:\n\n```json\n{\n  \"yabaiPath\": \"/opt/homebrew/bin/yabai\",\n  \"socketPath\": \"/tmp/yabai-dockstack.sock\",\n  \"style\": \"icon\",\n  \"cellSize\": 32,\n  \"offset\": 4,\n  \"focusedAlpha\": 1.0,\n  \"unfocusedAlpha\": 0.4,\n  \"debounceSeconds\": 0.05,\n  \"pollSeconds\": 3.0,\n  \"fullWidthSide\": \"left\",\n  \"edgeInset\": 6,\n  \"flagColor\": \"#4C8DFF\"\n}\n```\n\n- `fullWidthSide`: which edge the indicator goes to for a near-full-width window\n  (≥90% of the screen), where there's no clear left/right bias. `\"left\"` (default)\n  or `\"right\"`. Narrower windows still follow their on-screen position.\n- `edgeInset`: extra pixels to keep the indicator off the very screen edge when it\n  would otherwise clamp there (so it doesn't sit on a window's rounded corner).\n- `flagColor`: flag-mode bar color, `\"#RRGGBB\"` or `\"#RRGGBBAA\"`.\n- `showBackground`: draw a rounded backing pill behind the indicators so they read\n  as a floating chip (helpful over full-width windows). `true`/`false`.\n- `backgroundColor`: backing pill color, `\"#RRGGBB\"` / `\"#RRGGBBAA\"`.\n\nMost of these are adjustable from **Settings…** in the menu bar (no file editing\nneeded). The config file is still created automatically on first launch at\n`~/.config/yabai-dockstack/config.json` for anyone who prefers editing by hand.\n- `debounceSeconds`: lower = snappier focus highlight, higher = fewer redraws\n  during window drags.\n\n- `style`: `\"icon\"` or `\"flag\"`. The menu-bar \"Toggle icon/flag\" item flips this\n  and writes it back to the config file.\n- `debounceSeconds`: minimum interval between redraws when events arrive in a\n  burst.\n- `pollSeconds`: low-frequency fallback refresh, in case a signal is missed.\n\nUse **Reload config** in the menu after editing the file by hand.\n\n## How it works\n\n```\nyabai window event ──▶ ~/.yabairc signal runs: yabai-dockstack --refresh\n                                                    │ (pokes unix socket)\n                                                    ▼\n                       SignalListener ──▶ RefreshCoordinator (debounced)\n                                                    │\n                          yabai -m query --windows  ▼\n                       StackBuilder ──▶ IndicatorLayout + CoordinateMapper\n                                                    │\n                                          OverlayRenderer (one NSPanel per stack)\n```\n\nA low-frequency timer also triggers a refresh as a safety net. Focusing a window\nis delegated to `yabai -m window --focus`, so the app itself needs no\nAccessibility permission.\n\n## Testing\n\n- **Toolchain-independent self-test** (works with Command Line Tools), covering\n  decode, stack grouping, layout, coordinate mapping, config, diffing, and the\n  socket round-trip:\n  ```sh\n  swift run yst-selftest\n  ```\n  Pass a captured query to exercise the live decode path:\n  ```sh\n  yabai -m query --windows \u003e /tmp/q.json \u0026\u0026 swift run yst-selftest /tmp/q.json\n  ```\n- **Full XCTest suite** (requires Xcode):\n  ```sh\n  swift test\n  ```\n- **Replay mode** — render indicators from a static JSON dump without live yabai,\n  for visual checks:\n  ```sh\n  .build/debug/yabai-dockstack --replay Tests/YabaiDockstackKitTests/Fixtures/query-sample.json\n  ```\n\n## Acceptance checklist\n\n1. `./scripts/bundle.sh` produces `yabai-dockstack.app`.\n2. `open yabai-dockstack.app` → a `▦` item appears in the menu bar; the menu shows\n   **yabai: connected ✓** (signals were auto-registered — verify with\n   `yabai -m signal --list | grep yabai-dockstack`).\n3. Create a stack: `yabai -m window --stack next`.\n5. Icons appear beside the stacked window, top→bottom in stack order; the focused\n   window's icon is brightest.\n6. Hover an icon → a tooltip shows that window's title (multiple VSCode windows\n   show distinct project names).\n7. Click a non-focused icon → that window comes to front; highlight updates.\n8. Menu bar → **Toggle icon/flag** switches appearance and persists it.\n9. On a second display, indicators appear correctly placed on that screen.\n10. LaunchAgent makes it start at login.\n\n## Dock window previews\n\nHover a **Dock app icon** to pop up that app's windows across all spaces; click one\nto jump to its space and focus it (like a Windows-taskbar peek / DockView).\n\n- **Thumbnails:** a live thumbnail is shown for windows on a currently-visible\n  space. For windows on **other spaces** macOS cannot produce a live image\n  (verified: ScreenCaptureKit returns `-3811` for off-screen windows), so the app\n  shows the **last cached thumbnail** (captured while the window was on-screen) or,\n  if none, the **app icon + title**. Either way the entry is clickable.\n- **Permissions:** this feature needs **Accessibility** (to detect the hovered\n  Dock icon) and **Screen Recording** (to capture thumbnails). Open **Settings →\n  Permissions**: it shows each permission's live status (✓ / ✗) with a **Grant…**\n  button that requests the permission and opens the exact System Settings pane —\n  one at a time, so the two prompts don't collide. Once Accessibility is granted\n  the feature activates automatically (no relaunch). If a permission is missing it\n  stays dormant — the core stack indicators need no permissions at all.\n- **Toggle:** Settings → **Dock window previews** (on by default).\n\n## Is it safe? (signing \u0026 permissions)\n\nyabai-dockstack is open-source (MIT) and free. It is **intentionally not signed\nwith a paid Apple Developer ID nor notarized** — that costs $99/yr and this is a\ncommunity project, not a paid product. Consequences and what that means for you:\n\n- **Gatekeeper warns on first open.** Open it once via right-click → **Open**,\n  or System Settings → Privacy \u0026 Security → **Open Anyway**, or\n  `xattr -dr com.apple.quarantine /Applications/yabai-dockstack.app`. The Homebrew\n  cask strips quarantine for you, so `brew install --cask` just opens.\n- **Don't want to trust a prebuilt binary?** Build it yourself:\n  `./scripts/bundle.sh`. It's a few hundred lines of Swift you can read end to end.\n- **No network, no analytics, no phone-home.** It only shells out to your local\n  `yabai` and (for previews) captures windows locally.\n\n**Permissions — only what each feature needs:**\n\n| Feature | Permissions |\n|---|---|\n| Stack indicators + cross-space window menu | **none** (just `yabai -m query` / `--focus`) |\n| Dock window previews | **Accessibility** (detect the hovered Dock icon) + **Screen Recording** (window thumbnails) |\n\nIf you don't use Dock previews, you can grant nothing at all. Permissions are\nrequested only when that feature is enabled, and the app stays functional without\nthem.\n\n## App icon\n\nThe icon lives in `assets/`. Two variants are generated from\n`assets/icon-source.png`:\n\n- `AppIcon-native.icns` — content padded on a transparent canvas with rounded\n  corners (macOS HIG style). **This is the bundled default** (`AppIcon.icns`).\n- `AppIcon-fullbleed.icns` — the source as-is, square corners.\n\nSee `assets/icon-preview.png` for a side-by-side. To switch the bundled icon to\nfull-bleed, copy `assets/AppIcon-fullbleed.icns` over `assets/AppIcon.icns` and\nrebuild. To regenerate everything after editing the source:\n\n```sh\npython3 scripts/make-icons.py   # requires Pillow + macOS iconutil\n```\n\n\u003e Note: the name/logo use \"yabai\". This is an **unofficial** community tool and is\n\u003e not affiliated with the yabai project.\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fz20240%2Fyabai-dockstack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fz20240%2Fyabai-dockstack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fz20240%2Fyabai-dockstack/lists"}