GNU General Public License v2.0

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

项目背景与痛点

macOS 的窗口管理哲学一直是“手动摆放”。Stage Manager 和 Mission Control 提供的是组织能力,并非布局能力;系统从不替你决定两个终端应该各占半屏。对每天开着三四个终端、一个编辑器、两个浏览器窗口和一堆日志面板的开发者来说,这套哲学意味着每天上百次的手动拖动和缩放。

Linux 桌面社区早已把这个问题解决了,并且分裂成了两大流派:Niri 的滚动容器(窗口排成一条无限向右延伸的纸带,视口跟着焦点滑动)和 Hyprland 的 Dwindle BSP(每次新窗口把当前焦点区域二分,形成动态二叉树)。这两套交互范式经过大量用户打磨,手感和空间利用率都远超传统的“主从布局”。

macOS 这边的现状则有些尴尬。yabai 证明了可行性,但代价是脚本化配置、部分功能依赖关闭 SIP,升级系统时常被改动打断;Amethyst 提供了 BSP 但交互僵硬、动画缺失;AeroSpace 用 Swift 重写,方向对了,但只押注一种范式。OmniWM 的切入点很明确:把 Linux 上已经验证过的两套范式同时搬到 Apple Silicon 上,用原生技术栈实现,并且不要求用户改动系统完整性保护。

核心技术揭秘

从项目定位推断,OmniWM 只能是原生 Swift + AppKit 的组合。原因很直接:macOS 没有公开的窗口管理 API,所有平铺管理器都得通过 Accessibility 框架(AXUIElement)读写窗口的 position / size,或者走 SkyLight 私有符号(SLSMoveWindow 一类)绕开 AX 的 IPC 开销。这两条路都要求进程长期驻留并持有辅助功能授权,跨语言的胶水层只会徒增延迟。

它的架构关键不在于“怎么移动窗口”,而在于把布局策略和执行管道彻底解耦。滚动容器和 Dwindle 本质上都只是函数:输入是窗口集合与焦点,输出是一组目标 frame。真正困难的是管道另一端——macOS 的窗口是外部实体,用户和其他 App 随时会篡改它们的几何状态。

graph TD A[CGEventTap / 全局热键] --> B[指令解析层] C[AXObserver 窗口事件] --> D[状态采集器] D --> E[窗口模型 WindowModel] B --> E E --> F{"布局策略选择"} F -->|"滚动容器"| G[Niri 式列布局引擎] F -->|"二分切分"| H[Dwindle BSP 引擎] G --> I[帧计算 Frame Solver] H --> I I --> J[动画插值器] J --> K[AX / SkyLight 写回窗口] K --> L[漂移检测与矫正] L --> D

几个值得注意的技术难点:

滚动容器的坐标系问题。 Niri 式布局里,超出视口的列并不是“消失”,而是被平移到屏幕外。但 macOS 会把移出屏幕的窗口判定为不可见,部分 App(尤其是基于 Metal 或 Electron 的)会主动暂停渲染,滚回来时出现白屏或布局重排抖动。合理的做法是保留少量“预渲染缓冲区”,或者在窗口进入视口时主动触发一次 resize 事件强制重绘。

Dwindle 的切分方向。 Hyprland 的规则是按当前容器的长边切分,而不是固定横竖交替,这样能避免极端窄条的累积。实现上是一个二叉树,内部节点存 split 方向与 ratio,叶子节点绑定窗口 ID。插入新窗口时找到焦点叶子,替换为内部节点,再把整棵树重新做一次帧求解。

AX 写回的批处理与防抖。 每次 AXUIElementSetAttributeValue 都是一次跨进程调用,逐窗口串行写入会变成明显的性能瓶颈。动画就更苛刻了——想做出平滑的滚动效果,就得在每一帧里更新所有窗口的 frame,这基本会迫使实现者转向 SkyLight 这类更低层的通道,或者干脆接受“跳变 + 短暂过渡”的折中方案。

