Using hammerspoon to move windows between spaces with shortcuts on MacOS
Since moving to MacOS as my default work os ~2 years ago, I've tried to find a consistent way to achieve all of my usual linux workflows with shortcuts. I got everything working right away except moving windows between spaces. Most articles online tell you to grab the title bar and switch spaces using the built in space navigation shortcuts. This works, but still requires using your mouse. If you're trying to develop "keyboard only" workflows, this guide should sort you out.
By the end of this guide, you will be able to send the currently focused window to another space with the shortcut cmd+shift+1-6
The steps are:
~/.hammerspoon/init.lua
Hammerspoon is a macos scripting utility which provides a number of nice utilities for macos exposed via the lua scripting language. In hammerspoon's 1.0.0version, they added an api for moving windows between spaces. To install hamerspoon, you can either download it from the github, or install it using brew.
Copy the following script into ~/.hammerspoon/init.lua Please refer to the hammerspoon docs for info on what is happening in this script.
-- Set up the logger
local log = hs.logger.new('WindowMover', 'info')
-- Function to get spaceId by space name
function getSpaceIdByName(spaceName)
local spaceNames = hs.spaces.missionControlSpaceNames()
for uuid, desktops in pairs(spaceNames) do
log.i("UUID: " .. uuid) -- Log the UUID
for index, name in pairs(desktops) do
log.i("Index: " .. index .. ", Name: " .. tostring(name)) -- Log the index and name
if name == spaceName then
log.i("Found spaceId for " .. spaceName .. ": " .. index)
return index
end
end
end
log.w("Space not found: " .. spaceName)
return nil
end
-- Function to move focused window to a specific space
function moveFocusedWindowToSpace(spaceNumber)
local spaceName = "Desktop " .. spaceNumber
log.i("Attempting to move window to " .. spaceName)
local spaceId = getSpaceIdByName(spaceName)
if spaceId then
local focusedWindow = hs.window.focusedWindow()
if focusedWindow then
log.i("Moving window " .. focusedWindow:title() .. " to spaceId " .. spaceId)
hs.spaces.moveWindowToSpace(focusedWindow:id(), spaceId)
else
log.w("No focused window")
hs.alert.show("No focused window")
end
else
log.w("Space not found: " .. spaceName)
hs.alert.show("Space not found: " .. spaceName)
end
end
-- Bind keys cmd + shift + 1-6
for i = 1, 6 do
hs.hotkey.bind({"cmd", "shift"}, tostring(i), function()
log.i("Hotkey pressed: cmd + shift + " .. i)
moveFocusedWindowToSpace(i)
end)
end
post questions in the X thread below: questions