Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua

Home Page:http://www.hammerspoon.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

  1. Open about:profiles in a firefox window
  2. Create a new profile
  3. 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