qt/X11使窗口没有边框并且不在任务栏里显示

时间:2021-01-12 08:06:25
最近想弄一些widgets出来,突然遇到这样的大问题。这里给出了解决方案,方案是基于KWin的。不过我在compiz下测试成功,原理其实很简单,我们知道,如果KWin下可以使窗口不在任务栏里显示,那么在metacity,compiz等等窗口管理器下也是没有任务栏项(taskbar entry)的。
 
窗口的透明需要在QWidget的构造函数里面调用QWidget的构造函数实现,而直接通过setWFlags则就算设置了也没效果。使用Qt::WStyle_NoBorder | Qt:WStyle_Customize。

在下面的代码当中,MainForm继承自MainFormBase,而MainFormBase是一个用Qt Designer生成的一个QWidget的子类。而这个MainForm我创建多几个效果也是一样的,每一个都没有任务栏项。而主程序使用QApplication就可以了。
qt/X11使窗口没有边框并且不在任务栏里显示MainForm::MainForm(QWidget  * parent,  const   char   * name)
qt/X11使窗口没有边框并且不在任务栏里显示:MainFormBase(parent, name, 
qt/X11使窗口没有边框并且不在任务栏里显示              Qt::WStyle_NoBorder 
|  Qt::WStyle_Customize  //  <--- set flags here
qt/X11使窗口没有边框并且不在任务栏里显示
             )
qt/X11使窗口没有边框并且不在任务栏里显示qt/X11使窗口没有边框并且不在任务栏里显示
... {
qt/X11使窗口没有边框并且不在任务栏里显示    
// do not set flags here, otherwise it doesn't work
qt/X11使窗口没有边框并且不在任务栏里显示
qt/X11使窗口没有边框并且不在任务栏里显示    
// the code below is to let the window have no taskbar entry
qt/X11使窗口没有边框并且不在任务栏里显示
    Atom net_wm_state_skip_taskbar=XInternAtom (qt_xdisplay(),
qt/X11使窗口没有边框并且不在任务栏里显示                                                
"_NET_WM_STATE_SKIP_TASKBAR", False);
qt/X11使窗口没有边框并且不在任务栏里显示    Atom net_wm_state 
= XInternAtom (qt_xdisplay(),
qt/X11使窗口没有边框并且不在任务栏里显示                                     
"_NET_WM_STATE", False);
qt/X11使窗口没有边框并且不在任务栏里显示    XChangeProperty (qt_xdisplay(), winId(), net_wm_state,
qt/X11使窗口没有边框并且不在任务栏里显示                     XA_ATOM, 
32, PropModeAppend,
qt/X11使窗口没有边框并且不在任务栏里显示                     (unsigned 
char *)&net_wm_state_skip_taskbar, 1);
qt/X11使窗口没有边框并且不在任务栏里显示}

另外,这几个头文件也是必须的:
qt/X11使窗口没有边框并且不在任务栏里显示# include <X11/Xlib.h>
qt/X11使窗口没有边框并且不在任务栏里显示#
include <X11/Xutil.h>
qt/X11使窗口没有边框并且不在任务栏里显示#
include <X11/Xatom.h>


感谢为我提供思路的Stefan。
另外,这个网址的内容可以参考: http://standards.freedesktop.org/wm-spec/wm-spec-1.4.html#id2511406

后记:其实是我搞错了,上面的方法是X11的方法,而不是专门KWin的。如果是专门KWin,那么可以专门用这方法:
qt/X11使窗口没有边框并且不在任务栏里显示KWin::setState( winId(), NET::SkipTaskbar  ||  NET::SkipPager )

在没有在taskbar显示的同时,我们还希望不在pager里面显示。
qt/X11使窗口没有边框并且不在任务栏里显示MainForm::MainForm(QWidget  * parent,  const   char   * name)
qt/X11使窗口没有边框并且不在任务栏里显示:MainFormBase(parent, name, 
qt/X11使窗口没有边框并且不在任务栏里显示              Qt::WStyle_NoBorder 
|  Qt::WStyle_Customize  //  <--- set flags here
qt/X11使窗口没有边框并且不在任务栏里显示
             )
qt/X11使窗口没有边框并且不在任务栏里显示qt/X11使窗口没有边框并且不在任务栏里显示
... {
qt/X11使窗口没有边框并且不在任务栏里显示    
// do not set flags here, otherwise it doesn't work
qt/X11使窗口没有边框并且不在任务栏里显示
qt/X11使窗口没有边框并且不在任务栏里显示    
// the code below is to let the window have no taskbar entry and not display in the pager
qt/X11使窗口没有边框并且不在任务栏里显示
    Atom net_wm_state_skip_taskbar=XInternAtom (qt_xdisplay(),
qt/X11使窗口没有边框并且不在任务栏里显示                                                
"_NET_WM_STATE_SKIP_TASKBAR", False);
qt/X11使窗口没有边框并且不在任务栏里显示    Atom net_wm_state_skip_pager
=XInternAtom (qt_xdisplay(),
qt/X11使窗口没有边框并且不在任务栏里显示                                                
"_NET_WM_STATE_SKIP_PAGER", False);
qt/X11使窗口没有边框并且不在任务栏里显示    Atom net_wm_state 
= XInternAtom (qt_xdisplay(),
qt/X11使窗口没有边框并且不在任务栏里显示                                     
"_NET_WM_STATE", False);
qt/X11使窗口没有边框并且不在任务栏里显示    XChangeProperty (qt_xdisplay(), winId(), net_wm_state,
qt/X11使窗口没有边框并且不在任务栏里显示                     XA_ATOM, 
32, PropModeAppend,
qt/X11使窗口没有边框并且不在任务栏里显示                     (unsigned 
char *)&net_wm_state_skip_taskbar, 1);
qt/X11使窗口没有边框并且不在任务栏里显示    XChangeProperty (qt_xdisplay(), winId(), net_wm_state,
qt/X11使窗口没有边框并且不在任务栏里显示                     XA_ATOM, 
32, PropModeAppend,
qt/X11使窗口没有边框并且不在任务栏里显示                     (unsigned 
char *)&net_wm_state_skip_pager, 1);
qt/X11使窗口没有边框并且不在任务栏里显示}

感谢Aaron J. Seigo和John Tapsell的指导。