1

I was wondering if there is a way to programatically get a list of all windows on the screen, including windows that are outside the current application.

I will explain what I am trying to achieve. I am a linux user who recently started using a mac. I was using the fluxbox desktop manager on linux. When switching between windows, instead of pressing alt+tab repeatedly to cycle to the desired window, I was able to modify fluxbox to jump directly to the window I want. I was able to do that because fluxbox is opensource, I modified the code, setup a shortcut to give focus to a specific opened window of my choice.

I am trying to achieve the same thing on mac and I was wondering if that is even possible. It seems I can access the windows that are owned by my application, but I can't access the windows owned by other applications

I experimented with the Core Graphics library by following this post

  • I first use CGWindowListCopyWindowInfo to a get a list of CGWindowId
  • Next I use [NSApp windowWithWindowNumber:windowId] to get a NSWindow. But the NSWindow I get are nil except for windows that are owned by my application.

Is this the way mac is designed and we cannot access windows outside of our own application ? Or is there a way around that ? I am wondering how GUI automation tools work on Mac if Mac is designed to prevent an application from controlling windows of other applications.

RichardT
  • 375
  • 3
  • 12
  • 1
    You can't get an `NSWindow` handle from other processes' windows. `NSApp` refers to your own application. From your linked post - I would follow the suggestion of using the Accessibility API. – TheNextman Dec 11 '19 at 20:20

1 Answers1

3

The tool you likely want here is AppleScript. As an example of how you'd gather this, this script collects the names of all the windows and displays them in a dialog:

set names to {}
tell application "System Events"
    repeat with theProcess in processes
        if not background only of theProcess then
            tell theProcess
                set processName to name
                set theWindows to windows
                repeat with theWindow in theWindows
                    set end of names to (processName & ":\"" & (name of theWindow) & "\"")
                end repeat
            end tell
        end if
    end repeat
end tell

set AppleScript's text item delimiters to "
"
display dialog names as text
set AppleScript's text item delimiters to ""
Rob Napier
  • 286,113
  • 34
  • 456
  • 610