{"id":49092284,"url":"https://github.com/dot-fun/windowkit","last_synced_at":"2026-04-20T19:01:48.823Z","repository":{"id":352667200,"uuid":"1216120272","full_name":"Dot-Fun/windowkit","owner":"Dot-Fun","description":"Free, open-source macOS window manager with a 3×3 keyboard grid and multi-tap cycles. A Spectacle, Rectangle, Magnet, and Moom alternative. Apache 2.0.","archived":false,"fork":false,"pushed_at":"2026-04-20T17:27:43.000Z","size":802,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-20T17:37:21.326Z","etag":null,"topics":["accessibility-api","apple-silicon","dotfun","hotkeys","keyboard-shortcuts","macos","macos-app","magnet-alternative","menubar","moom-alternative","open-source","productivity","rectangle-alternative","spectacle-alternative","swift","swiftui","tiling-window-manager","window-manager"],"latest_commit_sha":null,"homepage":"https://dotfun.co","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dot-Fun.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-04-20T15:32:13.000Z","updated_at":"2026-04-20T17:28:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Dot-Fun/windowkit","commit_stats":null,"previous_names":["dot-fun/windowkit"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/Dot-Fun/windowkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dot-Fun%2Fwindowkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dot-Fun%2Fwindowkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dot-Fun%2Fwindowkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dot-Fun%2Fwindowkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dot-Fun","download_url":"https://codeload.github.com/Dot-Fun/windowkit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dot-Fun%2Fwindowkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32061251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["accessibility-api","apple-silicon","dotfun","hotkeys","keyboard-shortcuts","macos","macos-app","magnet-alternative","menubar","moom-alternative","open-source","productivity","rectangle-alternative","spectacle-alternative","swift","swiftui","tiling-window-manager","window-manager"],"created_at":"2026-04-20T19:01:12.300Z","updated_at":"2026-04-20T19:01:48.797Z","avatar_url":"https://github.com/Dot-Fun.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003e\n  \u003ca href=\"https://dotfun.co\"\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs/images/DotfunLogoDark.png\"\u003e\n      \u003cimg src=\"docs/images/DotfunLogo.png\" alt=\"dotfun\" height=\"32\" align=\"absmiddle\"\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n  \u0026nbsp;WindowKit — a free, open-source macOS window manager\n\u003c/h1\u003e\n\n\u003e A **free, open-source macOS window manager** with a spatial **3×3 keyboard grid** and **multi-tap cycles**. Snap, resize, and tile windows on your Mac with global keyboard shortcuts — a modern **Spectacle, Rectangle, Magnet, and Moom alternative**, built natively for **Apple Silicon** and licensed under **Apache 2.0**.\n\n[![Latest release](https://img.shields.io/github/v/release/Dot-Fun/windowkit?label=download\u0026color=F7531F)](https://github.com/Dot-Fun/windowkit/releases/latest)\n[![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)\n[![macOS 14+](https://img.shields.io/badge/macOS-14+-black?logo=apple)](#requirements)\n[![Built with Swift](https://img.shields.io/badge/Swift-5.9-orange?logo=swift)](#project-layout)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/images/dotfun-windowkit-menu.png\" alt=\"WindowKit macOS menubar window manager — menu dropdown\" width=\"300\" /\u003e\n  \u0026nbsp;\u0026nbsp;\n  \u003cimg src=\"docs/images/dotfun-windowkit-preferences.png\" alt=\"WindowKit Preferences — keyboard shortcut window snapping for Mac\" width=\"420\" /\u003e\n\u003c/p\u003e\n\n## Why WindowKit?\n\nWindowKit is a lightweight **menubar app for macOS** that snaps the focused window to halves, quadrants, thirds, sixths, a 3×3 spatial grid, or fullscreen — all with keyboard shortcuts. If you've used [Spectacle](https://github.com/eczarny/spectacle), [Rectangle](https://rectangleapp.com), [Magnet](https://magnet.crowdcafe.com), [BetterSnapTool](https://folivora.ai/bettersnaptool), or [Moom](https://manytricks.com/moom/), WindowKit will feel familiar — with a spatial-grid twist that is unique to it.\n\n- **Free \u0026 open source** — Apache 2.0 licensed, no paywall, no telemetry, no account required.\n- **3×3 spatial grid** — `U / I / O`, `J / K / L`, `M / , / .` map to the 9 screen positions. The keys' physical layout *is* the layout of the snap targets.\n- **Multi-tap cycles** — tap the same shortcut twice/thrice/four times to progressively enlarge the window at that anchor. `⌘⌥I` once = top-center 1/9; twice = top 1/3; three times = top 1/2; four times = top 2/3.\n- **Apple Silicon native** — arm64 build for M1 / M2 / M3 / M4 Macs on macOS 14 Sonoma or later.\n- **Works with Electron apps** — Chrome, Discord, Cursor, VSCode, Slack. A one-time `AXEnhancedUserInterface` nudge per app per launch handles Chromium's usual Accessibility API quirks.\n- **Dock-aware placement** — windows never cover a pinned Dock. Auto-hide Dock is handled the way macOS expects.\n- **Configurable tap window** — 150 ms – 1 s in Preferences, default 700 ms.\n\n## Compared to other macOS window managers\n\n| | **WindowKit** | Spectacle | Rectangle | Magnet | Moom |\n|---|:---:|:---:|:---:|:---:|:---:|\n| Free | ✅ | ✅ | ✅ | ❌ ($4.99) | ❌ ($10) |\n| Open source | ✅ Apache 2.0 | ✅ (archived 2017) | ✅ MIT | ❌ | ❌ |\n| Halves / quadrants via keyboard | ✅ | ✅ | ✅ | ✅ | ✅ |\n| Thirds / sixths / 2/3 bands | ✅ | ➖ limited | ✅ | ✅ | ✅ |\n| **Spatial 3×3 grid** (U/I/O, J/K/L, M/,/.) | ✅ | ❌ | ❌ | ❌ | ➖ custom grid |\n| **Multi-tap cycles** | ✅ | ❌ | ➖ repeat-resize | ❌ | ❌ |\n| Drag-to-snap | ❌ | ❌ | ✅ | ✅ | ✅ |\n| App-specific rules | ❌ | ❌ | ➖ | ❌ | ✅ |\n| Native Apple Silicon | ✅ | ❌ (unmaintained) | ✅ | ✅ | ✅ |\n| Menubar-only, no Dock icon | ✅ | ✅ | ✅ | ✅ | ✅ |\n\nUse **Rectangle** if you love drag-to-snap. Use **Magnet** or **Moom** if you want paid-app polish and mouse gestures. Use **WindowKit** if you live on the keyboard and want the spatial-grid mental model.\n\n**License**: Apache 2.0 — see [`LICENSE`](LICENSE). Provided \"as is\", without warranty of any kind, express or implied. The authors and dotfun are not liable for any damages arising from use of this software.\n\n## Install (prebuilt)\n\n1. Grab the latest **WindowKit-x.y.z.zip** from [Releases](https://github.com/Dot-Fun/windowkit/releases).\n2. Unzip, drag **WindowKit.app** into **/Applications**.\n3. Launch it. The menubar icon (orange 3×3 grid on dotfun orange) appears.\n4. On first launch Gatekeeper will complain — the build is unsigned. Right-click the app → **Open** → **Open Anyway**, or run:\n   ```bash\n   xattr -dr com.apple.quarantine /Applications/WindowKit.app\n   ```\n5. Grant Accessibility when prompted (System Settings → Privacy \u0026 Security → Accessibility → toggle WindowKit on).\n\n### Menubar menu\n\n- **Preferences…** — rebind shortcuts, adjust the multi-tap window (150 ms – 1 s, default 700 ms)\n- **About WindowKit** — logo + version\n- **Launch at Login** — toggle auto-start with macOS\n- **Debug → Copy Focused Window Info** — copies bundle ID / AX role / settable flags to the clipboard for bug reports\n- **Quit WindowKit** — ⌘Q\n\n## Requirements\n\n- macOS 14+\n- Swift 5.9+ / Xcode 15+\n- Accessibility permission (for moving windows of other apps)\n\n## Build\n\n```bash\nswift build -c release\n```\n\nOr open `Package.swift` in Xcode and build the `WindowKit` scheme.\n\n### Package as .app\n\n```bash\nscripts/build-app.sh\n```\n\nProduces `build/WindowKit.app`. Double-click to launch; a menu-bar icon appears (the app is `LSUIElement`, no Dock presence).\n\n## Run (dev)\n\n```bash\nswift run WindowKit\n```\n\n## Test\n\n```bash\nswift test\n```\n\n## Default Hotkeys\n\nLegend: ⌃ = Control, ⌥ = Option, ⌘ = Command, ⇧ = Shift.\n\n### Halves\n| Action | Shortcut |\n|---|---|\n| Left half | ⌃⌥ ← |\n| Right half | ⌃⌥ → |\n| Top half | ⌃⌥ ↑ |\n| Bottom half | ⌃⌥ ↓ |\n\n### Quadrants\n| Action | Shortcut |\n|---|---|\n| Top-left | ⌃⌥ 1 |\n| Top-right | ⌃⌥ 2 |\n| Bottom-left | ⌃⌥ 3 |\n| Bottom-right | ⌃⌥ 4 |\n\n### Thirds\n| Action | Shortcut |\n|---|---|\n| First third | ⌃⌥⌘ ← |\n| Center third | ⌃⌥⌘ ↑ |\n| Last third | ⌃⌥⌘ → |\n\n### 3×3 Spatial Grid (⌘⌥ + key)\nKeys mirror the cell's on-screen position:\n\n```\nU I O\nJ K L\nM , .\n```\n\n| Action | Shortcut |\n|---|---|\n| Top-left | ⌘⌥ U |\n| Top-center | ⌘⌥ I |\n| Top-right | ⌘⌥ O |\n| Middle-left | ⌘⌥ J |\n| Middle-center | ⌘⌥ K |\n| Middle-right | ⌘⌥ L |\n| Bottom-left | ⌘⌥ M |\n| Bottom-center | ⌘⌥ , |\n| Bottom-right | ⌘⌥ . |\n\n### Sizing\n| Action | Shortcut |\n|---|---|\n| Fullscreen | ⌃⌥ F |\n| Center | ⌃⌥ C |\n| Almost maximize (90%) | ⌃⌥ = |\n\n### History\n| Action | Shortcut |\n|---|---|\n| Undo window change | ⌃⌥ Z |\n| Redo | ⌃⌥⇧ Z |\n\n### Displays\n| Action | Shortcut |\n|---|---|\n| Move to next display | ⌃⌥⌘ ] |\n| Move to previous display | ⌃⌥⌘ [ |\n\nAll shortcuts are configurable in **Preferences → Keyboard Shortcuts** (⌘, from the menu bar).\n\n### Multi-tap cycles\n\nEach 3×3 grid key starts a cycle. Tapping the same key again within the **tap window** (default 700 ms, configurable 150 ms – 1 s in **Preferences → Shortcuts → Tap Behavior**) advances to a larger size anchored at that position. After the last step, another tap wraps back to the 1/9 cell. After the tap window elapses with no press, the counter resets and the next tap is a 1-tap again.\n\n| Position | Keys | Cycle (1-tap → last) |\n|---|---|---|\n| Corners | U, O, M, . | 1/9 cell → matching quadrant (1/2 × 1/2) → 2/3 × 2/3 anchored at that corner |\n| Top / bottom edges | I, , | 1/9 cell → top/bottom 1/3 band → top/bottom 1/2 → top/bottom 2/3 |\n| Side edges | J, L | 1/9 cell → left/right 1/3 column → left/right 1/2 → left/right 2/3 |\n| Center | K | 1/9 cell → 1/3 center column → fullscreen |\n\nTapping a *different* key resets the cycle — each key tracks its own counter.\n\n### Known behaviors\n\n- **Non-resizable apps** (e.g. System Settings panels) will be **moved** to the target location but keep their intrinsic size. WindowKit does not beep or error on move-only outcomes.\n- **The Dock is respected** — snapped windows will not overlap a pinned Dock. The target frame is computed against `NSScreen.visibleFrame`, which excludes the Dock and menu bar.\n- **Auto-hide Dock** lets windows use the full screen; the Dock overlays on hover (standard macOS behavior).\n\n## Permissions\n\nWindowKit requires **Accessibility** access to query and set frames of other apps' windows via `AXUIElement`. Without it, no hotkeys will take effect. On first launch the app shows an onboarding window with a button that opens **System Settings → Privacy \u0026 Security → Accessibility**.\n\n### Unsigned-build caveat\n\nBecause this build is unsigned (and ad-hoc signatures change on every rebuild), macOS treats each new build of `WindowKit.app` as a distinct identity for Accessibility purposes. **After every rebuild you must:**\n\n1. Open **System Settings → Privacy \u0026 Security → Accessibility**.\n2. Remove any stale `WindowKit` entry.\n3. Add the freshly built `WindowKit.app` and enable its toggle.\n\nThe onboarding window reappears whenever trust is revoked or invalidated, and hotkeys automatically disarm until trust is restored.\n\n## Known app compatibility\n\n- **Fully supported**: all native Cocoa apps (Finder, Safari, iTerm, Xcode, Terminal, Preview, Mail, Messages, etc.).\n- **Electron / Chromium apps** (Chrome, Discord, Cursor, VSCode, Slack, etc.): supported via a multi-tier window resolver and a one-time `AXEnhancedUserInterface` nudge per app per launch. The first hotkey press on such an app may feel ~30 ms slower while Chromium rebuilds its AX tree; subsequent presses are instant.\n- **Fixed-size apps** (EMEET Studio, System Settings panels, 1Password mini, Spotify mini): these will be **moved** to the target cell's origin but keep their intrinsic size — by design. No beep, no error.\n- **Apps running as root or with full-screen space privileges** (most games, some installers): unreachable via the Accessibility API. This is a macOS limitation, not a WindowKit bug.\n\nIf a specific app doesn't respond, open the menubar menu → **Debug → Copy Focused Window Info** and share the clipboard contents — it contains the bundle ID, AX role/subrole, and which attributes are settable, which is enough to triage.\n\n## FAQ\n\n### Is WindowKit a free Spectacle alternative?\nYes. Spectacle stopped receiving updates in 2017. WindowKit keeps the same spirit — a keyboard-first, menubar-only Mac window manager — and adds a spatial 3×3 grid with multi-tap cycles to snap windows on Mac in one or more presses. Apache 2.0, no paywall, no telemetry.\n\n### How does WindowKit compare to Rectangle?\nRectangle is the most popular modern Spectacle fork and is excellent if you love drag-to-snap. WindowKit has a smaller surface area — no mouse snapping, no app-specific rules — but it ships the spatial 3×3 grid (`U/I/O`, `J/K/L`, `M/,/.`) and multi-tap cycles that Rectangle doesn't. Both are free and open source. Pick whichever matches your mental model; they don't strictly conflict (though you may want to disable overlapping hotkeys in one of them).\n\n### Does WindowKit work on Apple Silicon (M1, M2, M3, M4)?\nYes. The release binary is arm64-native, compiled against the macOS 14 SDK.\n\n### Which macOS versions are supported?\nmacOS 14 Sonoma and later (Sonoma, Sequoia, and newer). Earlier versions are not supported — SwiftUI's `MenuBarExtra` requires macOS 13+ and some Accessibility APIs we rely on need Sonoma.\n\n### Does WindowKit work with Chrome, Discord, Cursor, VSCode, or Slack?\nYes. Chromium/Electron apps get a one-time `AXEnhancedUserInterface` nudge from WindowKit the first time you press a hotkey on them per launch — after that, frame changes work as expected. The first press on a Chromium app is ~30 ms slower while it rebuilds its Accessibility tree; subsequent presses are instant.\n\n### Why does WindowKit need Accessibility permission?\nmacOS requires Accessibility access for any app that reads or moves other apps' windows. This is the same permission Spectacle, Rectangle, Magnet, BetterSnapTool, and Moom all require. WindowKit only uses it to set window position and size — no keystroke logging, no screen recording, no network calls.\n\n### Is WindowKit a Magnet or Moom alternative?\nYes, functionally. Magnet and Moom are polished paid apps (roughly $5 – $10 on the Mac App Store); WindowKit is free and open source. If you want drag-to-snap edges or app-specific autolayout rules, Magnet or Moom are still better choices. If you want keyboard-first minimalism, WindowKit is the lightest option.\n\n### What's different about the 3×3 grid and multi-tap cycles?\nMost window managers think in halves and quadrants. WindowKit adds a third mental tier: nine positional cells whose keyboard shortcuts are arranged *spatially* — the letters' physical position on your keyboard matches the cell's position on screen. Holding `⌘⌥` and pressing `M` snaps the window to the bottom-left 1/9; pressing `M` a second time within the tap window grows it to the bottom-left 1/4 quadrant; a third tap grows it to 2/3 × 2/3 in that corner. Center-row keys `I`, `K`, `,` grow in bands and columns.\n\n### Where's the source? Can I contribute?\nAll of WindowKit is in this repository under Apache 2.0. Issues and PRs welcome. See [Project Layout](#project-layout) for the module map.\n\n## Project Layout\n\n- `App/` — SwiftUI `@main` app (MenuBarExtra), `ActionRunner`, `Info.plist`, assets\n- `Sources/WindowEngine/` — pure `Geometry`, `AXWindow` wrapper, `ScreenResolver`, coordinate converter\n- `Sources/HotkeyManager/` — Carbon global hotkeys\n- `Sources/PreferencesStore/` — `Shortcut` model, `UserDefaults` persistence, default bindings\n- `Sources/PreferencesUI/` — Preferences window, shortcut recorder, onboarding\n- `Sources/PermissionsCoordinator/` — Accessibility trust checks + publisher\n- `Sources/UndoStack/` — window frame history\n- `Tests/WindowEngineTests/` — geometry unit tests\n- `Tests/PreferencesStoreTests/` — store/shortcut tests\n- `scripts/build-app.sh` — release bundle assembly\n\n## Distribution\n\nUnsigned local build. Not notarized. See unsigned-build caveat above.\n\n## Release history\n\n- **v0.2.4** — Corner keys (U, O, M, .) gain a 3rd tap: 2/3 × 2/3 in that corner.\n- **v0.2.3** — `⌘⌥K` cycle adds a 1/3-wide center column between the 1/9 cell and fullscreen.\n- **v0.2.2** — Works with Chromium/Electron apps (Chrome, Discord, Cursor, VSCode, Slack) via a one-time `AXEnhancedUserInterface` nudge. Tap window default raised to 700 ms; slider ceiling raised to 1 s.\n- **v0.2.1** — dotfun branding, stale-grant detection, Launch at Login via `SMAppService`, Apache 2.0 LICENSE.\n\nFull list on the [Releases page](https://github.com/Dot-Fun/windowkit/releases).\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://dotfun.co\"\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs/images/DotfunLogoDark.png\"\u003e\n      \u003cimg src=\"docs/images/DotfunLogo.png\" alt=\"dotfun\" height=\"28\"\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdot-fun%2Fwindowkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdot-fun%2Fwindowkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdot-fun%2Fwindowkit/lists"}