2012-02-19 6 views
5

Estoy un poco confundido con algunos conceptos de gtk y gnome. Estoy tratando de obtener una lista de ventanas no minimizadas en mi escritorio gnome2, pero después de leer la documentación de pygtk e inspeccionar los resultados, no puedo entender los resultados.¿Cómo obtengo una lista de todas las ventanas en mi escritorio gnome2 usando pygtk?

Ninguno de los dos fragmentos a continuación parece funcionar.

Primero probé este ..

>>> gtk.gdk.window_get_toplevels() 
[<gtk.gdk.Window object at 0xb74339b4 (GdkWindow at 0x8a4c170)>] 

>>> gtk.gdk.window_get_toplevels()[0].get_children() 
[] 

entonces este

>>> d = gtk.gdk.DisplayManager() 
>>> d.get_default_display().get_screen(0).get_root_window().get_children() 
[<gtk.gdk.Window object at 0x89dcc84 (GdkWindow at 0x8a4c170)>, <gtk.gdk.Window object at 0x89dccac (GdkWindow at 0x8a4c0c0)>] 

Como se ve en la salida de la consola, la segunda opción devuelve dos ventanas. Pero no he podido descifrar cuáles son. Ninguno de ellos tiene hijos y siempre obtengo esas dos ventanas independientemente de cuántas ventanas tengo en mi escritorio.

¿Alguien podría explicar la jerarquía de objetos del típico entorno de escritorio basado en gtk? No puedo entender por qué el código anterior no funciona.

Por favor absténgase de publicar soluciones alternativas que utilicen wnck, xlib, qt, etc. Me interesa más saber qué estoy haciendo mal que obtener consejos, como consultar otras bibliotecas.

Respuesta

9

Su limitación es como decir "Quiero construir un reproductor de CD utilizando solo una banana. Por favor absténgase de publicar soluciones alternativas que recurran a los láser". GTK no puede hacer eso, estás usando la herramienta incorrecta para el trabajo.

He aquí una explicación de lo que es una "ventana" en realidad significa y por qué su código no funciona:

En primer lugar, es necesario entender la diferencia entre un gtk.Window y una gtk.gdk.Window. Una ventana GTK es un widget GTK de nivel superior que puede contener otros widgets. Por lo general, está vinculado a una ventana en su escritorio, pero no tiene que ser así: en GTK 3 hay un OffscreenWindow.

A GDK ventana, por otro lado, depende de la plataforma. En un escritorio X, es una envoltura delgada alrededor de una ventana X, que no es necesariamente una ventana de escritorio de nivel superior. En otros sistemas existe para abstraer el sistema de ventanas. Una ventana GDK recibe eventos, por lo que algunos widgets GTK que no son de ventana tienen sus propias ventanas GDK. "Ventana" es realmente un nombre terrible para estos objetos, pero fue heredado de X y probablemente no va a cambiar.

Cada proceso GTK solo sabe acerca de sus propias ventanas. Puede obtener una lista de las ventanas GTK topevel ​​de su propia aplicación usando gtk.window_list_toplevels(). Obtener los elementos secundarios de estas ventanas debe devolverle los widgets GTK que contienen. Sin embargo, no puede descender a la jerarquía de widgets de las ventanas de otros procesos. Por ejemplo, ¿qué pasa si otro proceso tiene una ventana con un widget secundario que es un widget personalizado que su proceso desconoce? ¿Qué debería informar como el tipo de ese widget?

Obtener una lista de las ventanas de topevel ​​GDK con gtk.gdk.window_get_toplevels() es básicamente lo mismo que obtener una lista de las ventanas de nivel X, hasta donde yo lo entiendo. No tiene forma de saber qué tipo de ventanas son: podrían ser el Panel de Gnome, o podrían ser ventanas de Qt, o podrían ser algo completamente diferente que no se corresponde con una ventana de escritorio.

Libwnck (link a la vista general de lo que hace) puede obtener una lista de ventanas no minimizadas, y sus títulos, pero no le permitirá ver dentro de ellos. No hay forma de hacer eso. Libwnck usa GDK internamente, por lo que técnicamente podrías hacerlo usando GDK, pero ¿por qué te molestaría si ya hay una biblioteca que hace eso por ti? Si realmente quieres hacerlo tú mismo, mira el código fuente de libwnck.

+1

No me refiero a ser grosero, pero no creo que su respuesta sea satisfactoria. Al final de su respuesta, desaprobó su analogía inicial de banana-cd-reader. Soy consciente de las diferencias entre una ventana de gtk y dtk.gdk, si lees mi pregunta cuidadosamente, notarás que eso fue un poco fuera de tema ... aunque mencioné que estaba confundido, así que supongo que reclamar mea-culpa – Pico

+0

Supongo que el resultado final es, ¿por qué no 'gtk.gdk.window_get_toplevels()' da como resultado el resultado que describió? En cuanto a ordenar las ventanas, tenía la impresión de que tienen atributos para ese único propósito. – Pico

+0

Ok, creo que interpreté tu pregunta para decir por qué no pudiste obtener las _ventanas_ infantiles de las ventanas. No sé por qué la llamada GDK no está haciendo lo que quieres. ¿Quizás deberías mirar el código fuente de libwnck para ver cómo funciona allí? – ptomato

7

Las ventanas que obtiene son las ventanas que se crearon dentro de su proceso. Para obtener la lista de ventanas, es necesario consultar las propiedades de la ventana raíz, así:

import gtk.gdk 
root = gtk.gdk.get_default_root_window() 
for id in root.property_get('_NET_CLIENT_LIST')[2]: 
    w = gtk.gdk.window_foreign_new(id) 
    if w: 
     print(w.property_get('WM_NAME')[2]) 

Tenga en cuenta que GDK es una capa delgada sobre subyacente motor gráfico del sistema operativo (X11/cuarzo/agua/GDI etc.) y el resultado puede diferir en diferentes dispositivos NIX.

+0

La última oración de la respuesta es horriblemente incorrecta. GDK no es ** ** una "envoltura delgada sobre el motor de widgets", es la biblioteca de dibujo/ventanas utilizada para ** implementar ** GTK. Qt y Motif no están conectados con GDK de ninguna manera. – user4815162342

+0

@ user4815162342 Muchas gracias, arreglado. – grigoryvp

Cuestiones relacionadas