2010-01-11 53 views
15

有誰知道如何獲得頂部活動窗口的PID,然後如何使用PID獲取窗口的屬性?我的意思是像進程名稱,程序名稱等屬性。獲取頂部窗口的pid和細節

我在Linux(Ubuntu 9.10)下使用Qt。

+0

你的應用程序知道它自己的pid,那是你想要的嗎? – Tobu 2010-01-11 11:43:45

+2

QT不是一種語言,它是一個工具包。 QT是用C++編寫的,但是對許多其他語言都有綁定。你使用C++嗎? – 2010-01-11 11:45:23

+0

@JamesPolley QT並不完全不同於一種語言,因爲它可以充當「一次編寫,無處不在編譯」工具,其中移植像POSIX調用之類的東西需要爲WinAPI,Android等編寫單獨的代碼。 – Wyatt8740 2016-12-05 00:49:12

回答

5

窗口所有者的PID存儲在X屬性_NET_WM_PID中。請注意,這只是一個事實上的標準。

您必須先找到窗口的ID,然後才能查詢屬性。我不知道QT爲此提供了什麼抽象,所以你可能不得不使用xlib或xcb。

玩起動器的工具xprop

5

xlib的XGetInputFocus會告訴你哪個窗口有焦點,這可能比最頂層的焦點更有趣。參看Xfree86的XGetInputFocus manpage

如果它真的是最頂層的窗口,而不是您關注的窗口,那麼我認爲沒有一個簡單的調用來做到這一點,因爲xlib似乎沒有提供任何方式查詢全局堆棧順序,這是數據結構,它告訴你哪些窗口在其他哪些窗口的前面。

一旦你有合適的窗口ID,xprop將列出PID _NET_WM_PID_下 - 儘管不是所有窗口都有這樣的屬性...

後記更多的想法;因爲我已經想過xlib ...很長一段時間

總結:

  1. X不提供窗口ID和PID之間的任何可靠的關聯,並作爲Noufal觀察,窗戶上的X服桌面可能來自許多不同的機器,並且兩臺遠程客戶機可能碰巧使用相同的PID,因爲它僅在每臺機器上唯一。參看How to get an X11 Window from a Process ID?

  2. X似乎並沒有提供一個接口,詢問哪個是最上面的窗口,或者是否一個窗口遮擋了另一個窗口。同樣有特權的訪問......參見How to identify top-level X11 windows using xlib?

  3. 通常可用的窗口管理器和Qt不給你X

  4. 特權都沒有找到的最頂層窗口的方式,和窗口ID的可靠的關聯匹配的PID,我們解決不了問題。

  5. 我們可以找到哪個窗口有焦點,這可能是我們想要的。但是,沒有wid來pid映射...

所以,對不起,它看起來不能做到。

0

安裝wmctrl(從存儲庫)。 wmctrl -lp可能是你想要的。如果您的程序需要它,您可以隨時查看源代碼。

+0

參考wmctrl關於-p選項的說法:「在窗口列表中包含PID,很少X應用程序支持此功能。」還要注意,WM可能會也可能不會支持EWMH; Qt可以與非合格的WM一起使用。 – 2010-01-12 08:32:38

19

有關X的一件事是它是網絡透明的。很有可能頂部顯示的實際窗口(具有焦點)運行在非自己的機器上,在這種情況下,窗口內運行的進程的進程ID在您的計算機上無效。

你能詳細談談你想做什麼嗎?我認爲這裏有一些遺漏的細節。理想情況下,您應該在X級別工作,而不是在特定的機器上工作。

+0

我希望我能+2這個。 – asveikau 2010-01-11 22:44:43

+0

感謝您的支持。 :) – 2010-01-12 04:12:33

+1

有焦點的窗口不需要在最上面。 – 2010-01-12 08:33:25

24

在linux調用xprop中有一個命令,它是一個用於在X服務器中顯示窗口屬性的實用程序。在Linux xprop -root爲您提供根窗口屬性和其他活動的程序。

xprop -root | grep _NET_ACTIVE_WINDOW\(WINDOW\) 

得到只是活動窗口ID:那麼你可以使用這個命令來獲得活動窗口的ID(沒有「_NET_ACTIVE_WINDOW(窗口):窗口編號」在該行的開頭)用這個命令:

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

現在你可以保存在用戶定義的變量,這個命令的輸出:

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

xprop有一個屬性調用-i d。該參數允許用戶在命令行上選擇窗口標識。我們應該尋找_NET_WM_PID(紅衣主教)在輸出......所以我們使用這個命令:

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

這給你最頂層的活動窗口的進程ID。

更trickey,做所有的事情,在短短1個命令:

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

現在,我可以用popen功能,搶標準輸出和打印通過我的C運行這些命令++程序(Linux)或保存。 popen創建一個管道,以便我們可以讀取我們正在調用的程序的輸出。

(你也可以使用 '的/ proc' 文件系統,並得到一個PID( '的/ proc/YOUR_PID /狀態')的更多細節)

#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; 
} 
+0

但請注意,這通常會失敗,因爲其他幾個回答都指出,_NET_WM_PID是一個通常不存在的屬性。 – 2011-02-24 09:11:29

+0

是的,我只是試過這個,而_NET_WM_PID不存在 – cheshirekow 2012-01-10 16:06:49

+4

你知道你可以在xprop命令行指定變量嗎?就像'xprop _NET_WM_PID -id $ window_id'一樣 – nonchip 2012-03-14 14:50:06

2

我投票了Michel Kogan’s answer,並加入它這個簡明摘要:

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,命令名(僅可執行文件名稱),其所有的參數的命令。

5

我很晚很晚參加派對,但我有類似的問題,我認爲這可以幫助其他人有同樣的問題。 有一個命令行伎倆要做到這一點,你可以嘗試execvp'ing,或執行它的輸出重定向到您的代碼

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"