Apple Never Fixed This Bug, so I Did It Myself
plz fix macOS bug Apple š„ŗ
--
Rewind back to August 2022. I was super hyped up for the upcoming college year, so much so that I got myself a new monitor to avoid another semester stuck working on my puny 13-inch MacBook screen.
I ended up with one of AOCās low-latency monitors, given Iāve never had the glorious and fabled 120Hz+ experience on any desktop OS. I didnāt even care that I was getting a gaming monitor for my MacBook (an M1 mac canāt run any real games apart from LoL or CS:GO, mind you). Man, I just wanted all my window dragging and scrolling to be smooth like butter (ā¦ like a criminal undercover).
A week later, after a stroll to Georgia Techās Amazon locker, I was in business. Oh, how breathtaking! The swift elegance of a windowās movement as I dragged it round and round, the way the infamous UFO virtually flows like water across the monitor!
All went so well, until I switched Spaces.
Thatās odd, the animation is taking a bit longer than usual. **Proceed to switch between spaces a few more times. Disconnect from the monitor, try switching spaces again on my laptop, and now maybe plug it back to see if it works? Okayā¦yep.**
The animation IS longer than usual. MUCH LONGER.
Go see for yourself (thanks u/mort96):
Time to return the monitor.
(just kidding, but bruh.)
Alright, Hear Me Out
Youād think Iām whining nonsense. Well, 300+ other Mac users have also noticed and have been fuming over this problem for years now. Itās even worse for the ones who bought one of the newer MBP models with their ProMotion displays; theyāre stuck with this dang problem from the get go.
Ok, maybe Iām clinically insane for being this obsessed over macOS Spaces. The first part might be true, but ever since Iāve switched to team Apple my workflow has solidified and revolved over the use of multiple spaces (I used to be an i3 fanboy, and i3 workspaces == macOS Spaces).
āBut, can you enable āReduced Motionā on System Settings š¤āļø?ā
Nope. That annoying delay is still there when you switch spaces with a higher refresh-rate monitor. Not to mention that macOS with reduced motion really ruins the feel of the OS ā I want all my JUICY animations! (yeah, and I was an i3 user...)
Apple?
Great. This has been a bug thatās been on macOS forever, and a decent number of people have caught on. No way Apple will leave this bug untouched for us avid macOS usersā¦right? Right?
Soā¦ Iāve waited a whole year for Apple to apply a quick patch, and lo and behold, nothing. Donāt get it twisted, I have not the slightest clue in operating system development, but I canāt imagine it being harder than changing some variable to a constant. What gives?
This was becoming a real bruh moment. I went through two college semesters, wasting precious milliseconds every time I went ahead and switched spaces. I couldāve contributed yet another Javascript framework to open source with all that time gone >:(
Fine, then. Iāll fix it myself.
My Hack-ish Fix
READ FIRST
My āhackā does NOT fix the delay for the gesture trigger (triple finger swipe). It only works for the keyboard shortcut (ā[Ctrl] + Left/Right arrow). However, you can look into using BetterTouchTool with yabai, though youāll need to disable macOS System Integrity Protection.
Also, I canāt verify if this works in a multi-monitor setup ā I never use my external monitor and my laptop screen at the same time. You may need some changes on following instructions/code based on how your displays and spaces settings are configured.
Now, onward!
1. Stop macOS from automatically rearranging spaces
For some crazy reason, your Mac ā by default ā rearranges the order of your spaces based on when youāve last used them.
Disable that by going to System Settings > Desktop & Dock > Scroll down to Mission Control > Unselect āAutomatically rearrange Spaces based on most recent useā
If you actually use spaces with this on, youāre weird. Please get some help, Iām rooting for you.
2. Configure keyboard shortcuts for each space
Pressing ā[Ctrl] + 1 swaps you to your first space/desktop by macOS defaults, regardless of which space you were in before. ā[Ctrl] + 2 brings you to the second space, and so on. Double check that you have these shortcuts by going to Keyboard > Keyboard Shortcuts > Mission Control.
While youāre at it, disable the āMove left/right a spaceā shortcuts, and change them to something obscure (it doesnāt matter what the new shortcut is, as long as itās not the default). Trust me, weāll override these shortcuts later with another tool.
The core trick to the fix is realizing that switching spaces with these keybinds takes less animation time than using āMove left/right a spaceā. Try it yourself if you donāt believe me.
3. Get Hammerspoon
Hammerspoon basically lets us control or automate macOS at the system level through Lua code. Think of it as an API for almost everything macOS.
Youāll want to follow the siteās directions to install Hammerspoon. It doesnāt do anything out of the box, since you need to create a script file in the proper folder. To do this, run this following command:
$ mkdir ~/.hammerspoon && touch ~/.hammerspoon/init.lua
Youāll then need to open this file using a code editor.
4. Hammerspoon code
Letās lay out the blueprint. Whenever we trigger space switching to happen, we want to:
- Figure out which space ānumberā we are currently on
- Determine if it can swap to the next/previous numbered space
- Send the ā[Ctrl] + <Number> shortcut to macOS
Luckily for you, Iāve figured it all out with this (pretty wacky) Lua code right here, so you can copy & paste this to your init.lua
file:
--- needed to auto-reload this config file after saving
function reloadConfig(files)
local doReload = false
for _,file in pairs(files) do
if file:sub(-4) == ".lua" then
doReload = true
end
end
if doReload then
hs.reload()
end
end
myWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reloadConfig):start()
hs.alert.show("Config loaded")
function focusedWindowSpaces()
local window = hs.window.focusedWindow()
local displayUUID = window:screen():getUUID()
local activeSpace = hs.spaces.activeSpaceOnScreen()
return window, activeSpace, hs.spaces.allSpaces()[displayUUID]
end
function getAdjacentSpace(right, currSpace, currSpaces)
if right then
adj = 1
else
adj = -1
end
for i = 1, #currSpaces do
if currSpace == currSpaces[i] then
if i + adj < 1 and i + adj > #currSpaces then
return nil
else
return currSpaces[i + adj], i + adj
end
end
end
end
hs.hotkey.bind("ctrl", "left", function()
-- get current window and space layout
window, currSpace, currSpaces = focusedWindowSpaces()
-- get current space and relative left space
newSpace, i = getAdjacentSpace(false, currSpace, currSpaces)
if newSpace == nil then return end
-- move perspective to left space
hs.eventtap.keyStroke({"ctrl"}, ""..i)
end)
hs.hotkey.bind("ctrl", "right", function()
-- get current window and space layout
window, currSpace, currSpaces = focusedWindowSpaces()
-- get current space and relative right space
newSpace, i = getAdjacentSpace(true, currSpace, currSpaces)
if newSpace == nil then return end
-- move perspective to right space
hs.eventtap.keyStroke({"ctrl"}, ""..i)
end)
Save these changes to init.lua
, and youāll see that your original ā[Ctrl] + Left/Right shortcuts will work again. More importantly, that darn delay is gone!
5. (Optional) A cherry on top
I swap between spaces really often, but I also find it really common that Iāll want to switch to another space while bringing a window along with me. You can go to Mission Control, slowly drag that window to the neighboring space, and finally switch spacesā¦yeah, super boring.
Or, you can bind all that to just one shortcut by adding this to init.lua
:
hs.hotkey.bind({"ctrl", "shift"}, "left", function()
-- get current window and space layout
window, currSpace, currSpaces = focusedWindowSpaces()
-- get current space and relative left space
newSpace, i = getAdjacentSpace(false, currSpace, currSpaces)
if newSpace == nil then return end
-- move window and perspective to left space
hs.spaces.moveWindowToSpace(window:id(), newSpace)
hs.eventtap.keyStroke({"ctrl"}, ""..i)
end)
hs.hotkey.bind({"ctrl", "shift"}, "right", function()
-- get current window and space layout
window, currSpace, currSpaces = focusedWindowSpaces()
-- get current space and relative right space
newSpace, i = getAdjacentSpace(true, currSpace, currSpaces)
if newSpace == nil then return end
-- move window and perspective to right space
hs.spaces.moveWindowToSpace(window:id(), newSpace)
hs.eventtap.keyStroke({"ctrl"}, ""..i)
end)
Now, ā[Ctrl] + Shift + arrow keys are bound to this super powerful combination of actions. Iām not sure about you, but moving windows to different spaces using shortcuts on macOS is pretty dope.
Enjoy!
With Hammerspoon and about 100 lines of Lua, I just hacked myself out of this macOS Spaces bug that has been bugging me for about a year now. Not too shabby, Iāll call it a win!
Itāll take a bit of getting used to the new animation and the shortcuts managed by Hammerspoon. If you ever feel like spamming these shortcuts, I actually find it faster to pause a bit between each shortcut trigger if you really want to quickly sift through your spaces.
Otherwise, I canāt wait for a future macOS update to make this article instantly obsolete. Iām counting on you, Apple!