5

我对一些 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 等的替代解决方案。我更感兴趣的是了解我做错了什么,而不是获得诸如检查其他库之类的建议。

4

2 回答 2

9

Your constraint is like saying "I want to build a CD player using only a banana. Please refrain from posting alternative solutions that resort to lasers." GTK can't do that, you're using the wrong tool for the job.

Here's an explanation of what a "window" actually means and why your code doesn't work:

First off, you need to understand the difference between a gtk.Window and a gtk.gdk.Window. A GTK window is a top level GTK widget that can contain other widgets. It is usually linked to a window on your desktop, but doesn't have to be - in GTK 3 there is an OffscreenWindow.

A GDK window, on the other hand, is platform-dependent. On an X desktop it is a thin wrapper around an X window, which is not necessarily a toplevel desktop window. On other systems it exists to abstract away the windowing system. A GDK window receives events, so some GTK non-window widgets have their own GDK windows. "Window" is really a terrible name for these objects, but it was inherited from X and it's probably not going to change.

Each GTK process only knows about its own windows. You can get a list of the toplevel GTK windows of your own application using gtk.window_list_toplevels(). Getting the children of these windows should return you the GTK widgets that they contain. However, you can't descend into the widget hierarchy of other processes' windows. For example, what if another process has a window with a child widget that is a custom widget that your process doesn't know about? What should it report as the type of that widget?

Getting a list of the toplevel GDK windows with gtk.gdk.window_get_toplevels() is basically the same as getting a list of the toplevel X windows, as far as I understand it. You have no way of knowing what kind of windows they are - they might be the Gnome Panel, or they might be Qt windows, or they might be something else altogether that doesn't correspond with a desktop window.

Libwnck (link to the overview of what it does) can get you a list of non-minimized windows, and their titles, but it won't allow you to see inside them. There's no way to do that. Libwnck uses GDK internally, so technically you could do it using GDK, but why would you bother if there's already a library that does that for you? If you really want to do it yourself, look at the libwnck source code.

于 2012-02-21T11:30:12.850 回答
8

您获得的窗口是在您的流程中创建的窗口。要获取窗口列表,需要查询根窗口的属性,如下所示:

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 设备上有所不同。

于 2012-07-04T16:18:56.010 回答