Free, open-source tiling window manager for Apple Silicon Macs, with Niri-style scrolling containers and Hyprland-style Dwindle BSP.
See the codeOmniWM 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
Thank you to everyone who contributed to OmniWM. Your ideas and code made a real difference.
|
Bitkey ━━━━━━━━
Naoki Ikeguchi @siketyan |
BlueLabs ━━━━━━━━
Cristian Álvarez Belaustegui @crbelaus |
EPAM ━━━━━━━━
Aleksei Gurianov @Guria |
Finanzguru ━━━━━━━━
Janek Thomaschewski @jthomaschewski |
GitHub ━━━━━━━━
Ryan Hecht @RyanHecht |
━━━━━━━━
muhammadkh @MuhammadKh |
Liip ━━━━━━━━
Jonathan Macheret @Jonathanm10 |
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 |
|
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 |
omniwmctl automationOmniWM 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.
OmniWM is built for high responsiveness and smooth, crisp animations.
OmniWM is in the official Homebrew cask repository:
brew install --cask omniwm
This installs OmniWM.app and puts omniwmctl on your PATH.
Quit OmniWM first, then run brew upgrade omniwm and relaunch it. Homebrew replaces the app bundle underneath a running OmniWM.
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.
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.
OmniWM-v<version>.zip app archive from ReleasesOmniWM.app to /ApplicationsDisplays have separate SpacesOmniWM checks for updates by default.
Open Release Page, Copy brew upgrade omniwm, Skip This Version, and Not Now.Settings > General > Updates or trigger a manual check from the status bar menu with Check for Updates....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.
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.
omniwmctl window mark can name, list, focus, summon, and remove runtime window marks. See Window Marks.
For setup, installation options, commands, queries, rules, subscriptions, and security details, see the IPC & CLI Reference.
Displays have separate SpacesSettings > HotkeysSettings > General > UpdatesStart at Login under Settings > General > Startup to launch OmniWM automatically when you log inCheck for Updates... from the status bar menu whenever you want to run a manual update checkOmniWM uses two display maps for different jobs:
The setup assistant opens automatically when OmniWM first sees multiple displays. To review or redo it later, choose Run Monitor Setup… in Settings > Monitors. The assistant's Show Numbers on Screens action helps match each physical display to its tile. Routing, workspace-home, and Mouse Warp changes remain drafts until you finish the assistant.
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.
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.
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:
Shared works in any active layout.Niri works only when the active workspace uses the Niri layout.Dwindle works only when the active workspace uses the Dwindle layout.Settings > Hotkeys lists all actions that can be assigned a shortcut, including advanced actions.
If a shortcut does not fire: Check Settings > Hotkeys and Settings > Troubleshooting for registration issues, then look for another hotkey tool, such as skhd or Raycast, still running with the same binding. HotkeyClash can help inspect possible conflicts in running apps, supported config files, and macOS shortcuts. It does not parse Raycast's shortcut settings. Disable or reassign the conflicting binding and retry before editing settings.toml.
| Action | Default Shortcut | Layout |
|---|---|---|
| Switch to Workspace 1-9 | Option + 1-9 | Shared |
| Move 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 |
When you create workspace 10 or higher, Settings > Hotkeys adds its Switch, Move, and Move Column actions as Unassigned.
| 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 |
| Set Mark on Focused Window | Unassigned | Shared |
| Remove Mark from Focused Window | Unassigned | 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 |
| 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 |
| 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.
| 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 |
| 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 |
| Shrink / Grow Container Primary Span | Option + - / Option + = | Niri |
| Shrink / Grow Window Secondary Span | Option + Shift + - / Option + Shift + = | Niri |
| Shrink / Grow Window Primary Span | 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 |
Niri grow/shrink actions use a configurable increment, defaulting to 5% instead of 10%. Change Resize Increment in Niri settings or [niri].resizeStepPercent in TOML (1–100). Explicit omniwmctl size arguments keep their specified amounts.
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 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.
Unreleased — available when building from main. Customize tab and pane shortcuts with Ghostty keybind entries in ~/.config/ghostty/config.ghostty (or your existing Ghostty config). User bindings override the defaults below; unbind removes a binding. Reload inside Quake with Cmd + Shift + ,, or relaunch OmniWM. The global toggle stays in Settings → Hotkeys and OmniWM's settings.toml.
keybind = cmd+t=unbind
keybind = ctrl+shift+t=new_tab
keybind = cmd+enter=new_split:right
keybind = cmd+shift+enter=close_surface
See Ghostty's keybinding syntax. Quake supports new_tab, close_tab, goto_tab, next_tab, previous_tab, last_tab, new_split, goto_split, close_surface, and equalize_splits, alongside Ghostty's terminal actions such as copy, paste, and font sizing.
| Action | Default 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 |
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.
Keyboard ShortcutsOption + drag to movehttp/https links in your default browser or mailto links in your mail app; other schemes are blockedOmniWM remembers one custom size and position. It reuses that frame when it fits the selected monitor; otherwise it uses the configured position and percentages. Reset to Default Position appears in Settings once a custom frame is in use.
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.
Quickly search windows, app menus, clipboard history, OmniWM commands, applications, or files from one shared palette:
Keyboard ShortcutsTab / Shift + Tab to cycle forward or backward through the available modesCmd + 1 for Windows, Cmd + 2 for Menu, Cmd + 3 for Clipboard, Cmd + 4 for Commands, Cmd + 5 for Applications, and Cmd + 6 for FilesEnter runs the selected command; commands for another layout stay visible but cannot be selectedUp / Down move the selectionEnter activates the selected resultShift + Enter summons the selected window to the right when available, or moves it into an empty current workspace, including floating windows. Floating windows cannot be summoned rightEnter copies the selected entry; Shift + Enter pastes it into the previous app when that target is still availableCmd + EnterEscape dismisses the paletteClipboard history starts disabled. Open Clipboard mode (Cmd + 3) and click Enable, or set clipboard.historyEnabled = true in settings.toml. History retains text, rich text, HTML, images, file references, and safe native formats within the configured limits; concealed, transient, and recognized password-manager content is skipped. A selected item has a preview, each row can be pasted or pinned, and Clear removes unpinned history. See the command palette guide for storage details.
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 supports trackpad opening and closing, with finger tracking when animations are enabled.
See all windows at once with thumbnails:
Keyboard ShortcutsBackspace deletes search textAlt (Option) + Shift + Mouse Scroll temporarily zooms the current overview; the next opening starts from the configured baselineArrow 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 viewCommand + W closes the selected window once per press and keeps Overview open; selection advances only after the window has closedEnter, Escape, the configured Overview shortcut, and clicking the backdrop dismiss Overview and focus the current selection; Escape does not clear search firstA visual indicator showing your workspaces:
Deduplicate App Icons is enabled, multiple windows from one app share an icon; click a grouped icon to open their window list, while a single-window icon focuses that window directlyToggle System Stats and omniwmctl command toggle-system-stats drive the same popup, and both do nothing unless a monitor currently shows that workspace-bar buttonHide in Native Fullscreen); reserved tiled layout space is left untouched so windows do not shuffle around the fullscreen sessionWorkspace-bar appearance controls are optional and also support per-monitor overrides:
Existing appearance stays unchanged until you opt in. For example, edit these keys inside the existing [workspaceBar] table (do not replace the complete configuration with this fragment):
transparentBackground = false
solidBlackBackground = true
inactiveIconOpacity = 0.9
showItemBackgrounds = false
showAccentHighlights = false
notchMode = "fillLeftOfNotch"
Omitted keys preserve the existing appearance.
Workspace-bar icon overrides can also be configured in settings.toml. Quote bundle IDs so TOML treats each dotted identifier as one key:
[workspaceBar.iconOverrides]
"com.example.App" = "icons/custom.icns"
"com.cmuxterm.app" = "bundle-resource:AppIconDark"
bundle-resource: loads a named image packaged inside the selected app. The Settings picker discovers likely app-icon resources on demand; runtime-generated or downloaded Dock icons may not be available. Absolute paths are used as written, ~ expands to your home directory, and relative paths are resolved from the directory containing settings.toml. Overrides affect only the workspace bar. A valid override takes precedence over the app's standard icon; an unavailable or invalid image falls back to the standard icon, then the dashed placeholder when no app icon is available. OmniWM does not watch image files; use Replace to reload a file changed in place.
Conceal selected menu-bar icons and reach them from a panel:
Settings > Hidden BarShift to insert into a column. Dwindle swaps whole tiles, including their tab groups. The modifier defaults to Option and can be changed or disabled in Settings → Mouse & Trackpad. In Overview, dragging a thumbnail needs no modifier and targets a workspace, window position, or Niri column gapOption by default) and right-drag a tiled window to resize it in either layoutOption + Shift + Mouse Scroll Wheel (default, configurable) to scroll along the active Niri primary axis: left/right in horizontal orientation or up/down in vertical orientationAccess settings by clicking OmniWM's status bar icon and selecting Settings or App Rules. Mouse and gesture settings live in Settings under Mouse & Trackpad. The Trackpad Gestures panel shows all five assignments together. Finger selectors work while a gesture is off; Set Up… explains conflicts and offers explicit reassignment choices before turning anything off. Expand a gesture row for its additional controls.
Settings > General also carries a System-wide Window Corners control (macOS 26.4+). It writes the system-wide preference, so it changes standard Mac app windows everywhere — including windows OmniWM does not manage — and apps that draw their own window chrome may ignore it. Affected apps must be fully quit and reopened before the new radius applies.
OmniWM stores its editable config at ${XDG_CONFIG_HOME:-$HOME/.config}/omniwm/settings.toml; that file is the canonical settings source and is live-reloaded when saved from an editor.
XDG_CONFIG_HOME and XDG_STATE_HOME are honored only when set to absolute paths; otherwise OmniWM uses ~/.config and ~/.local/state, respectively.
Most configuration is also editable in Settings. Start at Login is managed by macOS, and System-wide Window Corners changes a macOS preference; neither is stored in settings.toml. Clipboard retention limits and scratchpad labels are edited in TOML.
updateChecksEnabled is part of the persisted settings model, so it round-trips through settings.toml.${XDG_STATE_HOME:-$HOME/.local/state}/omniwm and stay out of dotfile-oriented config storage.A scratchpad is a slot that holds any number of floating windows and overlays them on the workspace you are looking at. There are ten slots, numbered 1 to 10; a slot with no windows in it is inert and invisible.
Hotkey and CLI toggles leave macOS-hidden apps hidden and skip windows suspended in native fullscreen. Clicking a workspace-bar pill while the slot is hidden can unhide its apps; exit native fullscreen before revealing a suspended window.
Each non-empty slot gets a pill in the workspace bar showing its name and its windows' icons; clicking
the pill toggles that scratchpad. Slots are identified by number everywhere, and an optional label
replaces the number in the workspace bar and in omniwmctl output:
[scratchpads.labels]
1 = "term"
3 = "COMMS"
Scratchpad membership lasts for the lifetime of the OmniWM process; only the labels are persisted.
Open App Rules from OmniWM's status-bar menu to configure window-matching behavior. Rules can match by bundle ID, app-name substring, title substring or regex, and AX role/subrole. More-specific matches win; ties follow list order.
Structural admission runs before ordinary rule ranking. Help tags, input-method surfaces, and WindowServer
children of another window stay unmanaged. At ordinary WindowServer levels, a closeable, parentless
accessory-app AXWindow is eligible for normal classification. Buttonless accessory roots, prohibited-app
roots, non-AXWindow roles, and otherwise unsupported AX subroles require an identifying rule with exact
axRole and axSubrole values plus a Tile or Float layout. Parentless roots at status-window level or higher
use the same precise shape, but only a user rule can opt them in; built-in rules cannot. A broad bundle/title
rule or Automatic layout does not cross these gates.
Initial container primary span is a one-time seed. It controls width in horizontal orientation and height in vertical orientation. Niri's Single Window Fit still takes visual precedence for a lone window, and physical minimum-size constraints can clamp the resolved pixel size without changing the stored initial proportion.
The equivalent TOML rule uses a proportion:
[[appRules]]
bundleId = "net.kovidgoyal.kitty"
initialContainerPrimarySpan = 0.5
Follow the contributor quick start for Xcode requirements, automatic dependency setup, and a separate OmniWM Dev app with independent settings. The guide covers rebuilding, switching back to your normal app, and verifying a pull request.
omniwmctl across OmniWM workspaces and displays.omniwmctl.Questions, setup help, and config sharing happen on the OmniWM Discord. Confirmed bugs still belong on GitHub — see Reporting Bugs. Community integrations and related forks are listed above and on the Community & Support page.
If you find OmniWM useful, consider supporting development:
The best way to report a bug is from inside OmniWM: open the status-bar menu and choose Report a Bug…. That opens the in-app report form, where recording or attaching trace and crash evidence is optional. On submit, OmniWM prepares one fresh diagnostic .log (with any evidence you selected appended), reveals it in Finder for you to attach, and opens a pre-filled GitHub issue — OmniWM never sees your GitHub login. Review the .log before attaching it to a public issue: it can include settings, app and window titles, and title-based rule matchers.
Prefer the web? The GitHub issue form works too; please include your OmniWM and macOS versions there.
Issues and pull requests are welcome on GitHub.
Start with CONTRIBUTING.md for the actual project guidelines, expectations, and preferred direction.
For deeper technical context, edit the source pages used by the documentation site:
The similarly named files under docs/ are compatibility stubs that direct old links to omniwm.app.
OmniWM is licensed under the GNU General Public License v2.0-only. Copyright (C) 2026 BarutSRB — https://github.com/OmniNull/OmniWM.
Every source file carries an SPDX license header. Forks and redistributions must retain these notices and the LICENSE file, and remain GPL-2.0-only with source available.
(top 24 of 62)
90 followers · starred Sep 2026
151 followers · starred Aug 2026
512 followers · starred Aug 2026
70 followers · starred Jun 2026
Swift
97.4%
Free, open-source tiling window manager for Apple Silicon Macs, with Niri-style scrolling containers and Hyprland-style Dwindle BSP.
See the codeOmniWM 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
Thank you to everyone who contributed to OmniWM. Your ideas and code made a real difference.
|
Bitkey ━━━━━━━━
Naoki Ikeguchi @siketyan |
BlueLabs ━━━━━━━━
Cristian Álvarez Belaustegui @crbelaus |
EPAM ━━━━━━━━
Aleksei Gurianov @Guria |
Finanzguru ━━━━━━━━
Janek Thomaschewski @jthomaschewski |
GitHub ━━━━━━━━
Ryan Hecht @RyanHecht |
━━━━━━━━
muhammadkh @MuhammadKh |
Liip ━━━━━━━━
Jonathan Macheret @Jonathanm10 |
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 |
|
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 |
omniwmctl automationOmniWM 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.
OmniWM is built for high responsiveness and smooth, crisp animations.
OmniWM is in the official Homebrew cask repository:
brew install --cask omniwm
This installs OmniWM.app and puts omniwmctl on your PATH.
Quit OmniWM first, then run brew upgrade omniwm and relaunch it. Homebrew replaces the app bundle underneath a running OmniWM.
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.
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.
OmniWM-v<version>.zip app archive from ReleasesOmniWM.app to /ApplicationsDisplays have separate SpacesOmniWM checks for updates by default.
Open Release Page, Copy brew upgrade omniwm, Skip This Version, and Not Now.Settings > General > Updates or trigger a manual check from the status bar menu with Check for Updates....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.
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.
omniwmctl window mark can name, list, focus, summon, and remove runtime window marks. See Window Marks.
For setup, installation options, commands, queries, rules, subscriptions, and security details, see the IPC & CLI Reference.
Displays have separate SpacesSettings > HotkeysSettings > General > UpdatesStart at Login under Settings > General > Startup to launch OmniWM automatically when you log inCheck for Updates... from the status bar menu whenever you want to run a manual update checkOmniWM uses two display maps for different jobs:
The setup assistant opens automatically when OmniWM first sees multiple displays. To review or redo it later, choose Run Monitor Setup… in Settings > Monitors. The assistant's Show Numbers on Screens action helps match each physical display to its tile. Routing, workspace-home, and Mouse Warp changes remain drafts until you finish the assistant.
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.
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.
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:
Shared works in any active layout.Niri works only when the active workspace uses the Niri layout.Dwindle works only when the active workspace uses the Dwindle layout.Settings > Hotkeys lists all actions that can be assigned a shortcut, including advanced actions.
If a shortcut does not fire: Check Settings > Hotkeys and Settings > Troubleshooting for registration issues, then look for another hotkey tool, such as skhd or Raycast, still running with the same binding. HotkeyClash can help inspect possible conflicts in running apps, supported config files, and macOS shortcuts. It does not parse Raycast's shortcut settings. Disable or reassign the conflicting binding and retry before editing settings.toml.
| Action | Default Shortcut | Layout |
|---|---|---|
| Switch to Workspace 1-9 | Option + 1-9 | Shared |
| Move 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 |
When you create workspace 10 or higher, Settings > Hotkeys adds its Switch, Move, and Move Column actions as Unassigned.
| 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 |
| Set Mark on Focused Window | Unassigned | Shared |
| Remove Mark from Focused Window | Unassigned | 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 |
| 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 |
| 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.
| 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 |
| 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 |
| Shrink / Grow Container Primary Span | Option + - / Option + = | Niri |
| Shrink / Grow Window Secondary Span | Option + Shift + - / Option + Shift + = | Niri |
| Shrink / Grow Window Primary Span | 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 |
Niri grow/shrink actions use a configurable increment, defaulting to 5% instead of 10%. Change Resize Increment in Niri settings or [niri].resizeStepPercent in TOML (1–100). Explicit omniwmctl size arguments keep their specified amounts.
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 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.
Unreleased — available when building from main. Customize tab and pane shortcuts with Ghostty keybind entries in ~/.config/ghostty/config.ghostty (or your existing Ghostty config). User bindings override the defaults below; unbind removes a binding. Reload inside Quake with Cmd + Shift + ,, or relaunch OmniWM. The global toggle stays in Settings → Hotkeys and OmniWM's settings.toml.
keybind = cmd+t=unbind
keybind = ctrl+shift+t=new_tab
keybind = cmd+enter=new_split:right
keybind = cmd+shift+enter=close_surface
See Ghostty's keybinding syntax. Quake supports new_tab, close_tab, goto_tab, next_tab, previous_tab, last_tab, new_split, goto_split, close_surface, and equalize_splits, alongside Ghostty's terminal actions such as copy, paste, and font sizing.
| Action | Default 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 |
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.
Keyboard ShortcutsOption + drag to movehttp/https links in your default browser or mailto links in your mail app; other schemes are blockedOmniWM remembers one custom size and position. It reuses that frame when it fits the selected monitor; otherwise it uses the configured position and percentages. Reset to Default Position appears in Settings once a custom frame is in use.
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.
Quickly search windows, app menus, clipboard history, OmniWM commands, applications, or files from one shared palette:
Keyboard ShortcutsTab / Shift + Tab to cycle forward or backward through the available modesCmd + 1 for Windows, Cmd + 2 for Menu, Cmd + 3 for Clipboard, Cmd + 4 for Commands, Cmd + 5 for Applications, and Cmd + 6 for FilesEnter runs the selected command; commands for another layout stay visible but cannot be selectedUp / Down move the selectionEnter activates the selected resultShift + Enter summons the selected window to the right when available, or moves it into an empty current workspace, including floating windows. Floating windows cannot be summoned rightEnter copies the selected entry; Shift + Enter pastes it into the previous app when that target is still availableCmd + EnterEscape dismisses the paletteClipboard history starts disabled. Open Clipboard mode (Cmd + 3) and click Enable, or set clipboard.historyEnabled = true in settings.toml. History retains text, rich text, HTML, images, file references, and safe native formats within the configured limits; concealed, transient, and recognized password-manager content is skipped. A selected item has a preview, each row can be pasted or pinned, and Clear removes unpinned history. See the command palette guide for storage details.
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 supports trackpad opening and closing, with finger tracking when animations are enabled.
See all windows at once with thumbnails:
Keyboard ShortcutsBackspace deletes search textAlt (Option) + Shift + Mouse Scroll temporarily zooms the current overview; the next opening starts from the configured baselineArrow 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 viewCommand + W closes the selected window once per press and keeps Overview open; selection advances only after the window has closedEnter, Escape, the configured Overview shortcut, and clicking the backdrop dismiss Overview and focus the current selection; Escape does not clear search firstA visual indicator showing your workspaces:
Deduplicate App Icons is enabled, multiple windows from one app share an icon; click a grouped icon to open their window list, while a single-window icon focuses that window directlyToggle System Stats and omniwmctl command toggle-system-stats drive the same popup, and both do nothing unless a monitor currently shows that workspace-bar buttonHide in Native Fullscreen); reserved tiled layout space is left untouched so windows do not shuffle around the fullscreen sessionWorkspace-bar appearance controls are optional and also support per-monitor overrides:
Existing appearance stays unchanged until you opt in. For example, edit these keys inside the existing [workspaceBar] table (do not replace the complete configuration with this fragment):
transparentBackground = false
solidBlackBackground = true
inactiveIconOpacity = 0.9
showItemBackgrounds = false
showAccentHighlights = false
notchMode = "fillLeftOfNotch"
Omitted keys preserve the existing appearance.
Workspace-bar icon overrides can also be configured in settings.toml. Quote bundle IDs so TOML treats each dotted identifier as one key:
[workspaceBar.iconOverrides]
"com.example.App" = "icons/custom.icns"
"com.cmuxterm.app" = "bundle-resource:AppIconDark"
bundle-resource: loads a named image packaged inside the selected app. The Settings picker discovers likely app-icon resources on demand; runtime-generated or downloaded Dock icons may not be available. Absolute paths are used as written, ~ expands to your home directory, and relative paths are resolved from the directory containing settings.toml. Overrides affect only the workspace bar. A valid override takes precedence over the app's standard icon; an unavailable or invalid image falls back to the standard icon, then the dashed placeholder when no app icon is available. OmniWM does not watch image files; use Replace to reload a file changed in place.
Conceal selected menu-bar icons and reach them from a panel:
Settings > Hidden BarShift to insert into a column. Dwindle swaps whole tiles, including their tab groups. The modifier defaults to Option and can be changed or disabled in Settings → Mouse & Trackpad. In Overview, dragging a thumbnail needs no modifier and targets a workspace, window position, or Niri column gapOption by default) and right-drag a tiled window to resize it in either layoutOption + Shift + Mouse Scroll Wheel (default, configurable) to scroll along the active Niri primary axis: left/right in horizontal orientation or up/down in vertical orientationAccess settings by clicking OmniWM's status bar icon and selecting Settings or App Rules. Mouse and gesture settings live in Settings under Mouse & Trackpad. The Trackpad Gestures panel shows all five assignments together. Finger selectors work while a gesture is off; Set Up… explains conflicts and offers explicit reassignment choices before turning anything off. Expand a gesture row for its additional controls.
Settings > General also carries a System-wide Window Corners control (macOS 26.4+). It writes the system-wide preference, so it changes standard Mac app windows everywhere — including windows OmniWM does not manage — and apps that draw their own window chrome may ignore it. Affected apps must be fully quit and reopened before the new radius applies.
OmniWM stores its editable config at ${XDG_CONFIG_HOME:-$HOME/.config}/omniwm/settings.toml; that file is the canonical settings source and is live-reloaded when saved from an editor.
XDG_CONFIG_HOME and XDG_STATE_HOME are honored only when set to absolute paths; otherwise OmniWM uses ~/.config and ~/.local/state, respectively.
Most configuration is also editable in Settings. Start at Login is managed by macOS, and System-wide Window Corners changes a macOS preference; neither is stored in settings.toml. Clipboard retention limits and scratchpad labels are edited in TOML.
updateChecksEnabled is part of the persisted settings model, so it round-trips through settings.toml.${XDG_STATE_HOME:-$HOME/.local/state}/omniwm and stay out of dotfile-oriented config storage.A scratchpad is a slot that holds any number of floating windows and overlays them on the workspace you are looking at. There are ten slots, numbered 1 to 10; a slot with no windows in it is inert and invisible.
Hotkey and CLI toggles leave macOS-hidden apps hidden and skip windows suspended in native fullscreen. Clicking a workspace-bar pill while the slot is hidden can unhide its apps; exit native fullscreen before revealing a suspended window.
Each non-empty slot gets a pill in the workspace bar showing its name and its windows' icons; clicking
the pill toggles that scratchpad. Slots are identified by number everywhere, and an optional label
replaces the number in the workspace bar and in omniwmctl output:
[scratchpads.labels]
1 = "term"
3 = "COMMS"
Scratchpad membership lasts for the lifetime of the OmniWM process; only the labels are persisted.
Open App Rules from OmniWM's status-bar menu to configure window-matching behavior. Rules can match by bundle ID, app-name substring, title substring or regex, and AX role/subrole. More-specific matches win; ties follow list order.
Structural admission runs before ordinary rule ranking. Help tags, input-method surfaces, and WindowServer
children of another window stay unmanaged. At ordinary WindowServer levels, a closeable, parentless
accessory-app AXWindow is eligible for normal classification. Buttonless accessory roots, prohibited-app
roots, non-AXWindow roles, and otherwise unsupported AX subroles require an identifying rule with exact
axRole and axSubrole values plus a Tile or Float layout. Parentless roots at status-window level or higher
use the same precise shape, but only a user rule can opt them in; built-in rules cannot. A broad bundle/title
rule or Automatic layout does not cross these gates.
Initial container primary span is a one-time seed. It controls width in horizontal orientation and height in vertical orientation. Niri's Single Window Fit still takes visual precedence for a lone window, and physical minimum-size constraints can clamp the resolved pixel size without changing the stored initial proportion.
The equivalent TOML rule uses a proportion:
[[appRules]]
bundleId = "net.kovidgoyal.kitty"
initialContainerPrimarySpan = 0.5
Follow the contributor quick start for Xcode requirements, automatic dependency setup, and a separate OmniWM Dev app with independent settings. The guide covers rebuilding, switching back to your normal app, and verifying a pull request.
omniwmctl across OmniWM workspaces and displays.omniwmctl.Questions, setup help, and config sharing happen on the OmniWM Discord. Confirmed bugs still belong on GitHub — see Reporting Bugs. Community integrations and related forks are listed above and on the Community & Support page.
If you find OmniWM useful, consider supporting development:
The best way to report a bug is from inside OmniWM: open the status-bar menu and choose Report a Bug…. That opens the in-app report form, where recording or attaching trace and crash evidence is optional. On submit, OmniWM prepares one fresh diagnostic .log (with any evidence you selected appended), reveals it in Finder for you to attach, and opens a pre-filled GitHub issue — OmniWM never sees your GitHub login. Review the .log before attaching it to a public issue: it can include settings, app and window titles, and title-based rule matchers.
Prefer the web? The GitHub issue form works too; please include your OmniWM and macOS versions there.
Issues and pull requests are welcome on GitHub.
Start with CONTRIBUTING.md for the actual project guidelines, expectations, and preferred direction.
For deeper technical context, edit the source pages used by the documentation site:
The similarly named files under docs/ are compatibility stubs that direct old links to omniwm.app.
OmniWM is licensed under the GNU General Public License v2.0-only. Copyright (C) 2026 BarutSRB — https://github.com/OmniNull/OmniWM.
Every source file carries an SPDX license header. Forks and redistributions must retain these notices and the LICENSE file, and remain GPL-2.0-only with source available.
(top 24 of 62)
90 followers · starred Sep 2026
151 followers · starred Aug 2026
512 followers · starred Aug 2026
70 followers · starred Jun 2026
Swift
97.4%