2010-01-11 16 views
15

¿Alguien sabe cómo obtener el PID de la ventana activa superior y luego cómo obtener las propiedades de la ventana usando el PID? Me refiero a propiedades como nombre de proceso, nombre de programa, etc.Obtención de pid y detalles para la ventana superior

Estoy usando Qt bajo Linux (Ubuntu 9.10).

+0

Tu aplicación conoce su propio pid, ¿eso es lo que quieres? – Tobu

+2

QT no es un idioma, es un juego de herramientas. QT está escrito en C++, pero tiene enlaces para muchos otros idiomas. ¿Estás usando C++? –

+0

@JamesPolley QT no es del todo diferente de un lenguaje en que puede actuar como una herramienta de 'escribir una vez, compilar en todas partes', donde portar algo como las llamadas POSIX requeriría escribir un código separado para WinAPI, Android, etc. – Wyatt8740

Respuesta

5

El PID de un propietario de ventana se almacena en la propiedad X _NET_WM_PID. Tenga en cuenta que esto es solo un estándar de facto.

Primero debe encontrar la identificación de la ventana, luego puede realizar una búsqueda de la propiedad. No sé de ninguna abstracción que QT proporcione para esto, por lo que probablemente tendrá que usar xlib o xcb.

Juega con la herramienta xprop para empezar.

5

xlib XGetInputFocus le dirá qué ventana tiene foco, que es probablemente más interesante que cuál es el más alto. Cf. Xfree86's XGetInputFocus manpage.

Si realmente es la ventana más alta, y no la ventana con foco que buscas, bueno, no creo que haya una simple llamada para hacer eso, porque xlib no parece ofrecer ninguna manera de consultar el orden de apilamiento global, que es la estructura de datos que le indica qué ventanas están delante de cuáles otras.

Una vez que tenga la ventana derecha Identificación, xprop enumerará el pid bajo _NET_WM_PID_ - aunque no todas las ventanas tienen una propiedad ...

PostScript Más pensamientos; Hace tiempo que no he pensado en xlib ...

Para resumir:

  1. X no ofrece ninguna asociación fiable entre los identificadores de ventana y los PID, y como se observa Noufal, las ventanas que se presentan en una X el escritorio puede provenir de muchas máquinas diferentes, y dos clientes remotos pueden usar el mismo PID, ya que solo es único por máquina. Cf. How to get an X11 Window from a Process ID?

  2. X no parece ofrecer una interfaz que pregunte cuál es la ventana superior, o si una ventana ocluye a otra. Asimismo con acceso privilegiado ... Cf. How to identify top-level X11 windows using xlib?

  3. gestores de ventanas comúnmente disponibles y Qt no le dan acceso privilegiado a X

  4. Sin tanto una manera de encontrar la ventana superior, y una asociación fiable de la ventana Identificación de la pid juego, nos no puede resolver la pregunta

  5. Podemos encontrar qué ventana tiene foco, y esto es probablemente lo que queremos. Pero de nuevo, sin el mapa wid a pid ...

Así que, lo siento, parece que no se puede hacer.

0

Instalar wmctrl (de los repositorios). wmctrl -lp podría ser lo que quieras. Siempre puede echar un vistazo a la fuente si la necesita de su programa.

+0

Cf. qué dice wmctrl sobre la opción -p: "Incluir PID en la lista de ventanas. Muy pocas aplicaciones X admiten esta característica". Tenga en cuenta también que el WM puede o no ser compatible con EWMH; Qt se puede usar con WM no conformistas. –

19

Una de las cosas que tiene X es su red transparente.Es muy posible que la ventana real que se muestra en la parte superior (que tiene foco) se ejecute en una máquina que no sea la suya, en cuyo caso, la identificación del proceso del proceso que se ejecuta dentro de la ventana no tendrá sentido en su máquina.

¿Puedes elaborar un poco sobre lo que quieres hacer? Creo que hay algunos detalles faltantes aquí. Idealmente, debería trabajar en el nivel X en lugar de en el específico de la máquina.

+0

Ojalá pudiera +2 esto. – asveikau

+0

Gracias por su apoyo. :) –

+1

La ventana con foco no necesita estar en la parte superior. –

24

hay un comando en linux call xprop que es una utilidad para mostrar propiedades de ventana en un servidor X. En linux xprop -root le da las propiedades de la ventana raíz y también otros programas activos. entonces se puede obtener el identificador de la ventana activa utilizando este comando:

xprop -root | grep _NET_ACTIVE_WINDOW\(WINDOW\) 

para obtener simplemente la ventana de identificación activa (sin "_NET_ACTIVE_WINDOW (ventana): Ventana ID #" en el principio de la línea) utilizan este comando:

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

ahora puede guardar esta salida de comando en una variable definida por el usuario:

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

xprop tiene un atributo llamado -i re. Este argumento permite al usuario seleccionar la identificación de la ventana en la línea de comando. Debemos buscar _NET_WM_PID (cardinal) de la producción ... así que utilice este comando:

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

esto le da la ID del proceso ventana superior activa.

para ser más trickey y hacer todas las cosas en tan sólo 1 ... comando:

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

Ahora puede ejecutar estos comandos a través de mi programa en C++ (en Linux) usando la función popen, la salida estándar de agarre e imprimir o guardarlo popen crea una tubería para que podamos leer el resultado del programa que invocamos.

(también se puede utilizar '/ proc' sistema de archivos y obtener más detalles de un 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; 
} 
+0

Pero tenga en cuenta que esto a menudo fallará porque, como varias otras respuestas han notado, _NET_WM_PID es un atributo que a menudo no está allí. –

+0

Sí, lo intenté y _NET_WM_PID está ausente – cheshirekow

+4

¿sabes que puedes especificar las variables en la línea de comando xprop? como en 'xprop _NET_WM_PID -id $ window_id' – nonchip

2

Voy a votar hasta Michel Kogan’s answer, y añadiendo este breve resumen de la misma:

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}") 

lo anterior se mostrará lo siguiente para la ventana activa: PID, nombre del comando (sólo el nombre del ejecutable), comando con todos sus argumentos.

5

Llego muy tarde a la fiesta, pero tuve un problema similar, y creo que esto puede ayudar a alguien más que tenga el mismo problema. Hay un truco línea de comandos para hacer esto, puede intentar execvp'ing, o ejecutándolo redirigiendo la salida a su código

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

da el nombre de la ventana, así como el nombre del programa. Por ejemplo, para esta pestaña, me da

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

WM_CLASS(STRING) = "Navigator", "Firefox" 
Cuestiones relacionadas