Skip to content

Lv-0/plumb

Repository files navigation

Plumb

Plumb

A single line descends, and finds its point.

Make your Mac feel more elegant to use.

Auto-centers and tiles macOS apps — a blessing for neat freaks!

License Platform Swift Release

English · 简体中文 · Español · Français · 日本語


📖 Table of Contents

About

Plumb is a macOS menu-bar window manager that supports both auto-centering and per-app auto-tiling.

Named after the plumb line — the weight a carpenter drops to find true vertical, true center. That's exactly what Plumb does: gently place a window at the true center of the screen, or at a designated position.

  • 🪧 Lives in the menu bar — no Dock icon, zero intrusion
  • 🎯 Evaluates layout per app activation / Space cycle, then suppresses duplicate work within that cycle
  • 🖥️ Computes within the usable screen area (auto-excludes Dock & menu bar), stable across multi-display
  • 📐 Per-app auto-tiling (allowlist) with a global margin and optional per-app directional margins
  • 🔌 Optional Launch at Login (native macOS login item, no hacky scripts)
  • 🪟 Liquid Glass settings UI (macOS 26) — frosted glass, app search, pill toggles

✨ Features

Feature Description
🎯 Activation-scoped layout Re-evaluates on app activation and Space changes, while suppressing duplicate work within the current cycle
✋ Respects manual layout A genuine move or resize leaves that window untouched for the rest of the current activation / Space cycle
🖥️ Precisely avoids Dock/menu bar Based on screen.frame - screen.visibleFrame, stable across multi-display
📐 Per-app auto-tiling Allowlist mechanism with a configurable global margin (px)
🎚️ Per-app tiling margins Tap any tiled app to set custom top, bottom, left, and right margins; apps without an override use the global default
🔄 Live app-list refresh Newly installed apps appear in the settings picker immediately, no restart needed
🪟 Liquid Glass settings UI macOS 26 frosted glass, search, pill toggles
🧠 Smart coordinate-space detection Auto-detects each app's window coordinate space and caches it for stability
🔌 Launch at Login Optional native macOS login item (SMAppService.mainApp); toggle reflects the real system state
🪧 Non-intrusive menu-bar presence Menu-bar icon only, does not occupy the Dock

📐 Auto-Tiling

Open Tiling Settings… from the menu bar to enable/disable the feature and manage your workflow.

  • Configure a single uniform edge margin (px)
  • Per-app margin override: tap any app in the Tiling list to expand an inline drawer and set its top, bottom, left, and right margins independently. Apps without an override use the global margin on all four sides; "Use Default" removes the override.
  • Select allowlisted apps from installed applications (system apps hidden by default, toggleable)
  • For allowlisted apps, tiling has priority over auto-centering
  • Optional Only Tile When Apps Launch mode: each app is tiled only from a real process launch; switching apps, screens, or Spaces does not tile it again. Quit and relaunch the app to allow a new automatic tile.
  • With that option off, trigger scope remains one app activation / Space cycle. Re-activating an app or changing Space starts a new evaluation.
  • Plumb tries both the standard AX size write and an AXFrame fallback. A reposition-only result is not treated as successful tiling; bounded retries continue, and only target-width geometry or the documented vertically anchored fallback is accepted.
  • For document apps (Pages, Numbers, Word, Excel), template galleries and file lists are centered only. Saved documents are tiled, while detected unsaved documents wait briefly for their frame to stabilize before tiling.

Semantics are inspired by Amethyst configuration concepts:

  • window-margin-size: equivalent to tiling margin in this project
  • floating + floating-is-blacklist=false: equivalent to allowlisted auto-tiling here

📸 Screenshots

Centering — app allowlist Tiling — per-app margin drawer
Centering tab Tiling tab with per-app margin drawer
Permissions — Accessibility, Screen Recording, Launch at Login
Permissions tab

Download & Install

Option 1: Download the DMG (recommended)

  1. Download the latest Plumb.dmg from Releases.
  2. Open the DMG and drag Plumb.app into Applications.
  3. In Applications, right-click Plumb.appOpen → click Open again.
  4. If blocked, go to System Settings → Privacy & Security and click "Open Anyway".

Option 2: Build from source

swift build -c release
./.build/release/Plumb

See Build locally.

Usage

  1. After launch, the Plumb icon appears in the menu bar.
  2. Grant the Accessibility permission — centering depends on it.
  3. (Optional) Grant the Screen Recording permission to improve multi-display coordinate detection stability.
  4. Click the menu-bar icon:
    • Trigger centering manually
    • Open Tiling Settings… to configure the allowlist and margin
    • Open Settings…Permissions tab to enable Launch at Login (Plumb starts automatically when you log in)

💡 Design principle: automatic layout is scoped to the current app activation / Space cycle. A genuine manual move or resize is respected for the rest of that cycle; re-activating the app or changing Space clears the manual mark and evaluates layout again.

Permissions

Accessibility

  • Path: System Settings → Privacy & Security → Accessibility
  • Why required: The app uses macOS Accessibility APIs to read the frontmost window's frame and write a new position for centering.
  • Without it: The app cannot read window geometry or move windows, so centering will not work.

Screen Recording

  • Path: System Settings → Privacy & Security → Screen Recording
  • Why required: The app needs full screen context to reliably compute usable display bounds and avoid Dock/menu bar while centering.
  • Without it: Screen-context-dependent centering can become unstable on multi-display or complex layouts.

Permission boundary

  • ❌ The app does not upload screen content and does not perform telemetry collection.
  • ✅ Permissions are used only for local window geometry calculations and positioning.

Why permissions may need re-granting (and how this is fixed)

macOS keys Accessibility and Screen Recording grants on an app's stable signing identity (its designated requirement). An ad-hoc signature's identity is just the binary's hash (cdhash), which changes on every rebuild — so each update looks like a brand-new app to macOS and its grants are discarded.

