Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get active window title using Python in Mac?

Tags:

python

macos

I am trying to write the Python script which prints the title of the active window using python in Mac OS.

Here is my code:

from AppKit import NSWorkspace
active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
print active_app_name

This code just prints name of the app like Google chrome or firefox, but not title. How to get title of the window?

like image 657
Bharath Avatar asked Mar 02 '15 17:03

Bharath


3 Answers

Here is what I used to find both the active application name and window title on Mac OS X using Python by using Quartz API.

First of all, we need to add imports as required:

if sys.platform == "darwin":
    import applescript
    from AppKit import NSWorkspace
    from Quartz import (
        CGWindowListCopyWindowInfo,
        kCGWindowListOptionOnScreenOnly,
        kCGNullWindowID
    )

And then we can get the active app name and window title via the code below:

def getActiveInfo(event_window_num):
    try:
        if sys.platform == "darwin":
            app = NSWorkspace.sharedWorkspace().frontmostApplication()
            active_app_name = app.localizedName()

            options = kCGWindowListOptionOnScreenOnly
            windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID)
            windowTitle = 'Unknown'
            for window in windowList:
                windowNumber = window['kCGWindowNumber']
                ownerName = window['kCGWindowOwnerName']
                # geometry = window['kCGWindowBounds']
                windowTitle = window.get('kCGWindowName', u'Unknown')
                if windowTitle and (
                                event_window_num == windowNumber
                        or ownerName == active_app_name
                ):
                    # log.debug(
                    #     'ownerName=%s, windowName=%s, x=%s, y=%s, '
                    #     'width=%s, height=%s'
                    #     % (window['kCGWindowOwnerName'],
                    #        window.get('kCGWindowName', u'Unknown'),
                    #        geometry['X'],
                    #        geometry['Y'],
                    #        geometry['Width'],
                    #        geometry['Height']))
                    break

            return _review_active_info(active_app_name, windowTitle)
        if sys.platform == "win32":
            (active_app_name, windowTitle) = _getActiveInfo_Win32()
            return _review_active_info(active_app_name, windowTitle)
    except:
        log.error('Unexpected error: %s' % sys.exc_info()[0])
        log.error('error line number: %s' % sys.exc_traceback.tb_lineno)
    return 'Unknown', 'Unknown'
like image 79
Jake W Avatar answered Sep 24 '22 13:09

Jake W


There is no access to app title from NSWorkspace.sharedWorkspace().activeApplication().

But you can find the current window title by its PID:

For example:

from AppKit import NSWorkspace
pid = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationProcessIdentifier']

Then find the right window using below code (it's stored in kCGWindowOwnerPID) as shown in below code:

Here is a complete shell example based on @JakeW's script:

#!/usr/bin/python
# Prints list of windows in the current workspace.
import sys
if sys.platform == "darwin":
    from AppKit import NSWorkspace
    from Quartz import (
        CGWindowListCopyWindowInfo,
        kCGWindowListOptionOnScreenOnly,
        kCGNullWindowID
    )

if sys.platform == "darwin":
    curr_app = NSWorkspace.sharedWorkspace().frontmostApplication()
    curr_pid = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationProcessIdentifier']
    curr_app_name = curr_app.localizedName()
    options = kCGWindowListOptionOnScreenOnly
    windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID)
    for window in windowList:
        pid = window['kCGWindowOwnerPID']
        windowNumber = window['kCGWindowNumber']
        ownerName = window['kCGWindowOwnerName']
        geometry = window['kCGWindowBounds']
        windowTitle = window.get('kCGWindowName', u'Unknown')
        if curr_pid == pid:
            print("%s - %s (PID: %d, WID: %d): %s" % (ownerName, windowTitle.encode('ascii','ignore'), pid, windowNumber, geometry))
elif sys.platform == "win32":
    (active_app_name, windowTitle) = _getActiveInfo_Win32()

It will list details of the current active window including its title.

like image 27
kenorb Avatar answered Sep 21 '22 13:09

kenorb


As of macOS 10.6 and later it is better to use: frontmostApplication and if you want to get all of the applications listed you can call runningApplications method.

You can see more details at https://developer.apple.com/documentation/appkit/nsworkspace#overview

For example:

from AppKit import NSWorkspace
NSWorkspace.sharedWorkspace().runningApplications() // for getting all applications
NSWorkspace.sharedWorkspace().frontmostApplication() // for active window
like image 44
Shay Dahan Avatar answered Sep 25 '22 13:09

Shay Dahan