2012-02-19 4 views
5

Я немного смущен некоторыми понятиями gtk и gnome. Я пытаюсь получить список не минимизированных окон на рабочем столе gnome2, но после прочтения документации pygtk и проверки результатов я не могу понять результаты.Как получить список всех окон на рабочем столе gnome2 с помощью pygtk?

Ни один из двух фрагментов ниже не работает.

Сначала я попробовал это ..

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

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

этот

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

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

Может ли кто-нибудь объяснить иерархию объектов типичной среды рабочего стола на основе gtk? Не могу понять, почему приведенный выше код не работает.

Пожалуйста, воздержитесь от публикации альтернативных решений, которые могут быть использованы для wnck, xlib, qt и т. Д. Я больше заинтересован в понимании того, что я делаю неправильно, чем в получении консультаций, таких как проверка других библиотек.

ответ

9

Ваше ограничение похоже на высказывание «Я хочу создать CD-плеер, используя только банан. Пожалуйста, воздержитесь от публикации альтернативных решений, которые прибегают к лазерам». GTK не может этого сделать, вы используете неправильный инструмент для работы.

Вот объяснение того, что такое «окно» на самом деле означает, и почему ваш код не работает:

Во-первых, вы должны понимать разницу между gtk.Window и gtk.gdk.Window. Окно GTK представляет собой виджет верхнего уровня GTK, который может содержать другие виджеты. Обычно это связано с окном на вашем рабочем столе, но не обязательно - в GTK 3 есть OffscreenWindow.

A GDK Окно, с другой стороны, зависит от платформы. На рабочем столе X это тонкая оболочка вокруг окна X, что не обязательно является окном рабочего стола. В других системах существует абстрактная система окон. Окно GDK принимает события, поэтому некоторые виджеты без окна GTK имеют свои собственные окна GDK. «Окно» действительно ужасное имя для этих объектов, но оно было унаследовано от X, и это, вероятно, не изменится.

Каждый процесс GTK знает только о его собственных окнах. Вы можете получить список окон верхнего уровня GTK вашего собственного приложения с использованием gtk.window_list_toplevels(). Получение детьми этих окон должно вернуть вам виджеты GTK, которые они содержат. Однако вы не можете спуститься в иерархию виджетов окон других процессов. Например, что, если в другом процессе есть окно с дочерним виджлетом, который является настраиваемым виджетами, о которых ваш процесс не знает? Что он должен указывать как тип этого виджета?

Получение списка окон верхнего уровня GDK с помощью gtk.gdk.window_get_toplevels() в основном аналогично получению списка окон верхнего уровня X, насколько я понимаю. У вас нет способа узнать, что это за окна: они могут быть панелью Gnome, или они могут быть Qt-окнами, или они могут быть совсем другими, что не соответствует окну рабочего стола.

Libwnck (link к обзору того, что он делает) может предоставить вам список не минимизированных окон и их заголовков, но он не позволит вам видеть внутри них. Невозможно это сделать. Libwnck использует GDK внутренне, так что технически вы могли бы это сделать с помощью GDK, но почему бы вам побеспокоить, есть ли библиотека, которая делает это для вас? Если вы действительно хотите сделать это самостоятельно, посмотрите исходный код libwnck.

+1

Я не хочу быть грубым, но я не думаю, что ваш ответ удовлетворительный. К концу вашего ответа вы разоблачили свою первоначальную аналогию с банановым cd-считывателем. Я знаю различия между окнами gtk и dtk.gdk, если вы внимательно прочитаете мой вопрос, вы заметите, что это было немного не по теме ... хотя я упоминал, что я был в замешательстве, поэтому я думаю, что я требовать mea-culpa. – Pico

+0

Я предполагаю, что нижняя строка - это почему 'gtk.gdk.window_get_toplevels()' вывод результата, который вы описали? Что касается сортировки окон, у меня создалось впечатление, что у них есть атрибуты для этой единственной цели. – Pico

+0

Ок, я думаю, я интерпретировал ваш вопрос, чтобы понять, почему вы не можете получить дочерние _widgets_ из окон. Я не знаю, почему вызов GDK не делает то, что вы хотите. Возможно, вам стоит взглянуть на исходный код libwnck, чтобы увидеть, как он работает там? – ptomato

7

Окна, которые вы получаете, это окна, которые были созданы в вашем процессе. Чтобы получить список окон, вы должны запросить свойства корневого окна, как это:

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

Пожалуйста, обратите внимание, что ГДК представляет собой тонкий слой над базовой графической ОС двигателя (X11/Quartz/аква/GDI и т.д.), и результат может отличаться на разных устройствах NIX.

+0

Последнее предложение ответа ужасно неверно. GDK является ** не ** «тонкой оболочкой над движком виджетов», это библиотека рисования/окна, используемая для ** реализации ** GTK. Qt и Motif никак не связаны с GDK. – user4815162342

+0

@ user4815162342 Спасибо, исправлено. – grigoryvp