Skip to content

About

Open eight terminals in a grid with one click. A menu-bar macOS app that tiles every window of any app into a grid. Free.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

SplitScreener

Open eight terminals in a grid. One click.

A free tiling window manager for macOS that arranges every window of one app at once — and can open the windows for you first.

Licence: free to use Latest release Downloads macOS 14+ Universal binary

SplitScreener opening eight Terminal windows and tiling them into a 4×2 grid in one click

Download the .dmg · Privacy · Terms · Engineering log


macOS tiles four windows and has no concept of "all the windows of this app". SplitScreener is that missing action: click the menu-bar glyph, pick a grid, and every window belonging to the app you were just using snaps into place on the display you choose. Or skip the windows entirely — the first item in the menu opens 4, 6, 8, 9, 12 or 16 Terminal windows in your current Finder folder and tiles them in the same click, in about a second.

It is menu-bar only, a 7 MB universal binary, and it needs exactly one permission. It makes exactly one network connection: once a day it asks GitHub for a static file listing the current version, and you can switch that off. Nothing else, ever — no analytics, no account, no server of mine. Free — no trial, nothing to buy.

Scope, stated up front. Solo project, and the source is not public — it is a free app, not an open-source one. Issues are read; there is no support promise and no roadmap. Nobody minds a stated boundary; they mind an unstated one.


Install

Homebrew — the fastest path:

brew tap borys520/tap
brew install --cask splitscreener

Or download the disk image:

  1. Grab SplitScreener-1.0.1.dmg from the latest release.
  2. Open it and drag SplitScreener to Applications.
  3. Launch it from Applications.

Do not run it from the disk image, and do not leave it in ~/Downloads. macOS runs a quarantined app from a randomised read-only path until you move it in the Finder — so the path you add to Accessibility is not the path the app is actually running from, and the permission silently does nothing. Dragging it to Applications is what clears that. The /Applications symlink in the disk image exists for exactly this reason.

You will not need to right-click ▸ Open, and you should never need xattr -cr. The app is signed with a Developer ID certificate and notarized by Apple; if macOS ever refuses to open it, that is a bug worth reporting, not a step to work around.

Requirements

macOS 14 Sonoma or later. Universal binary — Apple silicon and Intel. One permission (Accessibility). No account, no login, no subscription, nothing to buy.

Developed and tested on macOS 26. Behaviour that is known to vary on older systems — how minimised windows report their accessibility subrole, Stage Manager detection, Space scoping — is written up in the engineering log.


Use

Three flows. That is the whole app.

1. New Terminal Grid — the one it was built for

Click the menu-bar glyph and choose New Terminal Grid ▸ 8 Terminals. Eight Terminal windows open in the frontmost Finder folder (or ~) and are tiled immediately. It is the first item in the menu because it is the thing this app is for.

New Terminal Grid  ▸   4 Terminals (2 × 2, 960×494)
                       6 Terminals (3 × 2, 640×494)
                       8 Terminals (4 × 2, 480×494)
                       9 Terminals (3 × 3, 640×329)
                      12 Terminals (4 × 3, 480×329)
                      16 Terminals (4 × 4, 480×247)

Every row names the grid it will use and the exact pixel size each window will end up at, computed for the display the grid is actually going to land on — by the same chooser and the same geometry the tiler itself uses. On a 1920×1050 secondary the same menu offers 8 Terminals (3 × 3, 640×350) instead. The label is never a guess.

2. Tile windows that are already open

Click the menu-bar glyph. You get a header reading Terminal — 8 windows and nine grids drawn as miniature screens at your display's real aspect ratio — 2×1, 1×2, 3×1, 2×2, 3×2, 4×2, 3×3, 4×3, 4×4 — each with the cells that will receive a window filled in and its cell size printed. A size in orange is a grid this display is too small for; you can still pick it, and the toast will say so afterwards.

Click one and every tileable window of that app moves, with a two-second toast reporting Tiled 8 windows · 4 × 2 — Undo ⌃⌥Z.

