如何使用pygtk获取gnome2桌面上所有窗口的列表?

时间:2012-02-19 20:52:32

标签: python gtk pygtk gnome window-management

我对某些gtk和gnome概念感到困惑。我正在尝试在我的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等的替代解决方案。我更感兴趣的是理解我做错了什么,而不是获取建议,比如检查其他库。

2 个答案:

答案 0 :(得分:9)

你的约束就像是说“我想用香蕉制作CD播放器。请不要发布采用激光的替代解决方案。” GTK无法做到这一点,你正在使用错误的工具来完成工作。

以下是对“窗口”实际含义以及代码无效的原因的解释:

首先,您需要了解gtk.Windowgtk.gdk.Window之间的区别。 GTK窗口是顶级GTK窗口小部件,可以包含其他窗口小部件。它通常链接到桌面上的一个窗口,但不一定是 - 在GTK 3中有一个OffscreenWindow

另一方面, GDK 窗口与平台有关。在X桌面上,它是X窗口周围的薄包装,不一定是顶级桌面窗口。在其他系统上,它可以抽象出窗口系统。 GDK窗口接收事件,因此一些GTK非窗口小部件具有自己的GDK窗口。 “Window”对于这些对象来说确实是一个可怕的名称,但它是从X继承的,它可能不会改变。

每个GTK进程只知道其自己的窗口。您可以使用gtk.window_list_toplevels()获取您自己的应用程序的顶级GTK窗口列表。获取这些窗口的子项应该返回它们包含的GTK小部件。但是,您无法进入其他进程窗口的窗口小部件层次结构。例如,如果另一个进程有一个窗口,其子窗口小部件是您的进程不知道的自定义窗口小部件,该怎么办?它应该作为该小部件的类型报告什么?

获取带有gtk.gdk.window_get_toplevels()的顶级GDK窗口列表与获取顶层X窗口列表基本相同,据我所知。您无法知道它们是什么类型的窗口 - 它们可能是Gnome面板,或者它们可能是Qt窗口,或者它们可能是完全不同于桌面窗口的其他窗口。

Libwnck(link概述它的作用)可以获得非最小化窗口及其标题的列表,但它不允许您查看它们内部。没有办法做到这一点。 Libwnck在内部使用GDK,所以从技术上讲你可以使用GDK来做,但是如果已经有一个库为你做这个,你为什么要打扰?如果你真的想自己做,请查看libwnck源代码。

答案 1 :(得分: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])

请注意,GDK是底层OS图形引擎(X11 / Quartz / Aqua / GDI等)的薄层,不同NIX设备的结果可能不同。