漂移矫正。 这是所有平铺管理器的隐形战场。用户手动拖了一下窗口,引擎是应该吸收这个改动(更新模型)还是强行拉回(维护布局权威)?通常要用阈值加时间窗口来判断:微小的、瞬时的偏移视为系统抖动并忽略;大幅度的、持续的手动移动视为用户意图,同步进模型。这个策略调不好,用起来就会像在跟一个固执的管家较劲。

功能亮点与差异

双范式共存是 OmniWM 最实在的卖点。滚动容器在超宽屏上是降维打击——21:9 的显示器上你可以横向铺七八个终端而不用切 workspace;BSP 则更适合小屏幕和窗口数量少的场景。允许按 workspace 分别指定布局策略,等于让用户在两种思维方式之间自由切换,而不用装两个软件。

Apple Silicon 专属看似是限制,实则是减负。省掉 x86 兼容分支后,可以放心依赖 arm64 上的统一内存模型和较新的 CoreAnimation 行为,二进制体积和测试矩阵都小一圈。

不依赖 SIP 调整(如果实现确实如此)是相对 yabai 的巨大优势。系统更新不再意味着重新折腾一遍安装流程,这对把窗口管理器当生产力基础设施的人来说是刚需。

横向对比:yabai 功能最全但生态脆弱;Amethyst 稳定但交互陈旧;AeroSpace 原生但范式单一。OmniWM 的位置在“原生体验 + 多范式 + 低维护成本”这个交叉点上。

应用场景与落地建议

最适合的画像很清晰:单人主力开发机、屏幕至少 27 寸或带鱼屏、日常工作流以终端和编辑器为主。这类用户窗口数量多、布局重复性高,平铺带来的收益最直接。

落地时有几点值得注意。第一,辅助功能权限必须在首次启动时引导到位,否则所有操作都没有效果,而 macOS 的授权弹窗很容易被忽略。第二,别一上来就全键盘化,先把常用 App 的窗口规则(float 白名单)配好——弹窗、设置面板、视频播放器这类窗口如果被卷进平铺,体验会立刻崩坏。第三,团队协作场景下要慎重:窗口管理器深度绑定个人肌肉记忆,统一配置反而会拖慢所有人。第四,留意 Electron 系 App 对高频 resize 的反应,必要时给它们单独设置规则。

综合评价

优点:双布局范式在一处统一,覆盖了宽屏和小屏两类需求;原生 Swift 实现带来更低的延迟和更少的兼容性负担;架构上策略与执行分离,后续加新布局的成本很低。

缺点:项目尚处早期,边缘场景(多显示器 + Spaces 组合、原生全屏窗口、Stage Manager 共存)大概率还有粗糙的地方;动画若走 AX 通道,高频写入的性能天花板明显;Apple Silicon 专属把 Intel Mac 用户直接排除在外,社区规模会受到限制。

一句话总结:它把 Linux 桌面上最成熟的两套平铺思路,用 macOS 原生方式重新做了一遍,方向正确、取舍清楚,但离“装完就不用管”还有一段工程打磨的距离。

关于

GitHub 原始描述(英文)

Free, open-source tiling window manager for Apple Silicon Macs, with Niri-style scrolling containers and Hyprland-style Dwindle BSP.

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

语言占比

Astro
C
C++
CSS
JavaScript
Luau
MDX
Makefile
Metal
Nix
Nushell
Objective-C
Perl
Python
Shell
Swift
TypeScript

README

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 · Fluxer

OmniWM — Do what you love easier, faster, better.

Demo Video

Watch the demo

Contributors

Thank you to everyone who contributed to OmniWM. Your ideas and code made a real difference.


🛠️ Maintainers

Aleksei Gurianov millia ampora Richard G Zhizhen He

🏢 By Employer

