Cannot get all windows across all spaces for multi-instance applications (like firefox with profiles)
acheronfail opened this issue · comments
Goal
I want to find all windows for all applications including multi-instance applications, across all spaces.
Problem
Using hs.application.applicationsForBundleID
, I can only get all windows on the current space.
Using hs.window.filter
, I can get all windows across all spaces, with the exception of apps that share the same bundleID
. In my case, this is two instances of Firefox (using Firefox's profiles).
Summary:
Hammerspoon API | Gets windows from all spaces | Gets windows from all apps |
---|---|---|
hs.application.applicationsForBundleID |
No ❌ | Yes ✅ |
hs.window.filter |
Yes ✅ | No ❌ |
Is there a way to get all windows, from all running apps, across all spaces?
Reproduction
Open an app in Multi-Instance mode
This example uses Firefox as the multi-instance app. If you haven't created another profile in Firefox, follow these steps:
- Open
about:profiles
in a firefox window - Create a new profile
- When launching firefox, run
/Applications/Firefox Nightly.app/Contents/MacOS/firefox -P "$PROFILE_NAME"
Following the above steps, you'll have two instances of Firefox, but they're running separate profiles.
Run this Hammerspoon script
-- example script for issue
local bundleID = "org.mozilla.nightly" -- or any app that runs in multi-instance mode
local count = 0
-- gets all the apps running with `bundleID`, and all their windows
-- NOTE: has the limitation that it only detects windows on the current space
print(">>> hs.application.applicationsForBundleID <<<")
for _, app in pairs(hs.application.applicationsForBundleID(bundleID)) do
for _, win in pairs(app:allWindows()) do
count = count + 1
print(count, win:title())
end
end
print(">>> total windows found: " .. count)
count = 0
-- gets all windows across all spaces
-- NOTE: has the limitation that it only detects the first app running in multi-instance mode
-- (it's unaware of any other apps with the same bundle id)
print(">>> hs.window.filter <<<")
local windowFilter = hs.window.filter.new(true)
for _, win in pairs(windowFilter:getWindows()) do
local app = win:application()
if app and app:bundleID() == bundleID then
count = count + 1
print(count, win:title())
end
end
print(">>> total windows found: " .. count)
When running the script on a space with both instances of Firefox open:
$ hs ~/.hammerspoon/issue.lua
>>> hs.application.applicationsForBundleID <<<
1 DuckDuckGo — Privacy, simplified.
2 Hammerspoon docs: hs.application
>>> total windows found: 2
>>> hs.window.filter <<<
1 DuckDuckGo — Privacy, simplified.
>>> total windows found: 1
When running the script on a space without Firefox on it:
$ hs ~/.hammerspoon/issue.lua
>>> hs.application.applicationsForBundleID <<<
>>> total windows found: 0
>>> hs.window.filter <<<
1 DuckDuckGo — Privacy, simplified.
>>> total windows found: 1