This works on any app with more than one window open — iTerm2, Ghostty, Warp, Kitty, VS Code, Safari, Preview, Finder. Nothing about it is terminal-specific.

3. One hotkey, no menu

Shortcut Action
⌃⌥Return Tile the frontmost app into the best-fit grid on the display under the pointer
⌃⌥Space Open the picker
⌃⌥Z Put every window back exactly where it was

⌃⌥Return is the fastest path in the app. Unlike clicking the menu, a hotkey does not activate SplitScreener, so it cannot disturb what you were doing. All three are rebindable in Settings, and all three are global Carbon hotkeys — which means they work before you have granted Accessibility, and they never leak a keystroke into the app you are typing in.

Pressing ⌃⌥Return twice by accident does not cost you the undo: a re-tile that would move nothing keeps the snapshot.

Settings

One short window. Gaps between windows and at the screen edges (both 8 pt by default, with a live preview), which display to tile onto (under the pointer by default), the three shortcuts, launch at login, and two filters — skip minimised and full-screen windows, skip windows narrower than N points. That is the entire surface.

Launch at login is off until you switch it on. The welcome window that opens on first run puts it in front of you as one labelled switch — Start SplitScreener when I log in — and Settings ▸ Startup carries the same switch from then on. Both read the real state back out of macOS rather than remembering what they asked for, and the Startup section will tell you plainly whether macOS currently has SplitScreener registered. The app never adds itself to your login items on its own. The 1.0.0 build did, silently, on first run; that was wrong, and 1.0.1 fixes it.

What it deliberately does not do

No saved layouts. No per-app rules. No grid editor. No daemon watching your windows. It is a one-shot tiler: it moves what you asked for, when you asked, and then it stops.

If you need snap-to-edge zones, drag-to-corner halves and quarters, or a background service that keeps your windows arranged, this is the wrong app and Rectangle is probably the right one. SplitScreener does one thing those tools do not: it takes all the windows of one app and lays them out together, and it can create them.


The Accessibility permission

System Settings ▸ Privacy & Security ▸ Accessibility, with SplitScreener listed and switched on

Moving another app's windows on macOS requires exactly one permission: Accessibility. There is no other API. macOS asks you for it, not the app.

  1. Launch SplitScreener. The glyph appears in the menu bar at 40% alpha, and the Settings window opens on first run.
  2. Click Open Settings… in the permission card. System Settings lands on Privacy & Security ▸ Accessibility.
  3. Add SplitScreener with + if it is not already listed, then switch it on.
  4. Do not relaunch. The app polls once a second, so the card flips to ✓ Accessibility access granted and the glyph goes to full alpha on its own.

What that permission can do, and what this app does with it

That permission is genuinely powerful. It can let an app read what is on your screen and act as you. It is worth being suspicious of, and you should be.

SplitScreener asks each window for its position and size, and sets new ones. That is the entire use of the API. It never reads window contents, never takes a screenshot, and it sends none of what it reads anywhere. There is no analytics code in the binary and no account to create. It asks for nothing else either — no Screen Recording, no Input Monitoring, no Apple Events.

Since 1.0.1 the app does make one network connection, and it is worth being precise about it rather than leaving you to find out: once a day it fetches one static file from GitHub to see whether a newer version exists. The request has no query string and carries no identifier of any kind, nothing is downloaded or installed without a button press, and it is one click to switch off. The whole of it is in PRIVACY.md, including what GitHub can see and how to turn it off.

You do not have to take that on faith, and you do not need the source to check it. Ask the app you actually downloaded, and then watch it:

APP=/Applications/SplitScreener.app

# The ONE address it is configured to contact. There is no other.
defaults read "$APP/Contents/Info.plist" SUFeedURL

# Installing by itself is disallowed; the updater's system profile is off. Both print 0.
defaults read "$APP/Contents/Info.plist" SUAllowsAutomaticUpdates
defaults read "$APP/Contents/Info.plist" SUEnableSystemProfiling

# And watch it, live.
nettop -p SplitScreener