Bitkey
Bitkey
━━━━━━━━
Naoki Ikeguchi
Naoki Ikeguchi
@siketyan
BlueLabs
BlueLabs
━━━━━━━━
Cristian Álvarez Belaustegui
Cristian Álvarez Belaustegui
@crbelaus
EPAM Systems
EPAM
━━━━━━━━
Aleksei Gurianov
Aleksei Gurianov
@Guria
Finanzguru
Finanzguru
━━━━━━━━
Janek Thomaschewski
Janek Thomaschewski
@jthomaschewski
GitHub
GitHub
━━━━━━━━
Ryan Hecht
Ryan Hecht
@RyanHecht
Google
Google
━━━━━━━━
muhammadkh
muhammadkh
@MuhammadKh
inDrive
inDrive
━━━━━━━━
millia ampora
millia ampora
@dappermint
Liip
Liip
━━━━━━━━
Jonathan Macheret
Jonathan Macheret
@Jonathanm10
Luxor Labs
Luxor Labs
━━━━━━━━
Albert Ilagan
Albert Ilagan
@albertilagan
mooola
mooola
━━━━━━━━
Luke Stephens
Luke Stephens
@imprisonedmind
Nx
Nx
━━━━━━━━
Steven Nance
Steven Nance
@llwt
ReactSquad
ReactSquad
━━━━━━━━
Jan Hesters
Jan Hesters
@janhesters
Spotify
Spotify
━━━━━━━━
Alexander Dergachev
Alexander Dergachev
@Cy6erBr4in
SSW Consulting
SSW Consulting
━━━━━━━━
Matt Wicks
Matt Wicks
@wicksipedia
vhf
vhf
━━━━━━━━
Lukas Gerlinski
Lukas Gerlinski
@lgerlinski
Viber
Viber
━━━━━━━━
Yuri Chukhlib
Yuri Chukhlib
@YuriNachos
Walt
Walt
━━━━━━━━
Anton Plotnikov
Anton Plotnikov
@pltanton

🎓 By Education

Assumption University of Thailand
Assumption University of Thailand
━━━━━━━━
Panuphong Burakitphachai
Panuphong Burakitphachai
@t1dotdev
Linnaeus University
Linnaeus University
━━━━━━━━
Balazs Hevesi
Balazs Hevesi
@balazshevesi
NTU Singapore
NTU Singapore
━━━━━━━━
Nawat Suangburanakul
Nawat Suangburanakul
@holmns
Olin College of Engineering
Olin College of Engineering
━━━━━━━━
Cypress Frankenfeld
Cypress Frankenfeld
@cypressf
SUSTech
SUSTech
━━━━━━━━
Yang-Yiming
Yang-Yiming
@Yang-Yiming

✨ All Contributors

Adelin Berard Aisling Albert Ilagan Aleksei Gurianov Alexander Dergachev Aliaksandr Anton Plotnikov Ayaan Sandhu Balazs Hevesi binghan1227 Brian Smyth chen259456754 Cristian Álvarez Belaustegui Cypress Frankenfeld Dereck Angeles Filippo Zaffoni Fletcher Alderton georgian Henrik Larsson Hestnes Henry Perschk Jan Hesters Janek Thomaschewski Janos Miko Jonathan Macheret Jose Cardama KomarovD Lukas Gerlinski Luke Stephens Marcus Harlid Davin Mateusz Juszczyk matt petters Matt Wicks mkdir700 mm Mokhtar muhammadkh Naoki Ikeguchi Nawat Suangburanakul Ngo Quoc Viet Panuphong Burakitphachai Rich Hanes Richard Ginzburg rPio Ryan Hecht Steven Nance Taylor Bell Williamufo Yang-Yiming YeungKC Yuri Chukhlib Zhizhen He Zicochaos

🐞 Bug Reporters

Thank you to everyone whose bug reports led to fixes.

9j7axvsLuF Dan Dee Datarip Dhruv Jain dna07rak macsmister Manukashyap.U.V Max Rydahl Andersen

macOS Apple Silicon OpenAI Assisted

OmniNull%2FOmniWM | Trendshift

