Cascade all open app windows

I'm looking for a way to arrange all open app windows on a given screen. I would like to "cascade" them so that part of each window is visible, and when any of them are clicked I can easily click back to another window, meaning that no one window is ever lost behind another.

Here's the idea:

enter image description here

This involves both repositioning each window on the X and Y axis of the screen and resizing each window. to be the same size.

  • Is there any way to do this natively within the Mac OS?
  • Are there any apps that can achieve this functionality?

Update:

Tried the Hammerspoon solution and got the error below. It did move all my windows from the external monitor to the MacBook, and it didn't really cascade.

enter image description here

3 Answers

I don't know of any way to do this natively, aside from Mission Control.

Hammerspoon is a low-level automation tool which is great for this type of thing, if a little clumsy. It exposes many OS-level operations to a Lua scripting engine, including positioning of windows, among very many other things.

To implement this functionality in Hammerspoon, you could do something like:

function cascadeWindows() local windows = hs.window.allWindows() local screen = windows[1]:screen():frame() local xMargin, yMargin = screen.w/5, screen.h/5 -- This is equal to the gap between the edge of the topleft window and the edge of the screen. local layout = {} for i, win in ipairs(windows) do local winPos = { win:application(), win:title(), win:screen(), nil, hs.geometry.rect( (i-1)*(xMargin/(#windows-1)), -- x (i-1)*(yMargin/(#windows-1)), -- y, you might end up having to add some number here screen.w - xMargin, -- w screen.h - yMargin -- h ), nil } layout[#layout+1] = winPos end hs.layout.apply(layout)
end
hs.hotkey.bind({'cmd','alt','ctrl'}, 'space', cascadeWindows)

This code has been loosely tested, but should work as a starting point. To install, first install Hammerspoon, then put this code into your ~/.hammerspoon/init.lua file. You can find more information on exactly what is happening up there in the documentation for hs.layout.apply, and more generally in the Hammerspoon documentary.

If you don't know Lua and don't want to learn Lua (It's quick and easy!), or don't want to get involved in learning a new tool as deep as Hammerspoon, you can just follow the above instructions changing the key binding to whatever you want.

1

There is a native solution which doesn't require any 3rd party tools or running any scripts.

From the Window menu, hold down Option and click Arrange in Front. This will do exactly what you want, cascading all the windows as your diagram shows. It sorts them in alphabetical order.

Note that, it won't seem to work if the windows are the same size as the screen. Try it out by resizing a few windows first.

1

I was just looking for the same thing myself and came up with my own Hammerspoon solution:

hs.hotkey.bind({'cmd','alt','ctrl'}, ',', function() local windows = hs.window.orderedWindows() local screen = windows[1]:screen():frame() local nOfSpaces = #windows > 1 and #windows - 1 or 1 local xMargin = screen.w / 10 -- unused horizontal margin local yMargin = 20 -- unused vertical margin local spacing = 40 -- the visible margin for each window for i, win in ipairs(windows) do local offset = (i - 1) * spacing local rect = { x = xMargin + offset, y = screen.y + yMargin + offset, w = screen.w - (2 * xMargin) - (nOfSpaces * spacing), h = screen.h - (2 * yMargin) - (nOfSpaces * spacing), } win:setFrame(rect) end
end)

I'm quite satisfied with it so far. You may also be interested in the rest of my Hammerspoon config:

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like