Manual
Azimuth is a menu-bar window manager for macOS. It places, transforms, and moves the focused standard window predictably — using the keyboard, without scenes or automation.
Predictability over clever inference.
Requirements
Four things to know before using Azimuth.
Accessibility permission
Azimuth controls windows via the Accessibility API. Enable it in System Settings → Privacy & Security → Accessibility → toggle Azimuth on. You will be prompted on first launch.
Running Azimuth
Download the DMG from the releases page and drag Azimuth to Applications — no build tools required. The release is Developer ID–signed and notarized, so it opens without Gatekeeper warnings.
Target window
Azimuth operates on the focused standard window (AXStandardWindow). Full-screen spaces and special windows such as sheets and panels are intentionally skipped with clear failure feedback.
Target app policy
Commands act on the most recently active non-Azimuth app's focused window. Opening Azimuth's own Settings window does not change the target — your previous working app remains the target.
Feature summary
All implemented and planned capabilities, grouped by area.
| Area | Feature | Status |
|---|---|---|
| App shell | Menu-bar app + Dock hidden (release) + Settings window | ✅ |
| Permissions | Accessibility status display, request, and Settings navigation | ✅ |
| Window identification | Resolve focused standard window; skip special/full-screen/unfocused | ✅ |
| Command | Maximize to work area (or with uniform gaps) | ✅ |
| Command | Absolute thirds (1/3): horizontal left/center/right · vertical top/middle/bottom | ✅ |
| Command | Absolute two-thirds (2/3): horizontal left/right · vertical top/bottom | ✅ |
| Command | Snap + throw to adjacent display (snapThrow, left/right/up/down) | ✅ |
| Command | Move keep-size (left/right/up/down) · center | ✅ |
| Command | Relative shrink 1/2 & 2/3 (left/right/up/down edge pinned) | ✅ |
| Command | Move to next display (keep shape; moveToDisplay) | ✅ |
| Command | Undo (1 step per window) | ✅ |
| Coordinates | Multi-monitor support + position-aware adjacent display selection | ✅ |
| Input | Global hotkeys (Carbon) · Standard / Vim presets | ✅ |
| Settings | Preset selection / failure beep toggle / launch at login | ✅ |
| Settings | Per-command shortcut customization + conflict warnings | ✅ |
| Settings | Command group on/off · per-command unbind · hide menu-bar icon | ✅ |
| Settings | Updates: current version + Check for Updates… | ✅ |
| Updates | Automatic updates (Sparkle): checks the appcast, verifies EdDSA + notarization, updates in place | ✅ |
| Stability | AX messaging timeout · transient failure skip · permission cache hardening | ✅ |
| Planned | Anchor: position current window relative to another window | 🟡 |
| Planned | Scene save/restore, per-app default positions | 🟡 |
| Planned | URL scheme / Shortcuts / per-app rules | 🟡 |
Shortcuts — all 34 commands
Four modifier layers, each governing a distinct class of behavior. The layers never overlap.
| Group | Command | Shortcut (Standard) |
|---|---|---|
| Halves (snap + throw) | Left | ⌃⌥← |
| Right | ⌃⌥→ |
|
| Top | ⌃⌥↑ |
|
| Bottom | ⌃⌥↓ |
|
| Maximize · Undo · Center | Maximize | ⌃⌥↩ |
| Maximize with gaps | ⌃⌥⇧↩ |
|
| Undo | ⌃⌥⌫ |
|
| Center | ⌃⌥C |
|
| Thirds (1/3) | Horizontal: left · center · right | ⌃⌥123 |
| Vertical: top · middle · bottom | ⌃⌥456 |
|
| Two-thirds (2/3) | Horizontal: left · right | ⌃⌥78 |
| Vertical: top · bottom | ⌃⌥90 |
|
| Move (keep size) | Left · Right · Up · Down | ⌃⌥⌘←→↑↓ |
| Relative shrink (1/2) | Left · Right · Up · Down | ⌃⌥⇧←→↑↓ |
| Relative shrink (2/3) | Left · Down · Up · Right | ⌃⌥⇧M,./ |
| Move to next display | Left · Right · Up · Down | ⌃⌥⌘⇧←→↑↓ |
H (left) ·
L (right) ·
K (up) ·
J (down), Undo → U.
Maximize, Center, and number shortcuts are identical.
Example: ⌃⌥H (snap left) · ⌃⌥⌘K (move up) · ⌃⌥⇧J (shrink down) · ⌃⌥⌘⇧L (move to right display) · ⌃⌥U (undo).
Command behavior
Precise description of what each command does — what changes, what stays the same, and what the edge cases are.
Fills the work area — the visible region excluding the menu bar and Dock. The window expands to use every pixel available without overlapping system chrome.
Like Maximize, but leaves a uniform 12pt inset on all four sides so the window doesn't touch the screen edges — visual breathing room, tiling-friendly. Falls back to a plain maximize if the work area is too small for the gap.
Positions the window at an exact fraction of the work area. Axes are independent: a horizontal command only changes x/width; a vertical command only changes y/height. Compose freely — apply a horizontal third then a vertical third to land in any corner or center cell.
Two-stage behavior: if the window is not already in that half, it snaps there. If it is already in that half, it is thrown to the adjacent display in the same direction, landing in the opposite half (throw right → lands in the left half of the right display). If there is no adjacent display in that direction, the window stays in its current half.
Nudges the window by exactly its own width (horizontal) or height (vertical), with no resize and no display change. Clamped at the work-area boundary — repeat presses push the window to the edge and keep it flush. If the window is larger than the work area, it is pinned to the top-left corner.
Moves the window to the center of the work area without changing its size.
Shrinks the window to 1/2 (arrows) or 2/3 (M , . / → left/down/up/right, like Vim HJKL) of its current size relative to a pinned edge — not the screen. The edge in the given direction is fixed; the opposite edge moves inward. Exact, repeatable, and composable: 2/3 then 1/2 lands on 1/3.
Sends the window to the adjacent display in the given direction while preserving its relative position and proportional size on the new screen. The size is capped so it never exceeds the target work area, and the position is clamped to fit. If there is no adjacent display in that direction, the window stays put.
Restores the window's previous frame — one step per window. History is discarded if the display configuration changes (e.g., a monitor is connected or disconnected), since absolute coordinates become invalid.
When a command cannot complete, Azimuth plays a beep (configurable in Settings). Transient failures — such as those caused by a Space transition or a window animation in progress — are silently skipped without a beep, since they self-resolve immediately.
Roadmap
Planned work, in order of priority.
| Stage | Description | Status |
|---|---|---|
| P8 / v1 | Regression testing across representative apps (Finder / Safari / Terminal / VS Code / Xcode), failure case collection and stabilization — v1 release gate | ✅ Shipped / stable |
| Hardening | DisplayResolver: edge-based adjacency detection for asymmetric monitor layouts | ⏸ Deferred |
| v1.5+ | Anchor: snap or size-match the current window to another window on the same display | 🟡 |
| v2 | Workspaces: per-app default positions, named scene save/restore, monitor-aware scenes | 🟡 |
| v3 | Automation: URL scheme, AppleScript/Shortcuts actions, per-app rules, edge stash/pin | 🟡 |