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

17

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

    
задан Moiz 16.12.2008 в 23:33
источник

4 ответа

22

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

#!/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 с использованием кода Питера в качестве отправной точки.

    
ответ дан Dirk Stoop 17.12.2008 в 01:44
источник
12

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

from AppKit import NSWorkspace
active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
print(active_app_name)
    
ответ дан kmundnic 09.08.2014 в 02:20
источник
6

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

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

Чтобы получить активное окно в 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 в любом случае.

    
ответ дан Peter Hosey 17.12.2008 в 00:52
источник
1

Мне понадобилось текущее приложение на самом верхнем уровне в скрипте Python, который удобно устраивает окна на моем экране (см. 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

    
ответ дан SirVer 03.01.2012 в 21:04
источник