Поиск текущего активного окна в Mac OS X с использованием Python

Есть ли способ найти имя приложения текущего активного окна в данный момент в Mac OS X с помощью Python?

Ответ 1

Это должно работать:

#!/usr/bin/python

from AppKit import NSWorkspace
activeAppName = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationName']
print activeAppName

Работает только на Leopard или на Tiger, если у вас установлен PyObjC, и он указывает на правильный двоичный код python в строке 1 (не тот случай, если вы установили универсальный MacPython, который вы, вероятно, захотите сделать на Tiger). Но Питер ответит, что Carbon делает это, вероятно, будет намного быстрее, поскольку импорт чего-либо из AppKit в Python занимает некоторое время, или, точнее, импорт чего-либо из AppKit в первый раз в процессе Python занимает некоторое время.

Если вам нужно это в приложении PyObjC, то то, что я описываю, будет работать отлично и быстро, так как вы испытываете только задержку импорта AppKit один раз. Если вам нужно, чтобы это работало как инструмент командной строки, вы заметите поражение производительности. Если это относится к вам, вам, вероятно, лучше построить 10-строчный инструмент командной строки Foundation в Xcode, используя в качестве отправной точки код Peter.

Ответ 2

Метод в принятом ответе был устаревшим в OS X 10.7+. Текущая рекомендуемая версия будет следующей:

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

Ответ 3

Во-первых, вы хотите окно или имя приложения? Это не Windows-процесс приложения в Mac OS X может иметь несколько окон. (Кроме того, это также относится к Windows уже несколько лет, хотя я не знаю, как выглядит API для этого.)

Во-вторых, углерод или Cocoa?

Чтобы получить активное окно в Cocoa:

window = NSApp.mainWindow()

Чтобы получить имя вашего процесса в Cocoa:

appName = NSProcessInfo.processInfo().processName()

Изменить: О, я думаю, я знаю, чего вы хотите. Имя самого первого процесса, не так ли?

Я не думаю, что есть способ сделать это в Cocoa, но вот как это сделать в Carbon in C:

ProcessSerialNumber psn = { 0L, 0L };
OSStatus err = GetFrontProcess(&psn);
/*error check*/

CFStringRef processName = NULL;
err = CopyProcessName(&psn, &processName);
/*error check*/

Запомните CFRelease(processName), когда закончите с ним.

Я не уверен, что это будет выглядеть на Python, или если это возможно. Python не имеет указателей, что делает это сложным.

Я знаю, что PyObjC переведет последний аргумент CopyProcessName в err, processName = CopyProcessName(…), но привязки Carbon не полагаются на PyObjC (они являются частью основного Python 2), и я не уверен, что вы делаете о PSN в любом случае.

Ответ 4

Мне понадобилось текущее самое ближайшее приложение в Python script, который хорошо устраивает окна на моем экране (см. move_window).

Конечно, полный кредит принадлежит Питеру! Но вот полная программа:

#include <Carbon/Carbon.h>

int main(int, char) {
    ProcessSerialNumber psn = { 0L, 0L };
    OSStatus err = GetFrontProcess(&psn);

    CFStringRef processName = NULL;
    err = CopyProcessName(&psn, &processName);
    printf("%s\n", CFStringGetCStringPtr(processName, NULL));
    CFRelease(processName);
}

Построить с помощью gcc -framework Carbon filename.c