窗口应该保持在所有其他窗口的顶部。使用普通的x11 / xlib可以实现这种方式吗?谷歌搜索“永远在顶部”和“x11”/“xlib”没有返回任何有用的东西。
如果可能的话,我会避免像GTK +这样的工具包。
我正在使用Ubuntu和gnome桌面。在窗口菜单中,有一个选项“Always On Top”。这是由X服务器还是窗口管理器提供的?如果是第二种情况,是否有几乎任何wm都可以调用的通用函数?或者如何以“X11-generic”方式执行此操作?
XSelectInput(this->display, this->window,
ButtonPressMask |
StructureNotifyMask |
ExposureMask |
KeyPressMask |
PropertyChangeMask |
VisibilityChangeMask );
// ...
// In a loop:
if (XPending(this->display) >= 0)
{
XNextEvent(this->display, &ev);
switch(ev.type) {
// ...
case VisibilityNotify:
XRaiseWindow(this->display, this->window);
XFlush(this->display);
break;
// ...
}
}
但即使我的面具是正确的,事件处理和提高也几乎从未执行过!?
答案 0 :(得分:10)
#define _NET_WM_STATE_REMOVE 0 // remove/unset property
#define _NET_WM_STATE_ADD 1 // add/set property
#define _NET_WM_STATE_TOGGLE 2 // toggle property
...
...
Atom wmStateAbove = XInternAtom( display, "_NET_WM_STATE_ABOVE", 1 );
if( wmStateAbove != None ) {
printf( "_NET_WM_STATE_ABOVE has atom of %ld\n", (long)wmStateAbove );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE_ABOVE !\n" );
}
Atom wmNetWmState = XInternAtom( display, "_NET_WM_STATE", 1 );
if( wmNetWmState != None ) {
printf( "_NET_WM_STATE has atom of %ld\n", (long)wmNetWmState );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE !\n" );
}
// set window always on top hint
if( wmStateAbove != None ) {
XClientMessageEvent xclient;
memset( &xclient, 0, sizeof (xclient) );
//
//window = the respective client window
//message_type = _NET_WM_STATE
//format = 32
//data.l[0] = the action, as listed below
//data.l[1] = first property to alter
//data.l[2] = second property to alter
//data.l[3] = source indication (0-unk,1-normal app,2-pager)
//other data.l[] elements = 0
//
xclient.type = ClientMessage;
xclient.window = mywin; // GDK_WINDOW_XID(window);
xclient.message_type = wmNetWmState; //gdk_x11_get_xatom_by_name_for_display( display, "_NET_WM_STATE" );
xclient.format = 32;
xclient.data.l[0] = _NET_WM_STATE_ADD; // add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
xclient.data.l[1] = wmStateAbove; //gdk_x11_atom_to_xatom_for_display (display, state1);
xclient.data.l[2] = 0; //gdk_x11_atom_to_xatom_for_display (display, state2);
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
//gdk_wmspec_change_state( FALSE, window,
// gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
// GDK_NONE );
XSendEvent( display,
//mywin - wrong, not app window, send to root window!
root, // !! DefaultRootWindow( display ) !!!
False,
SubstructureRedirectMask | SubstructureNotifyMask,
(XEvent *)&xclient );
}
答案 1 :(得分:5)
您不想使用XRaiseWindow()来保持最佳状态。一些窗口管理器会完全忽略它。对于那些不这样做的人,请考虑如果多个应用程序尝试执行此操作会发生什么。繁荣!这就是窗口管理器负责堆叠窗口而不是应用程序的原因。
执行此操作的方法是使用扩展窗口管理器提示(EWMH)中定义的协议,请参阅:http://www.freedesktop.org/wiki/Specifications/wm-spec
具体来说,您需要_NET_WM_STATE_ABOVE,这就是“Always on Top”菜单项的工作方式。
如果您没有使用工具包,那么您将需要习惯于在工具包源代码中进行清理,以了解如何执行操作。在这种情况下,您可以在GTK +的X11后端查看函数gdk_window_set_keep_above()。这将显示如何使用_NET_WM_STATE_ABOVE提示。
答案 2 :(得分:2)
多年前我在Xlib中写过类似的东西。这是几行代码。当您的窗口被部分遮挡时,您将获得VisibilityNotify事件,然后调用XRaiseWindow。注意两个“永远在顶部”窗口重叠的情况。
答案 3 :(得分:-6)
例如,使用实际标题按钮(http://www.actualtools.com/titlebuttons/)。它允许任何窗口始终保持在顶部,卷起,透明等等。