Finestra is a small macOS window-management daemon with a menu bar cheat sheet. It is two single-file Swift programs, no dependencies, no Xcode project.
- Registers 57 global hotkeys itself through Carbon, so there is no input tap and nothing that can slow down or block other shortcuts
- Moves, resizes, centres, snaps and maximises the front window, sends it to the next monitor, and remembers the previous frame for undo
- Arranges the front two, three or four windows into cycling layouts, distributes a row or column of windows around the pointer, rotates and swaps a stack
- Opens a highlighted file path from any app, or reveals it in Finder
- Creates a new Markdown or plain text file in the front Finder window with the name ready to type
- Accepts the same commands over a FIFO, so any tool that can write a line of text can drive it
- Shows every shortcut in a menu bar panel (the second app, Finestra Shortcuts)
Finestra does not manage clipboard history or replace the macOS app switcher.
- macOS 15 or later. That is all for the one-line install below
- Building from source additionally needs the Xcode Command Line Tools
(
xcode-select --install), forswiftcandcodesign, and a code-signing identity; see "Build from source"
Nothing needs installing first: no Xcode, no Command Line Tools, no Git. Paste this into Terminal:
curl -fsSL https://raw.githubusercontent.com/braveva/finestra/main/Scripts/install.sh | shIt downloads the latest release from this repository, installs both apps into
~/Library/Application Support/Finestra/, writes and loads the two launch agents, and
then macOS asks to let Finestra control the computer using accessibility features. Click
Open System Settings and switch Finestra on. Every shortcut works from that moment, and
both apps start again at every login.
The first time a feature talks to Finder, Terminal or iTerm2 (new file, reveal in Finder, opening a path highlighted in a terminal) macOS asks for Automation access. Allow it.
Run the same line again to upgrade. FINESTRA_VERSION=v1.0.0 in front of it pins a
release. The installer is Scripts/install.sh in this repository; read it before running
it if you like, it uses only tools that ship with macOS.
xcode-select --install # once, if swiftc is missing
git clone https://github.com/braveva/finestra.git
cd finestra
export FINESTRA_CODESIGN_IDENTITY=- # ad-hoc; see "Signing" below for a stable identity
./Scripts/verify # type-check and run the self-tests
./Scripts/stage-install # builds both apps, copies them to Application Support
mkdir -p ~/Library/LaunchAgents
cp .build/LaunchAgents/com.eva.finestra.plist .build/LaunchAgents/com.eva.finestra.shortcuts.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.eva.finestra.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.eva.finestra.shortcuts.plistScripts/stage-install runs Scripts/build, copies Finestra.app and
FinestraShortcuts.app to ~/Library/Application Support/Finestra/, and renders the two
launch agent plists into .build/LaunchAgents/ with your home directory filled in. It
deliberately does not load them; the launchctl lines above do. Both agents start at
login and are kept alive.
Then grant permissions:
- Accessibility. Open the pane with
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility", click the plus button, press Shift+Command+G in the file dialog and paste~/Library/Application Support/Finestra/Finestra.app. Every window operation and every hotkey needs this. Restart the daemon afterwards:launchctl kickstart -k gui/$(id -u)/com.eva.finestra - Automation prompts appear the first time a feature talks to Finder, Terminal or iTerm2 (new file, reveal in Finder, opening a path highlighted in a terminal). Allow them.
The menu bar shows a window icon from Finestra Shortcuts once both agents are running.
Scripts/build refuses to run without a signing identity. FINESTRA_CODESIGN_IDENTITY=-
signs ad-hoc, which is fine for a one-off install but means macOS forgets the Accessibility
grant after every rebuild. For repeated builds use an Apple Development certificate: find
its SHA-1 with security find-identity -v -p codesigning and either export it in
FINESTRA_CODESIGN_IDENTITY or put it on one line in a file called
.finestra-signing-identity at the repository root (ignored by Git).
launchctl bootout gui/$(id -u)/com.eva.finestra
launchctl bootout gui/$(id -u)/com.eva.finestra.shortcuts
rm ~/Library/LaunchAgents/com.eva.finestra.plist ~/Library/LaunchAgents/com.eva.finestra.shortcuts.plist
rm -r ~/Library/Application\ Support/FinestraThe default modifier is Control+Option. Click the menu bar icon of Finestra Shortcuts
for the full list; the same table is the rows array at the top of
Sources/FinestraMenu/main.swift. A few examples:
| Keys | Action |
|---|---|
| ^⌥ Arrow | Slide the window to that edge, size kept |
| ^⌥⌘ Arrow, ^⌥⇧⌘ Arrow | Nudge 20 px or 100 px |
| ^⌥⇧ Arrow | Narrower, wider, taller, shorter |
| ^⌥ U I J K | Four quarters |
| ^⌥ D E G, ^⌥⇧ D E G | Left, middle, right third; top, middle, bottom third |
| ^⌥ Return, ^⌥ W, ^⌥ H, ^⌥ C | Maximise, full width, full height, centre |
| ^⌥ 2 3 4, ^⌥⇧ 2 3 4 | Arrange the front 2, 3 or 4 windows; tap again for the next layout, shift for the previous |
| ^⌥⌘ 2 to 5, ^⌥⇧⌘ 2 to 5 | Row across or column down through the pointer |
| ^⌥ [ ], ^⌥ R | Swap up or down in the stack; rotate all |
| ^⌥ N, ^⌥ Z | Send to the next monitor; undo |
| ^⌥ F, ^⌥⇧ F | Open the highlighted path; reveal its folder |
| ^⌥ T, ^⌥⇧ T | New Markdown or plain text file in the front Finder window |
To change a binding, edit hotkeyTable in Sources/FinestraDaemon/main.swift and the
matching row in the menu app, then run ./Scripts/verify (it checks the table has no
duplicate bindings) and rebuild.
The daemon reads one command per line from a FIFO, by default /tmp/finestra.fifo:
echo 'edge left' > /tmp/finestra.fifo
echo 'layout 0,0,0.5,1' > /tmp/finestra.fifo # x,y,w,h as fractions of the screen
echo 'arrange 3 next' > /tmp/finestra.fifo
echo 'distribute width 4' > /tmp/finestra.fifoCommands: move dx dy, grow dw dh, edge left|right|top|bottom, center,
fullwidth, fullheight, band i n, col i n, layout x,y,w,h [x,y,w,h ...],
arrange n next|prev, distribute width|height n, stack, rotate, swap up|down,
next, undo, openpath open|reveal, newfile md|txt, windows, screens,
resolve. The handler in Sources/FinestraDaemon/main.swift is the reference for
arguments.
| Path | Purpose | Override |
|---|---|---|
~/Library/Application Support/Finestra/finestra.log |
Log, one line per command | FINESTRA_LOG |
~/Library/Application Support/Finestra/screens.json |
Stable display identities across reconnects | FINESTRA_DB |
/tmp/finestra.fifo |
Command FIFO | FINESTRA_FIFO |
Sources/FinestraDaemon/main.swift the daemon: hotkeys, FIFO, window logic, self-tests
Sources/FinestraMenu/main.swift the menu bar cheat sheet
Resources/ Info.plists and launch agent templates
Scripts/build compile and sign both apps into .build/
Scripts/verify type-check, self-tests, plist lint
Scripts/stage-install copy to Application Support, render launch agents
MIT, see LICENSE.