Plumb is now signed with a stable local certificate (Plumb Local Signer) instead of ad-hoc. Because the designated requirement is bound to the certificate (not the per-build cdhash), your grants persist across updates after the first stable-signed version. To enable this on a given machine, run scripts/make_signing_cert.sh once (requires one admin password entry to trust the cert); subsequent builds then use the stable identity automatically. On a machine without the trusted cert, builds fall back to ad-hoc and grants will need re-giving after each update.

Limitation — building from source with a bare executable: a bare executable from swift build / swift run has no .app bundle and no stable signing identity, so its TCC grants are keyed to cdhash and reset on every rebuild. Use the .app build (via scripts/build_app.sh) for day-to-day testing of permission-dependent features.

Launch at Login

  • Where: Settings… (menu bar) → Permissions tab → Launch at Login toggle.
  • How: Registered as a native macOS login item via SMAppService.mainApp (no background daemons, no LaunchAgent hacks). The toggle reads the real system state, so it stays in sync even if you change it from System Settings → General → Login Items.
  • Note: Requires running as a signed .app. The bare swift build executable cannot register a login item.

Automatic updates

Plumb checks for updates on launch (at most once every 6 hours) and via Check for Updates… in the menu bar. When a newer version is available, you can update with one click — Plumb downloads the update, verifies its SHA-256 checksum, then relaunches into a small installer that replaces /Applications/Plumb.app and restarts the app automatically. If the app bundle is owned by you (e.g. installed by dragging from the DMG), the installer replaces it silently with no password prompt; otherwise it asks for your password once. With the stable signing identity in place, your Accessibility / Screen Recording permissions survive updates (see Why permissions may need re-granting).

Requirements

  • macOS 26+ (built on the macOS 26 SDK with the Liquid Glass UI; older versions are not supported)
  • Xcode Command Line Tools (xcode-select --install)

Build locally

# Run tests
swift test

# Build a Release binary
swift build -c release

# Run directly
./.build/release/Plumb

Package & Release

One-command release (recommended)

scripts/release.sh runs the entire flow end to end — bump version, build, sign, package, tag, push, publish the GitHub Release, and update the OTA appcast:

# Write the 5-language OTA notes first (en/zh/es/fr/ja, one line each)
scripts/release.sh --print-notes-template > /tmp/notes.txt
$EDITOR /tmp/notes.txt

# Then release (local-signed by default)
bash scripts/release.sh 2.0.50 --notes-file /tmp/notes.txt

What it does, in order: preflight checks (clean tree, tests, release build, secret scan) → bump 5 README badges → build signed .app + DMG + OTA zip → verify codesign (and assert the designated requirement is a certificate leaf hash, so TCC grants survive updates) → tag + push → create the GitHub Release with assets → update appcast.json (version/url/sha + 5-language notes). Full details and safety notes in RELEASING.md.

Build artifacts individually

scripts/build_app.sh      # produces dist/Plumb.app (signed with Plumb Local Signer)
scripts/create_dmg.sh     # produces dist/Plumb.dmg
scripts/create_zip.sh     # produces dist/Plumb-<version>.zip (for OTA)

The DMG includes Plumb.app and an Applications shortcut — install by dragging.

Signing modes

Mode When How
Local-signed (default) Everyday builds, testing scripts/build_app.sh uses Plumb Local Signer automatically (run scripts/make_signing_cert.sh once first)
Developer ID + notarized Public distribution without Gatekeeper warnings scripts/release.sh --sign developer-id (needs DEVELOPER_ID_APP + NOTARY_PROFILE env vars), or the standalone scripts/sign_and_notarize.sh

⚠️ Local-signed/unnnotarized DMG files can be blocked by Gatekeeper on a new Mac and may appear as "damaged" — run xattr -dr com.apple.quarantine /Applications/Plumb.app (see FAQ).

FAQ

"Damaged" or "unidentified developer" warning when opening Plumb.app?

This is the normal Gatekeeper flow for unnotarized distribution — not a corruption of the app code. Run:

xattr -dr com.apple.quarantine /Applications/Plumb.app

Or go to System Settings → Privacy & Security and click "Open Anyway" at the bottom.

Permissions reset every time I rebuild from source?

You're running the bare executable (swift run) or an ad-hoc .app. Both have an unstable signing identity, so macOS treats each build as a new app. Re-grant the two permissions (Accessibility, Screen Recording) after each rebuild.

Persisting grants across rebuilds requires a trusted signing identity. scripts/make_signing_cert.sh generates a self-signed code-signing certificate (with the codeSigning extended key usage); once trusted on your machine, scripts/build_app.sh uses it automatically and grants survive rebuilds. The cert's trust step writes to the admin trust domain, so on some macOS versions it must be run in an interactive Terminal (the sudo security add-trusted-cert step needs an interactive password).

Centering doesn't work?

Please make sure the Accessibility permission is granted: System Settings → Privacy & Security → Accessibility, and that Plumb is enabled. You may need to restart Plumb after granting.

Window centering is inaccurate on a multi-display setup?

Please grant the Screen Recording permission. Plumb uses the CGWindowList API as a secondary signal to more precisely identify the window's screen and coordinate space.

I dragged a window and it got re-centered?

During the current app activation / Space cycle, a genuine move or resize should leave that window where you placed it. Re-activating the app or changing Space starts a new layout cycle, so Plumb may center or tile it again then.

License

This project is open-sourced under the MIT License.


English · 简体中文 · Español · Français · 日本語

If Plumb helps you, a ⭐ Star is appreciated.

About

A lightweight macOS window manager that auto-centers and auto-tiles your apps.

Topics

Resources

License

Stars

14 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors