X11/GLX window 高于桌面
X11/GLX window above desktop
我想为桌面创建 opengl 应用程序,但图标和墙纸都坏了。
Window 应该在图标下:
创建代码 window:
XSetWindowAttributes swa;
swa.background_pixmap = ParentRelative;
swa.background_pixel = 0;
swa.border_pixmap = 0;
swa.border_pixel = 0;
swa.bit_gravity = 0;
swa.win_gravity = 0;
swa.override_redirect = True;
swa.colormap = XCreateColormap(dis, root, vi->visual, AllocNone);
swa.event_mask = StructureNotifyMask | ExposureMask;
unsigned long mask = CWOverrideRedirect | CWBackingStore | CWBackPixel | CWBorderPixel | CWColormap;
window = XCreateWindow(display, desktop, 0, 0,
display_width, display_height, 0, vi->depth,
InputOutput, vi->visual, mask, &swa); // vi -XVisualInfo
XLowerWindow(display, window);
long value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DESKTOP", false);
XChangeProperty(display, window,
XInternAtom(display, "_NET_WM_WINDOW_TYPE", false),
XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
Atom xa;
xa = ATOM(_WIN_LAYER);
if (xa != None) {
long prop = 0;
XChangeProperty(display, window, xa, XA_CARDINAL, 32,
PropModeAppend, (unsigned char *)&prop, 1);
}
xa = ATOM(_NET_WM_STATE);
if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_BELOW);
XChangeProperty(display, window, xa, XA_ATOM, 32, PropModeAppend,
(unsigned char *)&xa_prop, 1);
}
if (transparency < 1.0) {
uint32_t cardinal_alpha = (uint32_t) (transparency * (uint32_t)-1) ;
XChangeProperty(display, window,
XInternAtom(display, "_NET_WM_WINDOW_OPACITY", 0),
XA_CARDINAL, 32, PropModeReplace, (uint8_t*) &cardinal_alpha, 1);
}
XLowerWindow(display, window);
ctx = glXCreateContextAttribsARB(dis, fbc, NULL, True, gl3attr); //ctx = GLXContext
接下来我创建 XMapWindow(dis, window), glXMakeCurrent(dis, window, ctx), glViewport and clearColor(red)\swapBuffers (in cycle)
注意:ATOM = #define ATOM(a) XInternAtom(dis, #a, False)
遗憾的是,没有任何解决方案适用于 100% 的情况。最直接的解决方案是直接绘制到根 window:打开与 X 的连接,获取根 window 的 xid,查询它配置的视觉效果,创建兼容的 GLX 上下文,绘制到那个。 (这对于 X11 来说有些可靠;但是在 Microsoft Windows 或 macOS 上做类似的事情是不可能的。)
但是您无法更改 visual/pixelformat,并且仅绘制到根 window 不一定会使它成为桌面图标的 "underlay"。你看,大多数 "desktops" 都是通过在根 window 之上(但在其他所有内容之下)创建自己的全屏 window 来实现的,甚至可以用来绘制壁纸那么
直接绘制到根目录 window 只会给你想要的效果,如果选择的桌面环境配合并将其桌面和图标绘制为透明的合成 window ;或者它是否会使用 X 形扩展来屏蔽图标(我不知道有任何 DE 会这样做)。
我想为桌面创建 opengl 应用程序,但图标和墙纸都坏了。
Window 应该在图标下:
创建代码 window:
XSetWindowAttributes swa;
swa.background_pixmap = ParentRelative;
swa.background_pixel = 0;
swa.border_pixmap = 0;
swa.border_pixel = 0;
swa.bit_gravity = 0;
swa.win_gravity = 0;
swa.override_redirect = True;
swa.colormap = XCreateColormap(dis, root, vi->visual, AllocNone);
swa.event_mask = StructureNotifyMask | ExposureMask;
unsigned long mask = CWOverrideRedirect | CWBackingStore | CWBackPixel | CWBorderPixel | CWColormap;
window = XCreateWindow(display, desktop, 0, 0,
display_width, display_height, 0, vi->depth,
InputOutput, vi->visual, mask, &swa); // vi -XVisualInfo
XLowerWindow(display, window);
long value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DESKTOP", false);
XChangeProperty(display, window,
XInternAtom(display, "_NET_WM_WINDOW_TYPE", false),
XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
Atom xa;
xa = ATOM(_WIN_LAYER);
if (xa != None) {
long prop = 0;
XChangeProperty(display, window, xa, XA_CARDINAL, 32,
PropModeAppend, (unsigned char *)&prop, 1);
}
xa = ATOM(_NET_WM_STATE);
if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_BELOW);
XChangeProperty(display, window, xa, XA_ATOM, 32, PropModeAppend,
(unsigned char *)&xa_prop, 1);
}
if (transparency < 1.0) {
uint32_t cardinal_alpha = (uint32_t) (transparency * (uint32_t)-1) ;
XChangeProperty(display, window,
XInternAtom(display, "_NET_WM_WINDOW_OPACITY", 0),
XA_CARDINAL, 32, PropModeReplace, (uint8_t*) &cardinal_alpha, 1);
}
XLowerWindow(display, window);
ctx = glXCreateContextAttribsARB(dis, fbc, NULL, True, gl3attr); //ctx = GLXContext
接下来我创建 XMapWindow(dis, window), glXMakeCurrent(dis, window, ctx), glViewport and clearColor(red)\swapBuffers (in cycle)
注意:ATOM = #define ATOM(a) XInternAtom(dis, #a, False)
遗憾的是,没有任何解决方案适用于 100% 的情况。最直接的解决方案是直接绘制到根 window:打开与 X 的连接,获取根 window 的 xid,查询它配置的视觉效果,创建兼容的 GLX 上下文,绘制到那个。 (这对于 X11 来说有些可靠;但是在 Microsoft Windows 或 macOS 上做类似的事情是不可能的。)
但是您无法更改 visual/pixelformat,并且仅绘制到根 window 不一定会使它成为桌面图标的 "underlay"。你看,大多数 "desktops" 都是通过在根 window 之上(但在其他所有内容之下)创建自己的全屏 window 来实现的,甚至可以用来绘制壁纸那么
直接绘制到根目录 window 只会给你想要的效果,如果选择的桌面环境配合并将其桌面和图标绘制为透明的合成 window ;或者它是否会使用 X 形扩展来屏蔽图标(我不知道有任何 DE 会这样做)。