Получение pid и деталей для верхнего окна - PullRequest
17 голосов
/ 11 января 2010

Кто-нибудь знает, как получить PID верхнего активного окна, а затем, как получить свойства окна, используя PID? Я имею в виду свойства, такие как имя процесса, имя программы и т. Д.

Я использую Qt под Linux (Ubuntu 9.10).

Ответы [ 8 ]

24 голосов
/ 12 января 2010

в linux есть команда call xprop, которая является утилитой для отображения свойств окна на X-сервере. В Linux xprop -root предоставляет вам свойства корневых окон, а также другие активные программы. тогда вы можете получить идентификатор активного окна с помощью этой команды:

xprop -root | grep _NET_ACTIVE_WINDOW\(WINDOW\)

чтобы получить просто идентификатор активного окна (без "_NET_ACTIVE_WINDOW (WINDOW): идентификатор окна №" в начале строки) используйте эту команду:

xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}'

теперь вы можете сохранить выходные данные этой команды в определенной пользователем переменной:

myid=xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}'

xprop имеет атрибут call -id. Этот аргумент позволяет пользователю выбрать идентификатор окна в командной строке. Мы должны искать _NET_WM_PID (CARDINAL) в выводе ... поэтому мы используем эту команду:

xprop -id $myid | awk '/_NET_WM_PID\(CARDINAL\)/{print $NF}'

это дает вам самый верхний активный идентификатор окна процесса.

чтобы быть хитрее и делать все за 1 команду ...:

 xprop -id $(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}') | awk '/_NET_WM_PID\(CARDINAL\)/{print $NF}'

Теперь я могу запускать эти команды через мою программу на C ++ (в linux) с помощью функции popen, получить стандартный вывод и распечатать или сохранить его. popen создает канал, чтобы мы могли прочитать выходные данные вызываемой программы.

(вы также можете использовать файловую систему '/ proc' и получить более подробную информацию о PID ('/ proc / YOUR_PID / status'))

#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;

inline std::string exec(char* cmd) {
    FILE* pipe = popen(cmd, "r");
    if (!pipe) return "ERROR";
    char buffer[128];
    std::string result = "";
    while(!feof(pipe)) {
        if(fgets(buffer, 128, pipe) != NULL)
                result += buffer;
    }
    pclose(pipe);
    return result;
}

int main()
{
    //we uses \\ instead of \ ( \ is a escape character ) in this string
 cout << exec("xprop -id $(xprop -root | awk '/_NET_ACTIVE_WINDOW\\(WINDOW\\)/{print $NF}') | awk '/_NET_WM_PID\\(CARDINAL\\)/{print $NF}'").c_str(); 
 return 0;
}
19 голосов
/ 11 января 2010

Одна из особенностей X - прозрачность сети. Вполне возможно, что фактическое окно, отображаемое вверху (которое имеет фокус), работает на машине, отличной от вашей, в этом случае идентификатор процесса, выполняющегося внутри окна, не будет иметь смысла на вашей машине. *

Не могли бы вы немного рассказать о том, что вы хотите сделать? Я думаю, что здесь есть некоторые недостающие детали. В идеале вы должны работать на уровне X, а не на уровне конкретной машины.

5 голосов
/ 02 ноября 2012

Я очень опаздываю на вечеринку, но у меня была похожая проблема, и я думаю, что это может помочь кому-то еще, кто имеет такую ​​же проблему. Для этого есть хитрость командной строки, вы можете попробовать выполнить execvp или выполнить его, перенаправив вывод в ваш код

xprop -id $(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5) _NET_WM_NAME WM_CLASS

дает имя окна, а также имя программы. Например, для этой вкладки она дает мне

_NET_WM_NAME(UTF8_STRING) = "linux - Getting pid and details for topmost window - Stack Overflow - Mozilla Firefox"

WM_CLASS(STRING) = "Navigator", "Firefox"
5 голосов
/ 11 января 2010

xlib's XGetInputFocus скажет вам, какое окно имеет фокус, что, вероятно, более интересно, чем верхнее. Ср Руководство пользователя Xfree86 XGetInputFocus .

Если это действительно верхнее окно, а не окно с фокусом, к которому вы стремитесь, ну, я не думаю, что для этого есть простой вызов, потому что xlib, похоже, не предлагает никакого способа запрос глобального порядка стека, который представляет собой структуру данных, которая сообщает вам, какие окна перед какими, а какие другими.

Если у вас есть правильный идентификатор окна, xprop отобразит pid в _NET_WM_PID_, хотя не у всех окон есть такое свойство ...

Постскриптум Больше мыслей; Давно я не думал о xlib ...

Подведем итог:

  1. X не предлагает надежной связи между идентификаторами окон и идентификаторами окон, и, как отмечает Нуфал, окна, обслуживаемые на рабочем столе X, могут приходить с разных компьютеров, и два удаленных клиента могут использовать один и тот же PID так как он уникален только для каждой машины. Ср Как получить окно X11 из идентификатора процесса?

  2. X, похоже, не предлагает интерфейс, спрашивающий, какое окно является самым верхним или одно окно закрывает другое. Точно так же с привилегированным доступом ... Ср. Как определить окна X11 верхнего уровня с помощью xlib?

  3. Общедоступные оконные менеджеры и Qt не предоставляют вам привилегированный доступ к X

  4. Без способа найти самое верхнее окно и надежной связи идентификатора окна с соответствующим pid мы не сможем решить вопрос.

  5. Мы можем найти, какое окно имеет фокус, и это, вероятно, то, что мы хотим. Но опять же, без виджета pid map ...

Так что, извините, похоже, что это невозможно сделать.

5 голосов
/ 11 января 2010

PID владельца окна хранится в свойстве X _NET_WM_PID. Обратите внимание, что это только стандарт де-факто.

Сначала нужно найти идентификатор окна, затем вы можете запросить свойство. Я не знаю ни одной абстракции, предоставляемой QT для этого, поэтому вам, вероятно, придется использовать xlib или xcb.

Играть с инструментом xprop для начинающих.

2 голосов
/ 31 декабря 2011

Я голосую за Ответ Мишеля Когана и добавляю краткое изложение этого:

ps -o pid,comm,args $(xprop -id $(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}") -f _NET_WM_PID 0c " \$0\\n" _NET_WM_PID | awk "{print \$2}")

Вышеприведенное окно покажет следующее для текущего активного окна: PID, имя команды (только имя исполняемого файла), команда со всеми ее аргументами.

0 голосов
/ 05 августа 2013

Извлечено суть xprop в https://github.com/mondalaci/current-window-linux

Работает, но иногда segfaults - необходимо исправить и почистить.

0 голосов
/ 11 января 2010

Установить wmctrl (из репозиториев). wmctrl -lp может быть тем, что вы хотите. Вы всегда можете взглянуть на источник, если он вам нужен из вашей программы.

...