13

At work I have a 3 monitor setup. I would like to move the current application to a second or a third monitor with a key binding. How to do that?

6 Answers 6

28

I use the following script to cycle the focused window through the screens.

-- bind hotkey hs.hotkey.bind({'alt', 'ctrl', 'cmd'}, 'n', function() -- get the focused window local win = hs.window.focusedWindow() -- get the screen where the focused window is displayed, a.k.a. current screen local screen = win:screen() -- compute the unitRect of the focused window relative to the current screen -- and move the window to the next screen setting the same unitRect win:move(win:frame():toUnitRect(screen:frame()), screen:next(), true, 0) end) 
Sign up to request clarification or add additional context in comments.

Comments

16

The screen library helps finding the right "display". allScreens lists the displays in the same order as they are defined by the system. The hs.window:moveToScreen function moves to a given screen, where it's possible to set the UUID.

The following code works for me. Hitting CTRL+ALT+CMD+ 3 moves the currently focused window to display 3, same as if you would choose "Display 3" in the Dock's Option menu.

function moveWindowToDisplay(d) return function() local displays = hs.screen.allScreens() local win = hs.window.focusedWindow() win:moveToScreen(displays[d], false, true) end end hs.hotkey.bind({"ctrl", "alt", "cmd"}, "1", moveWindowToDisplay(1)) hs.hotkey.bind({"ctrl", "alt", "cmd"}, "2", moveWindowToDisplay(2)) hs.hotkey.bind({"ctrl", "alt", "cmd"}, "3", moveWindowToDisplay(3)) 

1 Comment

This is good but you need to know here which screen if first, second etc...
6

Not exactly the answer to OP but leaving this here for others who also want to cycle through monitors and maximize on each screen:

local app = hs.window.focusedWindow() app:moveToScreen(app:screen():next()) app:maximize() 

You can put this in a function and bind it to Ctrl + Alt + n like so:

function moveToNextScreen() local app = hs.window.focusedWindow() app:moveToScreen(app:screen():next()) app:maximize() end hs.hotkey.bind({"ctrl", "alt"}, "n", moveToNextScreen) 

Comments

3

I've answered this in Reddit post here, but in case anyone comes across this question here's the answer:

The Hammerspoon API doesn't provide an explicit function for doing this, so you gotta roll out with a custom implementation to achieve this:

-- Get the focused window, its window frame dimensions, its screen frame dimensions, -- and the next screen's frame dimensions. local focusedWindow = hs.window.focusedWindow() local focusedScreenFrame = focusedWindow:screen():frame() local nextScreenFrame = focusedWindow:screen():next():frame() local windowFrame = focusedWindow:frame() -- Calculate the coordinates of the window frame in the next screen and retain aspect ratio windowFrame.x = ((((windowFrame.x - focusedScreenFrame.x) / focusedScreenFrame.w) * nextScreenFrame.w) + nextScreenFrame.x) windowFrame.y = ((((windowFrame.y - focusedScreenFrame.y) / focusedScreenFrame.h) * nextScreenFrame.h) + nextScreenFrame.y) windowFrame.h = ((windowFrame.h / focusedScreenFrame.h) * nextScreenFrame.h) windowFrame.w = ((windowFrame.w / focusedScreenFrame.w) * nextScreenFrame.w) -- Set the focused window's new frame dimensions focusedWindow:setFrame(windowFrame) 

Wrapping the snippet above in a function and binding it to a hotkey should cycle the currently focused application across your different monitors.

Comments

1

Another way to move the window around is to use the directional move functions, e.g. win:moveOneScreenEast() and the like (there's one function for each direction). I find it useful to bind arrow keys to effect mnemonic keyboard shortcuts.

hs.hotkey.bind({'alt', 'ctrl', 'cmd'}, 'Right', function() local win = hs.window.focusedWindow() win:moveOneScreenEast(false, true, 0.5) end) hs.hotkey.bind({'alt', 'ctrl', 'cmd'}, 'Left', function() local win = hs.window.focusedWindow() win:moveOneScreenWest(false, true, 0.5) end) 

Reference: http://hammerspoon.org/docs/hs.window.html#moveOneScreenEast

Comments

0

Other answers to date seem to all be limited to moving windows, not complete applications as the question asks. Below is what I use, bound to a key combo using hs.hotkey.bind() as others note.

local function moveAppWindow() -- Move visible windows - including popups, modals, floating - from same screen as -- focused window. (Only standard windows misses those apps that annoyingly start -- as popups.) local focusedWindow = hs.window.focusedWindow() local focusedApp = focusedWindow:application() if focusedApp then local screens = hs.screen.allScreens() if #screens > 1 then local windows = focusedApp:allWindows() local initialScreen = focusedWindow:screen() local destinationScreen = nextScreen(initialScreen) for _, w in ipairs(windows) do if w:screen() == initialScreen and w:isVisible() then w:moveToScreen(destinationScreen, true, true) end end else focusedWindow:centerOnScreen(nil, true) end end end 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.