返回资讯中心
外部精选
软件工程
#开发者实时流

Show HN: SimpleWM builds on top of macOS Spaces for a i3-like experience

SimpleWM is a macOS menu-bar helper. It gives i3-style keys to the native

Hacker News 最新villaspedro2026/10/23 · 22 天前18 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

SimpleWM is a macOS menu-bar helper. It gives i3-style keys to the native macOS Spaces.

The app uses real Spaces. It does not emulate workspaces (AeroSpace does). It keeps SIP on. It loads private SkyLight functions with dlsym. Each private function is optional: a missing function disables one feature only.

Requirements: macOS 14 or later (tested on macOS 26.1). To build from source: Xcode 16 or later.

From a release (no build)

Download SimpleWM-<version>.zip from the Releases page.

Unzip it and move SimpleWM.app to /Applications.

Quit AeroSpace. SimpleWM does not tile while bobko.aerospace runs. Both apps use the same Option chords.

Open SimpleWM. macOS asks for Accessibility. Click "Open System Settings" and turn on SimpleWM. The app checks the grant every 2 s and starts itself.

Optional: open System Settings > Desktop & Dock. Turn on "Displays have separate Spaces". Without it, the app tiles only the focused display.

The release is signed with a Developer ID and notarized. The Accessibility grant survives updates.

The app uses Sparkle 2. It never installs an update without your permission.

Sparkle checks the EdDSA signature of each update before it installs it.

scripts/make-app.sh open dist/SimpleWM.app

The script signs with the first "Developer ID Application" identity in your keychain. Without one it uses an ad-hoc signature. An ad-hoc signature changes on each build, so macOS drops the Accessibility grant. To use another identity:

SIMPLEWM_SIGN_IDENTITY="Developer ID Application: Name (TEAMID)" scripts/make-app.sh

If the grant stops working after a rebuild, reset it and add the app again:

tccutil reset Accessibility com.simplewm.app

Menu bar

The status item shows a split icon and a short title:

Menu items: Enabled (toggle), Open Config, Reload Config, Start at Login, the update item, Quit. When a warning is active, the first menu row shows the reason.

"Start at Login" is on by default. The app registers itself at the first start from /Applications. macOS can ask for approval in System Settings > General > Login Items. Use the menu item to turn it off.

The update item shows "Check for Updates", or "Update (vX.Y.Z)" when a newer release exists (see Updates). A build that runs outside the app bundle (.build/debug/SimpleWM) has no update item.

Chord Command Action

alt-1 ... alt-9 space N Switch to native Space N of the focused display.

alt-shift-1 ... alt-shift-9 move-to-space N Move the focused window to Space N.

alt-tab back-and-forth Switch to the previous Space of the focused display, as in i3.

alt-h / alt-j / alt-k / alt-l focus left/down/up/right Move focus. At the edge, focus goes to the next display.

alt-shift-h/j/k/l move left/down/up/right Move the window in the tree. At the edge, the window goes to the next display.

alt-f fullscreen Zoom the window inside the tree. Native fullscreen is not used.

alt-e toggle-split Flip the split orientation of the parent container.

alt-r balance Give equal sizes to all windows.

alt-shift-minus resize -0.05 Make the window smaller.

alt-shift-equal resize 0.05 Make the window larger.

alt-shift-space toggle-float Toggle the focused window between tiled and floating.

alt-comma / alt-period focus-monitor left/right Move focus to the display on that side.

alt-shift-comma / alt-shift-period move-to-monitor left/right Move the window to the display on that side.

Drag the edge of a tiled window with the mouse to resize its split, as in i3. The new size stays after the mouse up. alt-shift-minus and alt-shift-equal do the same from the keyboard.

N follows the Mission Control order of the focused display. A fullscreen app counts as one Space. move-to-space N only targets a normal desktop.

If Space N does not exist, the app creates desktops up to N on that display and then switches to Space N (space N) or moves the window there (move-to-space N). A workspace appears on demand, as in i3. The app creates at most 9 Spaces on a display. Set createMissingSpaces to false to turn this off. Then a key for a missing Space does nothing.

Experimental: with removeEmptySpaces set to true, the app removes a desktop that has no window about 1.5 s later. The first desktop, the current desktop, a fullscreen app, and the last desktop of a display always stay. So one empty desktop remains at the end, as in Mission Control. A window on "All Desktops" keeps no desktop. The option is off by default. After 3 failed passes the app stops cleanup until a restart.

Key codes are physical. The keyboard layout (for example ABNT2) does not change the bindings.

The config file is ~/.config/simplewm/config.json. The app writes the default file on the first start. Use "Open Config" to edit it and "Reload Config" to apply it.

{ "bindings" : { "alt-1" : "space 1", "alt-shift-1" : "move-to-space 1", "alt-h" : "focus left", "alt-shift-h" : "move left", "alt-f" : "fullscreen", "alt-e" : "toggle-split", "alt-r" : "balance", "alt-v" : "split vertical", "alt-shift-minus" : "resize -0.05", "alt-shift-equal" : "resize 0.05" }, "createMissingSpaces" : true, "removeEmptySpaces" : false, "floatingApps" : [ "com.apple.systempreferences" ], "floatWindowsWithoutZoom" : true, "followOnMove" : false, "gaps" : { "inner" : 0, "outer" : 0 }, "rootOrientation" : "auto", "spaceSwitch" : { "strategy" : "auto", "warpCursor" : true } }

Keys:

A missing key keeps its default value. A file with an error keeps the last good config, and the app logs the error. A bad binding is logged and skipped.

The app uses private SkyLight functions. A macOS update can remove or change them. The app logs each missing function and disables only that feature.

Spaces are native. The app does not reorder Spaces. It removes only empty desktops (see removeEmptySpaces). Reorder Spaces in Mission Control.

Removing a desktop opens Mission Control for a moment, like creation. The app runs the Accessibility action AXRemoveDesktop on the thumbnail. When a desktop in the middle goes away, the desktops after it shift down by one number.

Creating a Space opens Mission Control for a moment (about half a second for each Space). macOS has no public API for this. The app presses the "+" button of Mission Control through Accessibility. It needs the Accessibility grant. The new Space goes at the end of the list. The current Space and the focus stay. A macOS update can change the Mission Control layout. Then creation fails, the log shows the reason, and the menu bar shows sWM!.

The app does not touch native fullscreen windows or their Spaces. A display that shows a fullscreen Space gets no tiling. space N still works.

macOS lists windows only on visible Spaces. The app updates a tree only while its Space is visible.

A window set to "All Desktops" floats. The app does not tile it.

Floating windows

A floating window keeps its own frame. The app never resizes or moves it. A window floats when one of these holds:

The toggle is per window and lasts until the window closes.

log stream --predicate 'subsystem == "com.simplewm.app"' --level debug

At startup the app logs the displays, their UUIDs, the current Space of each display, the user-Space count, and the Accessibility grant.

Run a dry run to read these logs without tiling. The app registers the hotkeys but does not change window frames:

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →