One window that holds all your other windows
A native macOS app that adopts windows you already have open and pins them inside one resizable container. Each contained window gets its own tab — click a tab to bring that window forward, click ↗ to let it go. The window stays the real, fully interactive app; it is just kept exactly where you want it.
Contain 0.3.3 stops working on 20 August 2026. On that date it explains that the preview has ended, points you at the current release and quits — restoring every window it was holding on the way out, so nothing is left hidden. The deadline exists so an early copy cannot quietly become a permanent install running unsupported months later; Settings → General counts down to it, and a new beta resets it. Contain updates itself, so staying current takes nothing on your part.
Not applications — windows. Three documents from one editor are three separate tabs, and each one keeps its own place in the container.
Contained window
The real TextEdit window, pinned to this rect.
Type in it. It is not a screenshot.
How it works
macOS has no public API for embedding another process's window inside your own. So Contain does what tiling window managers do: it uses the Accessibility API to move, resize, and raise each adopted window so it always sits exactly over the container's content area.
Every open window as a tile, four to a row — a list of App — Window title lines is fine for three entries and unreadable at thirty. Contained windows drop out; an app you hid yourself is offered as one entry that unhides it first.
Click the container — or + in the tab bar
Adopted windows drift — apps reposition themselves, and you drag things. Contain re-pins a drifting window within a second, and windows that refuse to be resized (Calculator) are centred at their natural size instead.
for window in contained {
if window.frame != containerContentRect {
// or centre it, if fixed-size
window.setFrame(containerContentRect)
}
}What it does
Every rule here exists because the alternative was surprising. Contain adopts, pins, and releases — and does nothing you did not ask for.
Click the empty container — or + in the tab bar — for a grid of every open window, four to a row, each tile showing the app icon at a size you can actually recognise plus the app and window name. Pick one and it becomes a tab. No relaunch, no plugin, no per-app support matrix.
Three TextEdit documents are three tabs, not one "TextEdit". Click a tab to bring that window forward; the apps that own no selected window step out of the way.
A snap loop re-pins any window that drifts within a second, so an app that repositions its own window — or a stray drag — does not break the layout.
Contain records each window's position, size and display before adopting it. The ↗ button (or ⌘W) puts it back precisely there, and so does quitting Contain. It never terminates a contained app — containing a window leaves no trace once you stop.
No screen capture, no proxy view, no remote drawing. What you see inside the container is the genuine app window, fully interactive, just kept glued to the container's content area.
Settings (⌘,) shows the installed version, when Contain last checked for an update, and whether Accessibility access is currently granted — with a shortcut straight to the pane when it is not. That grant fails silently, and it is easy to lose across updates.
New versions arrive in the background and install with a click; Check for Updates… runs the check on demand. Every update is signed, and Contain refuses one that is not signed with the key the installed copy already trusts.
The list of apps and windows you contain is the most revealing thing Contain knows, and none of it is ever sent — no bundle ID, no app name, no window title. Anonymous usage counts are named one by one in Settings → Privacy, with a switch that stops them the moment you click it.
Picker tiles can show a live thumbnail of each window, which needs Screen Recording — a far bigger permission than moving a window. Contain never raises that prompt on its own: it says what the permission allows, and works perfectly well on icons if you decline.
Requirements
Grant access under System Settings → Privacy & Security → Accessibility (add Contain with + if it is not listed). Contain's own Settings → General tells you at any time whether the grant is still live.
Distribution
Contain is not sandboxed. On macOS 26 the App Sandbox blocks outbound Accessibility messaging — reading another app's window attributes returns kAXErrorCannotComplete even with Accessibility granted — which kills Contain's core function. Verified empirically: an identical sandboxed build silently fails to move the adopted window.
Since the Mac App Store mandates the sandbox, Contain is distributed directly, as a Developer ID-signed, notarized disk image. The signing identity never changes between releases — macOS ties the Accessibility grant to an app's code signature, so a stable signature is what lets an update land without you having to grant access again.
A notarized disk image. Open it, drag Contain to Applications, launch it, and grant Accessibility access when macOS asks. From then on Contain updates itself.
Signed and notarized by Apple, so it opens without a Gatekeeper warning. This beta build stops working on 20 August 2026. See the changelog for what is in this release.
Known limitations
Contain works within the Accessibility API, and the API has edges. These are the ones you will actually run into.
Entering it moves the container into its own Space, and macOS offers no way to put another app's window into an app's full-screen Space — the container would fill the display while everything it contained stayed behind on the previous desktop. No API fixes this, so full screen is disabled and the green button zooms to fill the visible frame instead, which contained windows follow correctly.
A few apps refuse to shrink past a minimum — System Settings stops at 723×470 — and macOS reports the resize as successful while quietly clamping it. Contain reads back the size it actually got, grows the container once at adoption to swallow that minimum where the screen allows, and centres the window when it cannot, so the overflow is symmetric.
macOS offers no per-window hide. Release one window of an app that still has others contained and that app can no longer be hidden, so its remaining contained windows stay visible behind the selected one. Windows of the same app are instead pinned to the same rect, stacked underneath.
Contain caches the window list it last saw, so an app it hid itself stays fully pickable. An app you hid before Contain ever saw it shows up as a single "show windows…" entry that unhides it first.
A contained window is a separate OS window layered above the container, so while you drag the Contain window itself it may briefly slip behind. It is re-raised as soon as the drag ends.
Contain works on windows that already exist. Open the window yourself first, then contain it.
Public beta
Contain is at v0.3.3 — small, free, and still finding its edges. It adopts a window you already have open and puts it back exactly where it found it the moment you ask, so trying it costs you nothing but a download. The beta runs until 20 August 2026.