Up to 1.0.0 this section told you to run otool -L and nm -u and see zero networking symbols. Those now print matches, because an app that fetches a file has to link Apple's networking frameworks. Leaving the old commands here as if they still answered 0 would be the easiest kind of lie to tell, so they are gone; the three above are what replaces them.

Besides the feed URL, the complete list of URLs the app constructs is three, and none of them are network URLs: the x-apple.systempreferences: link that opens the Accessibility pane, a temporary-directory path for the launcher shim, and the file:// path of the Finder window you are in, read from the Finder's own accessibility attributes.


Why not the Mac App Store?

Because the App Store requires the App Sandbox, and a sandboxed process cannot make cross-app Accessibility calls. Not "needs an entitlement" — cannot.

This was measured, not assumed. The same binary, in two identical bundles differing only by com.apple.security.app-sandbox, calling AXUIElementSetAttributeValue on another app's window:

Bundle AXIsProcessTrusted() Result
Unsandboxed true AXError 0 — the window moves
Sandboxed true AXError -25204 kAXErrorCannotComplete

The permission was granted in both cases. The sandbox severs the IPC before TCC is ever consulted, so there is no toggle a user can flip to fix it. Apple's Developer Technical Support has said the same in writing.

This is why every Accessibility-based window manager on the store — Magnet, Moom Classic, Divvy, BetterSnapTool, Cinch — was first released in 2011, before Apple's June 2012 sandbox mandate, and is grandfathered in. Nothing built on the Accessibility API has entered the store in fourteen years. One that tried was rejected under Guideline 2.4.5(i) in October 2025.

There is exactly one modern way in: delegate every window move to the Shortcuts engine via Apple Events, as the one app that has shipped this way (941 Tiles, on the store since July 2026) does. That is a full rewrite of the tiler, it costs you live window state, and it still cannot deliver New Terminal Grid — a sandboxed app opening a folder outside its container fails with NSOSStatusErrorDomain -54.

So: direct distribution, signed and notarized, free. That is not a consolation prize — it is where this category's users actually are. Rectangle, AeroSpace, Amethyst, yabai, Loop and Swish are all absent from the Mac App Store, and Rectangle alone moves over 116,000 Homebrew installs a year.

The full measurement, including the probe bundles, is in the engineering log.


Build from source

You can't, and that is the one place where SplitScreener is less open than most of the apps it sits next to. The source repository is private. It is a free app, not an open-source one, and there is no plan to change that.

Worth saying plainly rather than leaving you to discover it, because for something that asks for the Accessibility permission the very next question is "then how do I know what it does?" Here are two answers you can act on in under a minute, neither of which requires you to trust me.

Check that what you have is what I signed

The app is signed with a Developer ID certificate and notarized by Apple. macOS checks that before it ever runs it — but you can check it yourself, and this is what you should do with any Mac app that asks for Accessibility:

codesign -dvv /Applications/SplitScreener.app 2>&1 | grep -E 'Identifier|Authority|Timestamp|flags'
spctl -a -vvv --type execute /Applications/SplitScreener.app
xcrun stapler validate /Applications/SplitScreener.app

You want to see Identifier=com.borysk.splitscreener, Authority=Developer ID Application: Borys Kusmirek (29VV5B5Y3P), flags=0x10000(runtime), a Timestamp, and source=Notarized Developer ID from spctl. That combination means the bundle is byte-for-byte the one that left my machine, that Apple scanned it, and that nothing has been added to it since. A repacked or patched copy fails all three checks — which is exactly why Terms asks you not to ship one.

Check where it is allowed to connect

The three commands in The Accessibility permission above. They read the feed address out of the bundle you downloaded and let you watch the traffic. The full account of that one connection is in PRIVACY.md.

What the build actually is

About 7,000 lines of Swift 6 in a single Swift Package Manager executable target, with exactly one dependency: Sparkle 2.9.6, the updater, added in 1.0.1. One script compiles a universal binary, assembles the .app, embeds and re-signs Sparkle with the same Developer ID certificate, signs the bundle with the hardened runtime and a secure timestamp, notarizes it, staples the ticket and packages the disk image.