OmniNull%2FOmniWM | Trendshift OmniNull%2FOmniWM | Trendshift

Highlights

  • Optional window switcher with previews and separate Command-Tab / Option-Tab workspace scopes
  • Ghostty-powered quake/sticky terminal
  • Native macOS window-tab support
  • Local IPC and omniwmctl automation
  • Scratchpads and sticky windows for any app
  • Overview
  • Unified command palette for windows, app menus, clipboard history, OmniWM commands, applications, and files
  • 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.
  • OmniShell network consent (Unreleased: available when building from main) — Widgets need declared hosts and user consent or organization preapproval; native programs need trust tied to their executable and command. Settings > Network & Permissions manages those decisions and the built-in Weather and Lyrics switches, both on by default. Organization policies can block them. See network permissions and managed preferences.

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)
  • Full Disk Access permission for Hidden Bar concealment and the OmniShell Notifications widget (optional); notification replies and dismissal also use Accessibility
  • System Audio Recording permission for per-app volume, Calendars access for the calendar widget, Location for the Wi-Fi widget’s network name and Bluetooth for the Bluetooth widget in the Luau shell (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

  1. Download the OmniWM-v<version>.zip app archive from the latest release
  2. Extract and move OmniWM.app to /Applications
  3. In System Settings > Desktop & Dock > Mission Control, turn ON Displays have separate Spaces
  4. Log out of macOS and log back in for that change to take effect unless you had it on already
  5. Launch OmniWM and grant Accessibility and Input Monitoring when prompted
  6. Optionally grant Screen Recording for capture-derived visuals
  7. 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. To skip the window on later launches without Screen Recording, tick Don’t ask about Screen Recording again first; it still appears if a required permission goes missing (Unreleased: available when building from main)

Canary builds

Stable releases are recommended for everyday use. Canary builds let you try recent changes and help test fixes before the next release. Daily scheduled runs publish a build only when the checked-out main commit, or the app commit beneath any documentation-only commits on top, passes CI and includes app changes since the newest stable or canary tag in its history; documentation-only changes do not trigger a new build. Builds are signed and notarized, but may contain regressions.

To try one with a Homebrew or GitHub Releases install:

  1. Save a copy of ~/.config/omniwm/settings.toml
  2. Quit OmniWM, then download the newest canary build and replace OmniWM.app in /Applications with the app from its ZIP
  3. Relaunch OmniWM. It uses your existing settings

Canary builds check only for newer published Canary releases. Stable builds continue to check only stable releases. Use Install and Relaunch in the update popup (Unreleased: available when building from main), download from the release page, or use brew upgrade --cask omniwm@canary if you installed that Homebrew cask and its new version is available. Older Canary builds need one manual update to gain Canary update checks.

To return to stable, quit OmniWM. If you installed omniwm@canary, run brew uninstall --cask omniwm@canary followed by brew install --cask omniwm. For an existing omniwm Homebrew install, run brew reinstall --cask omniwm; for a direct download, replace the app with the latest release. If stable cannot read settings saved by a canary, quit OmniWM and restore your copy. When reporting a canary bug, include its release link.

Updates

OmniWM checks for updates by default.

  • On launch, OmniWM polls the latest GitHub release at most once per day.
  • OmniWM never installs anything on its own. Install and Relaunch (Unreleased: available when building from main) downloads the release’s app zip from GitHub, checks it against the SHA-256 digest GitHub publishes for it, checks that the new app carries the release’s version and is signed and notarized by the same Developer ID as the running copy, swaps the bundle in place and relaunches. If you cancel the quit, the new version starts on the next launch. The button only appears when the release has an app zip and OmniWM can write to its own bundle, so Nix store and other read-only installs keep the manual actions.
  • When a newer release is available, OmniWM shows a centered popup with release notes and actions for Install and Relaunch (when available), Open Release Page, Copy brew upgrade omniwm, Skip This Version, and Not Now.
  • You can control this from Settings > General > Updates or trigger a manual check from the status bar menu with Check 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.

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.

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.

Quick Start

  1. Launch OmniWM from your Applications folder
  2. In System Settings > Desktop & Dock > Mission Control, turn ON Displays have separate Spaces
  3. Log out of macOS and log back in for that change to take effect unless you had it on already
  4. 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
  5. 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
  6. Keep one macOS Space per display and navigate with OmniWM workspaces; extra native Spaces are tolerated (their windows are left to macOS, not tiled)
  7. Use the defaults in Keyboard Shortcuts to navigate, and customize them in Settings > Keyboard Shortcuts
  8. Click the menu bar icon to access Settings, including Settings > General > Updates
  9. Enable Start at Login under Settings > General > Startup to launch OmniWM automatically when you log in
  10. Use Check for Updates... from the status bar menu whenever you want to run a manual update check
  11. 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:

  1. 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.
  2. Open OmniWM Settings > Displays 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.
  3. 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.
  4. 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.

The setup assistant opens automatically when OmniWM first sees multiple displays. To review or redo it later, choose Run Monitor Setup… in Settings > Displays. 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 > Displays 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 > Keyboard Shortcuts. Hyper is the literal Control + Option + Shift + Command chord by default; which modifiers make up Hyper is configurable in Settings > Keyboard Shortcuts (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 > Keyboard Shortcuts lists all actions that can be assigned a shortcut, including advanced actions.

If a shortcut does not fire: Check Settings > Keyboard Shortcuts 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.

Workspace
Action Default Shortcut Layout
Switch to Workspace 1-9 Option + 1-9 Shared
Move Focused Window to Workspace 1-9 Option + Shift + 1-9 Shared
Switch to Workspace Slot 1-9 (position on the current monitor) Unassigned Shared
Move Focused Window 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 Focused Window to Workspace Up Control + Option + Shift + Up Arrow Shared
Move Focused Window to Workspace Down Control + Option + Shift + Down Arrow Shared
Move Focused Column to Workspace 1-9 Unassigned Niri
Move Focused Column to Workspace Up Control + Option + Shift + Page Up Niri
Move Focused Column to Workspace Down Control + Option + Shift + Page Down Niri

When you create workspace 10 or higher, Settings > Keyboard Shortcuts adds its Switch, Move, and Move Column actions as Unassigned.

Focus
Action Default Shortcut Layout
Focus Left / Right / Up / Down Option + Arrow Keys Shared
Focus Next / Previous Window (Wrap) Unassigned Shared
Focus First / Last Window in Column Unassigned Niri
Focus Window or Workspace Down / Up Unassigned Niri
Focus Previously Focused 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 Panel Unassigned Shared
Toggle Quake Terminal Option + ` Shared
Toggle Overview Option + Shift + O Shared
Toggle System Stats Unassigned Shared
Volume Up Unassigned Shared
Volume Down Unassigned Shared
Mute or Unmute Volume Unassigned Shared
Play or Pause Media Unassigned Shared
Next Track Unassigned Shared
Previous Track Unassigned Shared
Toggle <drawer or widget> Unassigned Shared

Settings > Keyboard Shortcuts lists a Toggle action for every shell drawer and every shell widget with a popout.

Move Window
Action Default Shortcut Layout
Move Left / Right / Up / Down Option + Shift + Arrow Keys Shared
Move Window to Previous / Next Position Unassigned Shared
Move Window Down or to Workspace Down / Up or to Workspace Up Unassigned Niri
Pull Top Window from Next Column into Focused Column Unassigned Niri
Push Bottom Window from Focused Column into New Column Unassigned Niri

The pull action treats the focused column as the destination and does nothing when there is no next column. The push action moves the bottom window from the focused column into a new following column. Neither action wraps, and there is no pull-from-previous action.

Monitor
Action Default Shortcut Layout
Focus Next Monitor in Order Control + Command + Tab Shared
Focus Previous Monitor in Order Unassigned Shared
Focus Last Active Monitor Control + Command + ` Shared
Move Workspace to Monitor on Left / Right / Above / Below Unassigned Shared
Move Focused Window to Monitor on Left / Right / Above / Below 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 OmniWM 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
Toggle Floating/Tiled Focus Unassigned Shared
Rescue Off-Screen Floating Windows Unassigned Shared
Toggle Focused Window Floating Unassigned Shared
Toggle Scratchpad 1-10 Assignment for Focused Window 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 Tabbed Mode for Focused Column Option + T Niri
Toggle Container Full Primary Span Option + Shift + F Niri
Expand Container to Available Primary Span Control + Option + F Niri
Move Focused Column to First / Last Position Control + Option + Home / End Niri
Move Focused Column to Position 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 Focused 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 > Keyboard Shortcuts, 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 > Keyboard Shortcuts. Focus Next / Previous Window (Wrap) always wraps within the active Niri column or Dwindle group. Move Window to Previous / Next Position 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)

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 → Keyboard Shortcuts 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

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)
  • Command-click an OSC 8 hyperlink to open http/https links in your default browser or mailto links in your mail app; other schemes are blocked

