OmniWM
OmniWM is a free, open-source, Developer ID-signed and Apple-notarized tiling window manager for Apple Silicon Macs running macOS 26 or later. It combines Niri-style orientation-aware scrolling containers and Hyprland-style Dwindle BSP layouts, selectable per workspace, with multi-monitor routing and optional local CLI/IPC automation.
Website · Documentation · Install · Compatibility
Demo Video
Contributors
Thank you to everyone who contributed to OmniWM. Your ideas and code made a real difference.
🏢 By Employer
|
Bitkey ━━━━━━━━
Naoki Ikeguchi @siketyan |
BlueLabs ━━━━━━━━
Cristian Álvarez Belaustegui @crbelaus |
EPAM ━━━━━━━━
Aleksei Gurianov @Guria |
Finanzguru ━━━━━━━━
Janek Thomaschewski @jthomaschewski |
GitHub ━━━━━━━━
Ryan Hecht @RyanHecht |
━━━━━━━━
muhammadkh @MuhammadKh |
Luxor Labs ━━━━━━━━
Albert Ilagan @albertilagan |
Nx ━━━━━━━━
Steven Nance @llwt |
ReactSquad ━━━━━━━━
Jan Hesters @janhesters |
Spotify ━━━━━━━━
Alexander Dergachev @Cy6erBr4in |
SSW Consulting ━━━━━━━━
Matt Wicks @wicksipedia |
vhf ━━━━━━━━
Lukas Gerlinski @lgerlinski |
Viber ━━━━━━━━
Yuri Chukhlib @YuriNachos |
🎓 By Education
|
Assumption University of Thailand ━━━━━━━━
Panuphong Burakitphachai @t1dotdev |
Linnaeus University ━━━━━━━━
Balazs Hevesi @balazshevesi |
NTU Singapore ━━━━━━━━
Nawat Suangburanakul @holmns |
Olin College of Engineering ━━━━━━━━
Cypress Frankenfeld @cypressf |
SUSTech ━━━━━━━━
Yang-Yiming @Yang-Yiming |
✨ All Contributors
|
Highlights
- Ghostty-powered quake/sticky terminal
- Native macOS window-tab support
- Local IPC and
omniwmctlautomation - Scratchpads and sticky windows for any app
- Overview
- Unified command palette for windows and app menus
- Menu Anywhere
- Niri-style tabbed containers and Dwindle tile groups
- Niri-style scrolling and Hyprland-style Dwindle BSP layouts
- Status-bar icon concealment (similar to Ice)
- Keep Awake (similar to Caffeine)
- Interactive workspace and app-icon bar
- Many more features not shown in the video.
Compatibility and Limitations
OmniWM requires Apple Silicon, macOS 26 or later, Accessibility, Input Monitoring, and Displays have separate Spaces. Screen Recording is optional. Read the complete Compatibility, Requirements & Limitations page before installing.
- Dwindle restore scope — After a restart OmniWM rebuilds each Dwindle workspace from the persisted placements: split orientation and ratio, tab-group membership, tab order, and the active tab. Fullscreen state and the selected window are not restored, and once a window without a persisted placement is present, later windows insert normally instead of being placed from the catalog.
- Scratchpad membership — Window membership lasts for the current OmniWM process. Scratchpad labels persist, but memberships do not.
Performance & Trust
OmniWM is built for high responsiveness and smooth, crisp animations.
- Direct macOS integration — OmniWM uses public frameworks and selected Apple private APIs for window management and visual surfaces.
- Refresh-rate-aware animations — Animation pacing follows the active display refresh rate, including 60, 120, and 144 Hz displays.
- SIP stays enabled — Official OmniWM releases do not require disabling System Integrity Protection.
- Signed and notarized releases — Official release builds are Developer ID signed and Apple-notarized.
- Free and open source — OmniWM has no subscriptions, feature paywalls, trial limits, or usage caps and is licensed GPL-2.0-only.
Requirements
- macOS 26+ (Tahoe) on Apple Silicon
- Hidden Bar concealment and optional issue-report rewriting require macOS 27 or later; rewriting also requires enabled Apple Intelligence and an available local model
- Accessibility and Input Monitoring permissions (required at launch)
- Screen Recording permission for Overview thumbnails, drag previews, and captured Hidden Bar glyphs (optional)
- Displays have separate spaces ON (the macOS default; OmniWM pauses window management until it is enabled)
Installation
Homebrew
OmniWM is in the official Homebrew cask repository:
brew install --cask omniwm
This installs OmniWM.app and puts omniwmctl on your PATH.
Upgrading
Quit OmniWM first, then run brew upgrade omniwm and relaunch it. Homebrew replaces the app bundle underneath a running OmniWM.
Migrating from the project tap
BarutSRB/tap is retired: 0.6.7 was its final release, and every later version ships only through the official cask. If you installed from the tap, quit OmniWM and run these commands in this order:
brew update
brew upgrade omniwm
brew untap BarutSRB/tap
brew update has to come first: it fetches the retired tap's redirect to the official cask and moves your install over. Untapping before that would offer to uninstall OmniWM. brew reinstall --cask homebrew/cask/omniwm is optional and only switches the install record to the official cask right away.
Nix
OmniWM is packaged in nixpkgs, maintained by mmfallacy and samiser, and Home Manager ships an official
programs.omniwm module, maintained by DavSanchez. The package installs the signed release artifact with bsdtar, so the Developer ID
signature stays valid, and exposes OmniWM and omniwmctl on PATH. Both currently live on unstable branches
only (the nixpkgs unstable channels and Home Manager master) and may trail the latest GitHub release.
Install the package directly:
nix profile install nixpkgs#omniwm
With nix-darwin or Home Manager, add pkgs.omniwm to environment.systemPackages or home.packages.
For a declarative setup, enable the Home Manager module. It installs the package, runs OmniWM as a launchd
agent, and writes ~/.config/omniwm/settings.toml from an attribute set or a tracked TOML file:
programs.omniwm = {
enable = true;
settings = ./omniwm-settings.toml;
};
Treat the declared TOML file or attribute set as authoritative: edit it and run Home Manager switch to apply
changes. OmniWM preserves settings symlinks, so settings backed by a read-only Nix-store file cannot be saved
from the GUI. Set programs.omniwm.launchd.enable = false if you prefer to start and quit OmniWM manually
instead of having Home Manager manage its launchd agent.
After either installation, complete the macOS setup in steps 3-7 below.
GitHub Releases
- Download the latest
OmniWM-vapp archive from Releases.zip - Extract and move
OmniWM.appto/Applications - In System Settings > Desktop & Dock > Mission Control, turn ON
Displays have separate Spaces - Log out of macOS and log back in for that change to take effect unless you had it on already
- Launch OmniWM and grant Accessibility and Input Monitoring when prompted
- Optionally grant Screen Recording for capture-derived visuals
- Return to OmniWM’s permissions window and click Start OmniWM or Continue Without Screen Recording. If a required permission still appears missing, click Check Again
Updates
OmniWM checks for updates by default.
- On launch, OmniWM polls the latest GitHub release at most once per day.
- Updates stay manual. OmniWM does not auto-download or auto-install a new release.
- When a newer release is available, OmniWM shows a centered popup with release notes and actions for
Open Release Page,Copy brew upgrade omniwm,Skip This Version, andNot Now. - You can control this from
Settings > General > Updatesor trigger a manual check from the status bar menu withCheck for Updates....
Documentation
The canonical documentation hub lives at omniwm.app. This README and the guides follow current main; features newer than the latest release are marked Unreleased.
- Documentation Home
- Layout Modes
- Keyboard Shortcuts
- Architecture Guide
- IPC & CLI Reference
- Contribution Docs
- Canonical Contributing Guide
IPC and CLI
OmniWM ships with a bundled CLI, omniwmctl, for automation and scripting.
IPC is disabled by default. Enable Enable IPC from the menu bar before using the CLI or any automation.
Diagnostics can be scripted with omniwmctl capture start trace, omniwmctl capture start performance, omniwmctl capture stop, and omniwmctl capture status.
For setup, installation options, commands, queries, rules, subscriptions, and security details, see the IPC & CLI Reference.
Quick Start
- Launch OmniWM from your Applications folder
- In System Settings > Desktop & Dock > Mission Control, turn ON
Displays have separate Spaces - Log out of macOS and log back in for that change to take effect unless you had it on already
- Grant Accessibility and Input Monitoring in the launch permissions window, and optionally Screen Recording. Return to that window and click Start OmniWM or Continue Without Screen Recording; use Check Again if a required permission still appears missing
- Windows will automatically tile in orientation-aware Niri containers: monitors using horizontal orientation show columns that scroll left and right, while vertical orientation shows rows that scroll up and down
- Keep one macOS Space per display and navigate with OmniWM workspaces; extra native Spaces are tolerated (their windows are left to macOS, not tiled)
- Use the defaults in Keyboard Shortcuts to navigate, and customize them in
Settings > Hotkeys - Click the menu bar icon to access Settings, including
Settings > General > Updates - Enable
Start at LoginunderSettings > General > Startupto launch OmniWM automatically when you log in - Use
Check for Updates...from the status bar menu whenever you want to run a manual update check - On macOS 27+, if you enable Hidden Bar and selected menu-bar icons disappear, right-click or Option-click OmniWM's menu-bar icon to open the Hidden Icons Bar and click any icon to use it.
User Guide
Multi-Monitor Setup
OmniWM uses two display maps for different jobs:
- Open System Settings > Displays > Arrange. Put the physically largest or widest display at the bottom. Place the next smaller display above and to its right so its bottom-left corner touches the lower display's top-right corner. Continue the same staircase for every additional display. This macOS map is a technical arrangement used for actual window placement; it does not need to look like your desk.
- Open OmniWM Settings > Monitors and arrange the OmniWM routing map to match where the displays really sit on your desk. Tiles can be separated by empty grid cells, but every display must remain connected through a chain of shared rows or columns. A diagonal-only tile is disconnected and cannot exchange directional focus, window moves, or mouse warp.
- Assign at least one workspace to every connected display. Window moves between displays need a destination workspace, so the setup assistant will not finish while a display is uncovered. You can reassign an existing workspace or explicitly add one for that display.
- Leave Mouse Warp turned on for the recommended experience. It lets the pointer cross between displays according to the real-desk OmniWM map even though macOS uses the staircase.
Custom arrangements are remembered for each set of connected displays, so home and work can keep different positions for the same laptop display. Reconnecting a saved set restores its arrangement automatically. If there is no exact match, OmniWM inherits the smallest saved arrangement containing every connected display; an uncovered set or an invalid grid follows macOS. Editing, resetting, or finishing setup saves only the connected set, leaving any larger arrangement unchanged. Simply connecting displays or opening Settings does not save an arrangement. Workspace assignments and other per-monitor settings remain separate.
Move Window Across Monitor at Edge sends a window beyond a workspace edge to the adjacent routed display and always follows it. Dedicated monitor-move actions work independently of this setting and use Follow Window to Monitor, which also controls focus after ordinary window or column transfers to another workspace.
Workspace homes can be Main, Secondary, Tertiary, or a specific display. By default Main is the display with the macOS menu bar and Secondary and Tertiary are the next displays in arrangement order. The Monitor Roles list in Settings > Monitors lets you rank displays instead: the highest-ranked connected display is Main, then Secondary, then Tertiary, and disconnected entries are skipped, so two external displays can hold fixed roles at your desk while the built-in display takes over when you unplug. The Quake terminal's Main Monitor option follows the same ranking.
Layout Modes
OmniWM offers two layout engines that you can switch between per workspace:
Niri (Orientation-Aware Scrolling Containers) - On monitors using horizontal orientation, windows form vertical columns that scroll left and right; in vertical orientation, they form horizontal rows that scroll up and down. Each container can hold multiple windows or be "tabbed" (multiple windows, one visible at a time).
Hyprland Dwindle (BSP) - Binary space partition layout that recursively divides screen space. Each new window splits the space in half, and a tile can group multiple windows as tabs. Best for traditional tiling with predictable layouts.
Use the Toggle Workspace Layout shortcut below to switch layouts per workspace or configure them in GUI settings.
Keyboard Shortcuts
All shortcuts are customizable in Settings > Hotkeys. Hyper is the literal Control + Option + Shift + Command chord by default; which modifiers make up Hyper is configurable in Settings > Hotkeys (for example, exclude Shift to keep Hyper + Shift + … free for extra bindings). Changing the combination retargets every shortcut that currently resolves to Hyper onto the new one, so the shortcut list updates in place as you toggle the modifiers. Optionally pick a System Hyper Trigger — a single key (Caps Lock, F13–F20, or a left- or right-side modifier) or an extra mouse button that acts as Hyper while held (this needs Input Monitoring permission). Leave the trigger as None if you already produce Hyper another way, such as a Karabiner Elements remap. The tables below list all the default hotkeys:
Layout legend:
Sharedworks in any active layout.Niriworks only when the active workspace uses the Niri layout.Dwindleworks only when the active workspace uses the Dwindle layout.
Include Advanced Commands in Settings > Hotkeys to see and bind them; the tables below include both standard and advanced actions.
Workspace
| Action | Default Shortcut | Layout |
|--------|------------------|--------|
| Switch to Workspace 1-9 | Option + 1-9 | Shared |
| Move Window to Workspace 1-9 | Option + Shift + 1-9 | Shared |
| Switch to Workspace Slot 1-9 (position on the current monitor) | Unassigned | Shared |
| Move to Workspace Slot 1-9 (position on the current monitor) | Unassigned | Shared |
| Switch to Last Active Workspace (Back and Forth) | Control + Option + Tab | Shared |
| Switch to Next Workspace | Unassigned | Shared |
| Switch to Previous Workspace (Sequential) | Unassigned | Shared |
| Move Window to Workspace Up | Control + Option + Shift + Up Arrow | Shared |
| Move Window to Workspace Down | Control + Option + Shift + Down Arrow | Shared |
| Move Column to Workspace 1-9 | Unassigned | Niri |
| Move Column to Workspace Up | Control + Option + Shift + Page Up | Niri |
| Move Column to Workspace Down | Control + Option + Shift + Page Down | Niri |
Focus
| Action | Default Shortcut | Layout |
|--------|------------------|--------|
| Focus Left / Right / Up / Down | Option + Arrow Keys | Shared |
| Focus Down or Top / Up or Bottom | Unassigned | Shared |
| Focus Top Window / Bottom Window | Unassigned | Niri |
| Focus Window or Workspace Down / Up | Unassigned | Niri |
| Focus Previous Window | Option + Tab | Shared |
| Traverse Backward | Unassigned | Niri |
| Traverse Forward | Unassigned | Niri |
| Focus First Column | Option + Home | Niri |
| Focus Last Column | Option + End | Niri |
| Focus Column 1-9 | Control + Option + 1-9 | Niri |
| Focus Window 1-9 in Column | Unassigned | Niri |
| Toggle Command Palette | Control + Option + Space | Shared |
| Open Menu Anywhere | Control + Option + M | Shared |
| Close Focused Window | Unassigned | Shared |
| Toggle Workspace Bar | Unassigned | Shared |
| Toggle Hidden Icons Bar | Unassigned | Shared |
| Toggle Quake Terminal | ` Option + ` | Shared |
| Toggle Overview | Option + Shift + O | Shared |
| Toggle System Stats | Unassigned | Shared |
Move Window
| Action | Default Shortcut | Layout |
|--------|------------------|--------|
| Move Left / Right / Up / Down | Option + Shift + Arrow Keys | Shared |
| Reorder Window Up / Down | Unassigned | Shared |
| Move Window Down or to Workspace Down / Up or to Workspace Up | Unassigned | Niri |
| Consume Window into Column / Expel Window from Column | Unassigned | Niri |
Monitor
| Action | Default Shortcut | Layout |
|--------|------------------|--------|
| Focus Next Monitor | Control + Command + Tab | Shared |
| Focus Previous Monitor | Unassigned | Shared |
| Focus Last Monitor | Control + Command + ` | Shared |
| Move Workspace to Left / Right / Up / Down Monitor | Unassigned | Shared |
| Move Window to Left / Right / Up / Down Monitor | Unassigned | Shared |
The workspace-to-monitor actions target the active workspace and intentionally use the same temporary runtime override as omniwmctl workspace move-to-monitor --force. They do not rewrite the workspace's Home Monitor or swap workspaces, and unsafe fullscreen, hidden-app, scratchpad, or focus states still block the move.
The window-to-monitor actions send the focused window directly to the current workspace on the adjacent routed display, independently of Move Window Across Monitor at Edge. The destination display must have at least one assigned workspace, which the Monitor Setup assistant verifies. They do not wrap when no monitor exists in that direction. Follow Window to Monitor controls whether focus follows the window; when it is off, you remain in the source workspace.
Layout
| Action | Default Shortcut | Layout |
|--------|------------------|--------|
| Toggle Fullscreen | Option + Return | Shared |
| Toggle Native Fullscreen | Unassigned | Shared |
| Balance Sizes | Option + Shift + B | Shared |
| Cycle Size Forward | Option + . | Shared |
| Cycle Size Backward | Option + , | Shared |
| Move to Root | Unassigned | Dwindle |
| Toggle Split | Unassigned | Dwindle |
| Swap Split | Unassigned | Dwindle |
| Grow Horizontally / Vertically | Unassigned | Dwindle |
| Shrink Horizontally / Vertically | Unassigned | Dwindle |
| Grow / Shrink Focused Window | Unassigned | Dwindle |
| Preselect Left / Right / Up / Down | Unassigned | Dwindle |
| Clear Preselection | Unassigned | Dwindle |
| Raise All Floating Windows | Option + Shift + R | Shared |
| Rescue Off-Screen Floating Windows | Unassigned | Shared |
| Toggle Focused Window Floating | Unassigned | Shared |
| Assign Focused Window to Scratchpad 1-10 | Unassigned | Shared |
| Toggle Scratchpad 1-10 | Unassigned | Shared |
| Toggle Workspace Layout | Option + Shift + L | Shared |
Container and Column
| Action | Default Shortcut | Layout |
|--------|------------------|--------|
| Move Container Left / Right | Control + Option + Shift + Left / Right Arrow | Shared |
| Move Container Up / Down | Unassigned | Dwindle |
| Toggle Column Tabbed | Option + T | Niri |
| Toggle Container Full Primary Span | Option + Shift + F | Niri |
| Expand Container to Available Primary Span | Control + Option + F | Niri |
| Move Column to First / Last | Control + Option + Home / End | Niri |
| Move Column to Index 1-9 | Unassigned | Niri |
| Set Container Primary Span -10% / +10% | Option + - / Option + = | Niri |
| Set Window Secondary Span -10% / +10% | Option + Shift + - / Option + Shift + = | Niri |
| Set Window Primary Span -10% / +10% | Unassigned | Niri |
| Reset Window Secondary Span | Control + Option + R | Niri |
| Cycle Window Primary Span Forward / Backward | Unassigned | Niri |
| Cycle Window Secondary Span Forward / Backward | Unassigned | Niri |
| Center Column | Unassigned | Niri |
| Center Visible Columns | Unassigned | Niri |
Consume or Expel Window Left / Right exist as automation-only actions. They are reachable from omniwmctl but never appear in Settings > Hotkeys, because they intentionally cannot be bound to a shortcut.
The daily Focus and Move shortcuts adapt to the active layout and Niri orientation. In horizontal Niri orientation, Move Left / Right consumes or expels across columns while Move Up / Down reorders within a column. Vertical orientation rotates those roles: Move Up / Down consumes or expels across rows while Move Left / Right reorders within a row.
Dwindle Groups
Dwindle groups use the existing Focus and Move bindings, so there are no separate group shortcuts to memorize. Only the active member occupies the tile; the other members stay hidden and the clickable tab rail shows their order.
| Goal | Default Shortcut | Behavior |
|------|------------------|----------|
| Focus another tile | Option + Arrow Keys | Left / Right are always spatial. Up / Down are spatial for a singleton tile. |
| Select the next / previous tab | Option + Down / Up Arrow | Within a group, Down advances and Up goes back. At the group edge OmniWM tries a spatial tile, then the configured monitor transition, and wraps locally only when neither exit succeeds. |
| Join a singleton into a tile or group | Option + Shift + Arrow Keys | Joins the focused singleton with the touching tile in that direction. |
| Extract the active tab | Option + Shift + Arrow Keys | When the focused tile is grouped, extracts only its active tab onto the requested side. |
| Move the complete tile or group | Control + Option + Shift + Left / Right Arrow | Move Container swaps the whole structure. Up / Down are advanced, unassigned Dwindle actions. |
| Select an exact tab | Click its tab rail item | Reveals and focuses that member without changing the group order. |
Moving a tab directly from one existing group into another is intentionally a two-step operation: extract it first, then move the resulting singleton toward the destination group. A singleton at a genuine workspace edge can still use the normal cross-monitor Move behavior; a rejected group mutation does not fall through to tile swapping or monitor movement.
The unassigned advanced actions are available in Settings > Hotkeys. Focus Down or Top / Up or Bottom always wraps within the active Niri column or Dwindle group. Reorder Window Up / Down changes the active member's position by one without wrapping. Move Container is the whole-structure escape hatch and never transfers to another monitor at a workspace edge. Dwindle join/extract and Move Container operations are intentionally unavailable while Overview is open; leave Overview before changing a Dwindle tree.
Quake Terminal (Inside Terminal)
| Action | Shortcut |
|--------|----------|
| New Tab | Cmd + T |
| Close Tab | Cmd + W |
| Next Tab | Cmd + Shift + ] |
| Previous Tab | Cmd + Shift + |
| Next Tab (Alt) | Ctrl + Tab |
| Previous Tab (Alt) | Ctrl + Shift + Tab |
| Select Tab 1-9 | Cmd + 1-9 |
| Split Pane (Horizontal) | Cmd + D |
| Split Pane (Vertical) | Cmd + Shift + D |
| Close Pane | Cmd + Shift + W |
| Equalize Splits | Cmd + Shift + = |
| Navigate Pane | Cmd + Option + Arrow Keys |
Features
Quake Terminal
A true quake/sticky terminal powered by Ghostty's libghostty. The default Center position fades it in place; Top, Bottom, Left, and Right slide it in from that screen edge.
- Toggle it from the global shortcut shown in Keyboard Shortcuts
- Supports multiple tabs and splits within tabs
- Tab and pane shortcuts are listed in Quake Terminal (Inside Terminal)
- Mouse resize by dragging edges; Option + drag
to move - Configure position, width and height as percentages of the monitor's available screen area, opacity, and background effect in Settings
- Choose Standard Blur with an adjustable radius or native Regular Glass/Clear Glass; switching effects preserves the saved Standard Blur radius
- Auto-hides on focus loss (optional)
Quake Terminal loads Ghostty's normal configuration files and their included files, so font, theme, and other terminal preferences can be shared. OmniWM applies its Quake background opacity and effect afterward; configure those in Settings → Quake Terminal.
Command Palette
Quickly search windows, app menus, or clipboard history from one shared palette:
- Open it from the global shortcut shown in Keyboard Shortcuts
- Use Tab
/Shift + Tabto cycle forward or backward through the available modes - Use Cmd + 1
forWindows,Cmd + 2forMenu, andCmd + 3forClipboard - Type to search by substring; window-title matches rank first, followed by app-name and workspace-name matches
- Menu results always show keyboard shortcuts when available
- Up
/Downmove the selection - Enter
activates the selected result - Windows from macOS-hidden apps remain searchable with a Hidden badge; selecting one unhides its app and focuses that exact window
- In Windows mode, Shift + Enter
summons the selected window to the right when available - In Clipboard mode, Enter
copies the selected entry and pastes it into the previous app when that target is still available;Shift + Entercopies without pasting - Escape
dismisses the palette
) and click Enable, or set clipboard.historyEnabled = true in settings.toml. History retains supported text, rich text, HTML, images, and file references within the configured limits; items marked concealed, transient, or autogenerated, including recognized password-manager markers, are skipped. Each row has Copy and Delete actions, and the trash button clears the history. See the [command palette guide for storage details.
Menu Anywhere
Open the frontmost app's menus at your cursor with a global shortcut. Menu Anywhere builds a native floating menu from the menus, submenus, and shortcuts the app exposes through Accessibility.
Overview Mode
Overview supports trackpad opening and closing, with finger tracking when animations are enabled.
See all windows at once with thumbnails:
- Open it from the global shortcut shown in
Keyboard Shortcuts
Configure the 50–150% baseline zoom plus backdrop and window-border colors in Settings → Overview
Click a window to focus it
Type to filter/search windows; Backspace deletes search text
Alt (Option) + Shift + Mouse Scroll temporarily zooms the current overview; the next opening starts from the configured baseline
Arrow Keys navigate spatially; Left / Right stay within the current workspace. Tab / Shift + Tab` cycle forward or backward through matching windows, and keyboard navigation automatically scrolls the selected thumbnail into view