-
Notifications
You must be signed in to change notification settings - Fork 639
Description
Function of this script
This script monitors the number of active Finder windows. Upon detecting two or more windows, it executes the ⌘U shortcut to consolidate them.
What I try to solve
However, as Aerospace segregates windows into distinct virtual workspaces, the script invokes an Aerospace command to migrate all non-focused windows to the currently active virtual workspace whenever a new window is generated.
Bug
A flaw in the implementation intermittently prevents certain windows from successfully relocating to the designated workspace.
In the console I see hs.application:allWindows() only returned the newest Finder window and the last created windows(That is 2 windows) even when I have 4 to 5 finder windows.
Fix Attempt
Attempt 1: Added delay before workspace migration → ==no dice==
Attempt 2: Reversed sequence:
- Option A: Aerospace move then ⌘U
- Option B: ⌘U then Aerospace move
==Both paths lead to failville==.
==Code==
local wf = hs.window.filter.new(false):setAppFilter('Finder')
local function sh_quote(s)
return "'" .. tostring(s):gsub("'", "'\\''") .. "'"
end
wf:subscribe(hs.window.filter.windowCreated, function(window, appName, eventName)
local app = hs.application.find(appName)
if not app then return end
local windows = app:allWindows()
for _, n in pairs(windows) do
print(string.format("finder windows: %s (ID: %d)", n:title(), n:id()))
end
-- The loop prints
-- 2025-09-14 12:47:58: finder windows: /Users/acid/Downloads/UniDL (ID: 32953)
-- 2025-09-14 12:47:58: finder windows: /Users/acid/Downloads/UniDL (ID: 32931)
-- 2025-09-14 12:47:58: finder windows: (ID: 0)
-- I create one Finder window in each virtual workspace (aerospace) and check if they're sent to the most recently focused workspace.
-- Looks like allWindows only captures the newest Finder window and the last created windows each time windowCreated was triggered.
-- Any idea what's causing this? How can I solve it?
if #windows >= 2 then
hs.eventtap.keyStroke({"cmd"}, "u", app) --I use cmd u to group all finder windows
end
local raw = hs.execute("aerospace list-workspaces --focused", true) or ""
local workSpaceName = raw:match("([^\r\n]+)") or ""
workSpaceName = workSpaceName:match("^%s*(.-)%s*$") or ""
if workSpaceName == "" then
hs.alert.show("Unable to fetch current workspace")
return
end
for _, win in ipairs(windows) do
local wid = tostring(win:id())
if wid and wid ~= 0 then
local cmd = string.format("aerospace move-node-to-workspace --window-id %s %s", wid, sh_quote(workSpaceName))
hs.execute(cmd, true)
end
end
end)