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

Pic*_*ico 5 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()
[]
Run Code Online (Sandbox Code Playgroud)

那么这个

>>> 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)>] 
Run Code Online (Sandbox Code Playgroud)

如控制台输出中所示,第二个选项返回两个窗口.但我无法弄清楚它们是什么.他们都没有任何孩子,无论我在桌面上有多少个窗口,我总是得到这两个窗口.

任何人都可以解释典型的基于gtk的桌面环境的对象层次结构吗?我无法理解为什么上面的代码不起作用.

请不要发布资源到wnck,xlib,qt等的替代解决方案.我更感兴趣的是了解我做错了什么,而不是获取建议,比如我们检查其他库.

pto*_*ato 9

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

这里解释了"窗口"实际意味着什么以及为什么代码不起作用:

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

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

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

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

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

  • 我的意思不是无礼,但您的回答并不令人满意。在回复的最后,您揭穿了最初的香蕉CD阅读器类比。我知道gtk和dtk.gdk窗口之间的区别,如果您仔细阅读我的问题,您会注意到这有点偏离主题了……尽管我确实提到我很困惑,所以我想声称是小学生。 (2认同)

gri*_*yvp 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])
Run Code Online (Sandbox Code Playgroud)

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