Sparkle.framework is the only nested code in the bundle, and it is trimmed to what a non-sandboxed app actually loads: the two XPC services that exist only to let a sandboxed app reach the network and write outside its container are deleted before signing, as Sparkle's own documentation recommends. There is no helper tool, no XPC service and no daemon.

The parts that were genuinely hard are written up in full in the engineering log — 76 KB of measured behaviour of AXUIElement, TCC signature keying, SMAppService, App Translocation, Spaces, Stage Manager and NSWorkspace.open. It is the most useful thing published here, and for most purposes it is a better read than the source would be.


FAQ

Is it really free? Yes, and free in the way that needs no asterisk: no trial, no licence key, no "pro" tier, no account, no upsell, nothing that expires. It was built for one developer's own eight terminals. There is no server behind it and nothing to bill for. Use it at work, use it for client work, install it on fifty machines — see Terms, which is about a page long.

Why isn't the source public? Because I decided to keep it private, and that is the whole reason — there is no licensing story behind it and nothing is being sold. The app is free either way. If your rule is "no closed-source app gets Accessibility", that is a completely reasonable rule and you should keep it; Rectangle and AeroSpace are open source, excellent, and I would rather you used one of those than used something you are not comfortable with. If your rule is "show me what it does", the Accessibility section gives you two commands that check the claims against the binary itself, the engineering log publishes the hard parts in detail, and every release is Developer-ID-signed and notarized so you can prove the copy you have is the one I built.

How is this different from Rectangle or Magnet? Those are snap-to-zone tools: you move one window at a time into a half, a quarter or a third. SplitScreener does not do that, and does not try to. It takes every window of one app and lays them out together in one action — and it is the only one that will open the windows for you. If you want half-screen snapping, use Rectangle; it is excellent and also free. The two do not overlap much, and nothing stops you running both.

Doesn't macOS already do this? macOS split screen puts two windows side by side, and macOS 26's tiling handles up to four. Neither has any concept of "all the windows of this app", and neither can auto-arrange windows that do not exist yet. If four windows is enough for you, you do not need this.

Can it open multiple Terminal windows at once? That is the headline feature. 4, 6, 8, 9, 12 or 16, in your current Finder folder, already tiled, in about a second.

Does it work with iTerm2 / Ghostty / Warp / Kitty? It tiles them today, like any other app. It only spawns Apple's Terminal in 1.0. Spawning other terminals is the obvious 1.1.

Does it work with multiple displays? Yes. Pick a display in Settings, or leave it on the default and it uses whichever display your pointer is on.

Does it send anything anywhere? One thing, once a day: a request for a static file on GitHub that says what the current version is. It carries no identifier — not a random one, not a stable one — and no information about you, your Mac or how you use the app. Nothing is downloaded or installed unless you click. Un-tick Check Automatically in the menu and even that stops. PRIVACY.md is the full account, including what GitHub can see in its own logs. Nothing else leaves the machine, ever.

Does it add itself to my login items? Only if you ask it to. The switch is on the welcome screen the first time you launch the app, default off, and in Settings ▸ Startup after that — one click either way. 1.0.0 registered the login item automatically on first run without asking; that was a mistake and 1.0.1 removes it. If 1.0.0 did it to you, 1.0.1 leaves the login item alone rather than yanking it out from under you — Settings ▸ Startup shows you the actual state so you can switch it off yourself, and so does System Settings ▸ General ▸ Login Items.

Will it update itself? It will tell you, and never more than that. 1.0.1 checks once a day and shows you a window with the release notes if there is something newer; downloading and installing happen only when you click. That is not a default you can accidentally flip: the bundle is built with SUAllowsAutomaticUpdates set to false, which removes silent installation from the updater entirely, so there is no setting — hidden or otherwise — that makes SplitScreener install anything on its own. Check Automatically in the menu switches the check itself off, and new versions are always also on the releases page and in the Homebrew cask.

Is there a Windows or Linux version? No. It is built directly on the macOS Accessibility API and would be a different program entirely.


Troubleshooting

Nothing moves, and the Accessibility toggle still reads ON