OmniWM 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.

Select Kitty under Settings → Quake Terminal → Terminal to use Kitty’s quick-access terminal. Install Kitty separately. It uses quick-access-terminal.conf, with optional placement, auto-hide, and opacity overrides in OmniWM. The Ghostty settings and shortcuts above apply to the embedded provider. See the Kitty provider guide.

Unreleased: available when building from main. Select foot to use the Quake terminal of foot for macOS 1.28.0-macos.8 or newer, installed separately. OmniWM runs a dedicated foot server that it keeps for reuse. It uses foot.ini, with optional placement, auto-hide, opacity and dim overrides that apply the next time the panel is shown; dimming is off by default. foot has no tabs or splits, and the regular foot app’s own Option + ` hotkey can clash with OmniWM’s shortcut. See the foot provider guide.

Command Palette

Quickly search windows, app menus, clipboard history, OmniWM commands, applications, or files from one shared palette:

  • Open it from the global shortcut shown in Keyboard Shortcuts
  • Use Tab / Shift + Tab to cycle forward or backward through the available modes
  • Use Cmd + 1 for Windows, Cmd + 2 for Menu, Cmd + 3 for Clipboard, Cmd + 4 for Commands, Cmd + 5 for Launcher, and Cmd + 6 for Files
  • Type to search; mark-name matches come first in Windows mode, then window title, app name, and workspace name, with focus recency breaking ties
  • Windows mode shows window marks and finds windows by mark name; its Mark and Remove Mark buttons act on the selected window
  • Menu results always show keyboard shortcuts when available
  • Commands are grouped by category until you search; each row shows its layout and current shortcut, including unassigned commands
  • In Commands mode, Enter runs the selected command; commands for another layout stay visible but cannot be selected
  • Up / Down move 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, or moves it into an empty current workspace, including floating windows. Floating windows cannot be summoned right
  • In Clipboard mode, Enter copies the selected entry; Shift + Enter pastes it into the previous app when that target is still available
  • Launcher and Files open in a browse grid; switch either mode to a list from the view menu
  • Files shows recent documents before typing, supports type filters, and can reveal a selection in Finder with Cmd + Enter
  • Escape dismisses the palette

Unreleased: available when building from main. Launcher adds saved commands, scripts and CLI tool discovery to the former Applications mode. Configure entries in Settings > Launcher; see the Launcher guide and TOML reference.

Clipboard 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 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% zoom, scrolling controls, and 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 changes the zoom; closing Overview saves it for the next opening
  • 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
  • Assigned structural move, reorder, consume/expel, and workspace-transfer shortcuts operate on the selected thumbnail while Overview is open
  • In Niri workspaces, r

README 内容过长,已截取前 64 KB。完整内容请前往 GitHub 仓库查看。

评论

暂无评论