我正在寻找一种方法来确定用户是否在X11下切换虚拟桌面。
我正在使用Python和X11库以及PyGTK。我在C中找到了一些工作示例,但是我缺乏将它们翻译成Python的专业知识,并且我阅读了几个X11寻呼机应用程序(fbpanel,pypanel)的源代码,但我似乎无法找到我正在寻找的内容
我必须注册信号吗?使用X11还是GTK? 我是否需要忙碌等待?
我对X11和GTK都是全新的,所以任何提示/帮助都会非常感激。
电贺, 菲利普
PS:我目前的努力可以找到here。
答案 0 :(得分:1)
这是基于GTK的解决方案:
screen = gtk.gdk.screen_get_default()
root = screen.get_root_window()
root.set_events(gtk.gdk.SUBSTRUCTURE_MASK)
root.add_filter(event_filter)
def event_filter(event, user_data):
# process event
return gtk.gdk.FILTER_CONTINUE
显然,SUBSTRUCTURE_MASK包含通常与工作区交换机关联的事件。不过,这个解决方案感觉有点尴尬。有什么想法吗?
电贺, 菲利普
答案 1 :(得分:0)
您可能需要查看libwnck或可能的Python绑定。
答案 2 :(得分:0)
通常,根窗口上的属性更改会向客户端通知桌面更改, 所以听一下PROPERTY_CHANGE_MASK而不是SUBSTRUCTURE_MASK; 这样可以减少噪音。
对于属性发生变化的,我怀疑它们之间有所不同 不同的windowmanagers /桌面/无论如何;我正在运行ubuntu / unity和 当我做" xprop -root"在桌面切换之前和之后,并对结果进行区分, 我发现更改的属性是_NET_DESKTOP_VIEWPORT。
我得到的主要噪音是根窗口 每次活动窗口更改时,_NET_ACTIVE_WINDOW属性都会更改。
答案 3 :(得分:0)
另一种改进:使用GDK_SUBSTRUCTURE_MASK
代替Don Hatch says,而不是GDK_PROPERTY_CHANGE_MASK
。此外,您感兴趣的确切属性是_NET_CURRENT_DESKTOP
。这是一个32位属性,其值是从0开始的桌面编号。
这是一个完整的可编译且可运行的示例,捕获了桌面切换的瞬间并报告了此后的当前桌面数量。该示例在C中进行,因为我不精通Python,希望您能翻译。
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
GdkFilterReturn propertyChangeFilter(GdkXEvent* xevent, GdkEvent*e, gpointer data)
{
const XPropertyEvent*const propEvt=(const XPropertyEvent*)xevent;
if(propEvt->type!=PropertyNotify)
return GDK_FILTER_CONTINUE;
if(propEvt->state!=PropertyNewValue)
return GDK_FILTER_CONTINUE;
const Atom NET_CURRENT_DESKTOP=(Atom)data;
if(propEvt->atom!=NET_CURRENT_DESKTOP)
return GDK_FILTER_CONTINUE;
fprintf(stderr, "Desktop change detected\n");
Atom actualType;
int actualFormat;
unsigned long nitems, remainingBytes;
unsigned char* prop;
if(XGetWindowProperty(propEvt->display, propEvt->window, propEvt->atom,
0, 1, False, AnyPropertyType,
&actualType, &actualFormat, &nitems, &remainingBytes,
&prop) != Success)
{
fprintf(stderr, "Failed to get current desktop number\n");
return GDK_FILTER_CONTINUE;
}
if(nitems!=1 || remainingBytes!=0 || actualFormat!=32)
{
XFree(prop);
fprintf(stderr, "Unexpected number of items (%lu) or remaining bytes (%lu)"
" or format (%d)\n", nitems, remainingBytes, actualFormat);
return GDK_FILTER_CONTINUE;
}
guint32 value;
memcpy(&value, prop, sizeof value);
XFree(prop);
fprintf(stderr, "Current desktop: %u\n", value);
return GDK_FILTER_CONTINUE;
}
int main(int argc, char** argv)
{
gtk_init(&argc,&argv);
GdkDisplay*const gdkDisplay=gdk_display_get_default();
Display*const display=gdk_x11_display_get_xdisplay(gdkDisplay);
const Atom atom=XInternAtom(display, "_NET_CURRENT_DESKTOP", True);
GdkWindow*const root=gdk_get_default_root_window();
gdk_window_set_events(root, GDK_PROPERTY_CHANGE_MASK);
gdk_window_add_filter(root, propertyChangeFilter, (gpointer)atom);
gtk_main();
}