This is the one failure worth knowing about in advance. macOS does not remember "you granted SplitScreener" — it remembers "you granted this exact signature". If the signature changes, every call fails while the toggle keeps looking correct.

The app treats this specific error as permission lost: it dims the glyph and re-shows the permission card rather than silently doing nothing. To fix it:

tccutil reset Accessibility com.borysk.splitscreener

Then remove and re-add the app with the − / + buttons in System Settings. Toggling it off and on is not enough; only removing and re-adding refreshes the stored signature.

Never run tccutil reset Accessibility without the bundle identifier. That resets every app on your Mac.

If you installed from the disk image and never dragged the app to Applications, this is also what you will see — see Install.

Some windows didn't move, and the grid has holes

They are on another Space. macOS does not let any app move a window that lives on a Space you are not currently looking at, and with Displays have Separate Spaces on, each display has its own.

SplitScreener detects this and tells you — 3 windows are on another Space appears under the picker and in the toast — instead of handing you a grid with holes in it and windows you cannot find. Bring those windows to the current Space with Mission Control and tile again.

Terminal windows come out slightly different sizes

Expected, not a bug. Terminal only accepts whole character cells, so it rounds whatever size it is given by a few points either way. SplitScreener tolerates one character cell (12 pt) of drift, does at most one corrective pass, and never remembers a size Terminal refused. A few points of variation between columns is Terminal's grid, not a layout error.

The toast says "quite cramped"

You asked for more cells than the display comfortably holds. SplitScreener does it anyway — it is your screen — and tells you the truth about the result: Tiled 12 windows · 4 × 3 — cells are 350×260, quite cramped. Anything below 380×200 per cell earns that note, and the picker prints the same grids' cell sizes in orange before you click.

It is a note, never a block. On a 13" 1440×900 the honest answers are 6 or 9 windows; 12 and 16 will still be laid out exactly as asked.

"New Terminal Grid" opened nothing and mentioned Stage Manager

Stage Manager continuously repositions windows, so nothing can be tiled while it is on. SplitScreener checks before it opens anything, so you get one sentence rather than eight loose Terminal windows. Turn Stage Manager off in System Settings ▸ Desktop & Dock and try again.

The menu names the wrong app

Clicking a menu-bar item activates the app that owns it, so SplitScreener remembers which app you were actually in rather than asking the system at menu-open time. If the header ever names SplitScreener itself, click into the app you want and use ⌃⌥Return, which never activates SplitScreener and so cannot get confused.

"New Terminal Grid" hangs

Opening a folder macOS protects — Documents, Desktop, Downloads, or anything under /Volumes — can make the system's open call never return. SplitScreener routes those through a small temporary launcher script instead of touching the protected path itself and puts a 15-second deadline on the whole operation, so the worst case is "timed out" rather than a permanent hang.

Tip: set Terminal ▸ Settings ▸ Profiles ▸ Shell ▸ Ask before closing: Never to skip the close confirmation on spawned windows.

Reading the logs

/usr/bin/log show --last 10m --predicate 'subsystem == "com.borysk.splitscreener"' --info

Attach the output to a bug report.


Issues and feedback

There is no source to send a patch to, so the useful things are bug reports and specific requests. See CONTRIBUTING.md for what makes a report actionable — short version: the macOS version, the display setup, and the log show output decide whether a window-manager bug can be reproduced at all, and the issue template asks for exactly those three.

Feature requests are read and mostly declined, which is not rudeness: the small surface is the design. Two things are genuinely wanted — spawning terminals other than Apple's Terminal, and bug reports from macOS 14 and 15, which I have no machine to test on.

Licence

Free to use for anything, including commercially. No warranty. Don't ship modified builds and don't sell it. That is the whole of it, in plain English, in TERMS.md.

SplitScreener is free software in the sense that it costs nothing. It is not open source: the source repository is private and all rights to it are reserved. See Build from source for what you can verify without it.

© 2026 Borys Kusmirek

About

Open eight terminals in a grid with one click. A menu-bar macOS app that tiles every window of any app into a grid. Free.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors