2012-02-19 15 views
5

Sono un po 'confuso con alcuni concetti gtk e gnome. Sto cercando di ottenere l'elenco delle finestre non ridotte al minimo sul mio desktop gnome2, ma dopo aver letto la documentazione di pygtk e aver esaminato i risultati, non riesco a capire i risultati.Come posso ottenere un elenco di tutte le finestre sul mio desktop gnome2 usando pygtk?

Nessuno dei due frammenti di seguito sembra funzionare.

Per prima cosa ho provato questo ..

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

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

allora questo

>>> 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)>] 

Come si vede nella uscita della console, la seconda opzione restituisce due finestre. Ma non sono stato in grado di capire cosa siano. Nessuno di loro ha figli e io ho sempre queste due finestre indipendentemente da quante finestre ho sul mio desktop.

Qualcuno potrebbe spiegare la gerarchia degli oggetti del tipico ambiente desktop basato su gtk? Non riesco a capire perché il codice sopra non funziona.

Si prega di astenersi dal pubblicare soluzioni alternative a wnck, xlib, qt, ecc. Sono più interessato a capire cosa sto facendo male che a ottenere consigli come noi controllando altre librerie.

risposta

9

Il tuo vincolo è come dire "Voglio costruire un lettore CD usando solo una banana. Si prega di astenersi dal pubblicare soluzioni alternative che ricorrono ai laser". GTK non può farlo, stai usando lo strumento sbagliato per il lavoro.

Ecco una spiegazione di ciò che una "finestra" in realtà significa e perché il codice non funziona:

Prima di tutto, è necessario capire la differenza tra un gtk.Window e gtk.gdk.Window. Una finestra GTK è un widget GTK di livello superiore che può contenere altri widget. Solitamente è collegato a una finestra sul desktop, ma non deve essere presente: in GTK 3 è disponibile lo OffscreenWindow.

A La finestra GDK, al contrario, dipende dalla piattaforma. Su un desktop X è un involucro sottile attorno a una finestra X, che non è necessariamente una finestra desktop di livello superiore. Su altri sistemi esiste per astrarre il sistema di finestre. Una finestra GDK riceve eventi, quindi alcuni widget GTK senza finestre hanno le proprie finestre GDK. "Window" è davvero un nome terribile per questi oggetti, ma è stato ereditato da X e probabilmente non cambierà.

Ogni processo GTK conosce solo la sua finestre di proprietà di . È possibile ottenere un elenco delle finestre GTK di livello superiore di la propria applicazione utilizzando gtk.window_list_toplevels(). Ottenere i figli di queste finestre dovrebbe restituire i widget GTK che contengono. Tuttavia, non è possibile scendere nella gerarchia dei widget delle finestre di altri processi. Ad esempio, che succede se un altro processo ha una finestra con un widget figlio che è un widget personalizzato di cui il tuo processo non è a conoscenza? Cosa dovrebbe segnalare come il tipo di quel widget?

Ottenere un elenco delle finestre GDK di primo livello con gtk.gdk.window_get_toplevels() equivale sostanzialmente a ottenere un elenco delle finestre X di livello superiore, per quanto ho capito. Non hai modo di sapere che tipo di finestre sono - potrebbero essere il pannello di Gnome, o potrebbero essere finestre di Qt, o potrebbero essere qualcos'altro che non corrisponde a una finestra del desktop.

Libwnck (link alla panoramica di ciò che fa) può ottenere un elenco di finestre non ridotte a icona e relativi titoli, ma non consente di vedere al loro interno. Non c'è modo di farlo. Libwnck usa GDK internamente, quindi tecnicamente potresti farlo usando GDK, ma perché ti disturberesti se c'è già una libreria che fa questo per te? Se vuoi davvero farlo da solo, guarda il codice sorgente di libwnck.

+1

Non intendo essere scortese, ma non credo che la vostra risposta sia soddisfacente. Alla fine della tua risposta, hai sfatato l'analogia iniziale con il lettore cd-banana. Sono consapevole delle differenze tra una finestra gtk e una finestra dtk.gdk, se leggete attentamente la mia domanda, noterete che era un po 'fuori tema ... anche se ho menzionato che ero confuso, quindi suppongo di rivendicare mea-culpa. – Pico

+0

Immagino che la linea di fondo sia, perché non 'gtk.gdk.window_get_toplevels()' sta emettendo il risultato che hai descritto? Per quanto riguarda l'ordinamento delle finestre, avevo l'impressione che avessero attributi per quell'unico scopo. – Pico

+0

Ok, immagino di aver interpretato la tua domanda nel senso che non potresti avere il bambino _widgets_ delle finestre. Non so perché la chiamata GDK non stia facendo quello che vuoi. Forse dovresti guardare il codice sorgente di libwnck per vedere come funziona lì? – ptomato

7

Le finestre che si ottengono sono le finestre create all'interno del processo. Per ottenere l'elenco delle finestre, è necessario interrogare le proprietà della finestra di root, in questo modo:

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]) 

prega di notare che GDK è un sottile strato sopra sottostante motore di OS grafica (X11/quarzo/Aqua/GDI etc) e il risultato potrebbe essere diverso su diversi dispositivi NIX.

+0

L'ultima frase della risposta è orribilmente errata. GDK è ** non ** un "thin wrapper over widget engine", è la libreria di disegno/windowing usata per ** implementare ** GTK. Qt e Motif non sono collegati in alcun modo con GDK. – user4815162342

+0

@ user4815162342 Grazie mille, risolto. – grigoryvp

Problemi correlati