User interface X11/Xlib:窗口始终位于顶部
一个窗口应位于所有其他窗口的顶部。这在普通x11/xlib中可能吗?谷歌搜索“始终在顶部”和“x11”/“xlib”并没有返回任何有用的信息 如果可能的话,我会避免使用像GTK+这样的工具包 我正在使用Ubuntu和gnome桌面。在窗口菜单中,有一个选项“始终在顶部”。这是由X服务器还是窗口管理器提供的?如果是第二种情况,是否有一个可以为几乎任何wm调用的通用函数?或者如何以“X11通用”的方式实现这一点User interface X11/Xlib:窗口始终位于顶部,user-interface,x11,window-managers,User Interface,X11,Window Managers,一个窗口应位于所有其他窗口的顶部。这在普通x11/xlib中可能吗?谷歌搜索“始终在顶部”和“x11”/“xlib”并没有返回任何有用的信息 如果可能的话,我会避免使用像GTK+这样的工具包 我正在使用Ubuntu和gnome桌面。在窗口菜单中,有一个选项“始终在顶部”。这是由X服务器还是窗口管理器提供的?如果是第二种情况,是否有一个可以为几乎任何wm调用的通用函数?或者如何以“X11通用”的方式实现这一点 编辑:我实现了fizzer的答案,现在有以下代码: XSelectInput(this-
编辑:我实现了fizzer的答案,现在有以下代码:
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;
// ...
}
}
但是即使我的面具是正确的,事件处理和提升几乎从未执行过 很多年前,我在Xlib中写过类似的东西。这是几行代码。当您的窗口部分被遮挡时,您会收到VisibilityNotify事件,然后调用XRaiseWindow。注意两个“始终位于顶部”窗口重叠的情况。您不想使用XRaiseWindow()来保持顶部。一些窗口管理器会完全忽略它。对于那些没有,考虑如果不止一个应用程序试图做到这一点会发生什么。繁荣这就是为什么窗口管理器负责堆叠窗口,而不是应用程序 执行此操作的方法是使用扩展窗口管理器提示(EWMH)中定义的协议,请参阅: 特别是在这里,您需要_NET_WM_STATE_,上面是“始终在顶部”菜单项的工作方式
如果您不使用工具箱,您需要习惯于在工具箱源代码中进行清理,以了解如何操作。在本例中,您可以查看GTK+的X11后端中的函数gdk_window_set_keep_over()。这将显示如何使用上面的提示。使用实际标题按钮(http://www.actualtools.com/titlebuttons/)比如说。它允许任何窗口始终保持在顶部、卷起、透明等 实际上,所有低级窗口工具都是用这两种语言中的一种或两种语言定义的,因此,如果可以做到这一点,那么就可以用C/C++实现。这不是一个真正的语言问题。更改了问题。当然,这不是关于是否可以使用c/c++,而是如果可以仅使用x11/xlib的最小绑定,那么您是否可以获得其他事件类型?此外,您的窗口是否处于顶层,即根窗口的子窗口?您只能相对于兄弟姐妹打开一个窗口。是的,我确实获得了其他事件,并且该胜利是根胜利的子胜利。是因为我做了以下事情吗?XserverRegion region=xfixeCreateRegion(此->显示,0,0);XFixesSetWindowShapeRegion(此->显示,此->窗口,形状输入,0,0,区域);这不是一个好主意,因为任何时候你有两个应用程序这样做,他们将“战斗”的顶部。EWMH中有一个专门的提示。在罕见的情况下,如果没有窗口管理器,这项技术几乎是您所拥有的全部,但在这种情况下,您很可能可以控制运行的内容,因此避免两个窗口争夺顶部就简单多了。谢谢。确定您没有使用XRaiseWindow()是正确的。这也是我的想法。但是我之前已经看过gdk_window_set_keep_over(),并且我尝试向特定窗口发送一个XEvent“\u NET\u WM\u STATE_over”。什么都没做。。。使用Compiz和Metacity。此处可能会出现错误,例如错误获取XSendEvent的详细信息,或者在应该设置属性时在尚未映射的窗口上使用事件。此外,WM可能会忽略某些语义窗口类型的消息。无论如何,如果你发布一个文件可编译的测试程序,人们可以尝试诊断。嗨,浩劫!我想知道您是否可以将我链接到GDK后端源代码,这样我就可以看到他们是如何执行上面的
GDK\u窗口\u set\u keep\u
。另外,如果您可以将我链接到GTK sourcecode,我也想查看上面的GTK_window_set_
:这不是关于ms windows,也不是关于标题栏中的可单击按钮。你完全没有抓住要点。一个极好的解决方案谢谢!我喜欢评论中与GDK的比较!我很好奇,为什么你没有设置xclient.send_event
?XFlush
必须在XSendEvent
之后调用,否则它不会将窗口设置为始终位于顶部。延迟注释,但XSendEvent会为你设置xclient.send_event。
#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 );
}