From 234e3cb390c7bb149ddd281d695d81a368e1a441 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Tue, 17 Jun 2025 11:26:22 -0400 Subject: Improve X11 wallpaper window Signed-off-by: Andrew Opalach --- meson.build | 2 +- src/window_x11.c | 80 +++++++++++++++++++++++++++++++++++++--------- src/window_x11.h | 1 + subprojects/libnaunet.wrap | 2 +- 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/meson.build b/meson.build index 74a4441..146c7e6 100644 --- a/meson.build +++ b/meson.build @@ -103,7 +103,7 @@ elif get_option('api') == 'dx11' endif if get_option('window') == 'x11' - x11 = dependency('X11') + x11 = dependency('x11') xext = dependency('xext') xrandr = dependency('xrandr') stela_src += ['src/window_x11.c'] diff --git a/src/window_x11.c b/src/window_x11.c index cf54ba1..413e9bd 100644 --- a/src/window_x11.c +++ b/src/window_x11.c @@ -1,6 +1,5 @@ #define AL_LOG_SECTION "x11" #include -#include #include "window_x11.h" #include "common.h" @@ -36,7 +35,8 @@ bool stl_global_init(bool skip_graphics) if (!stl_maybe_load_egl()) return false; global.egl.display = eglGetDisplay((EGLNativeDisplayType)global.x11_d); if (!global.egl.display) { - log_error("Failed to get x11 EGL display."); + log_error("Failed to get X11-native EGL display."); + return false; } if (!stl_load_egl(&global.egl)) return false; #endif @@ -76,7 +76,7 @@ bool stl_global_init(bool skip_graphics) s32 stl_global_get_poll_fd() { - return XConnectionNumber(global.x11_d); + return ConnectionNumber(global.x11_d); } void stl_global_process_events() @@ -147,9 +147,6 @@ static bool window_x11_create_window(struct stl_window *window, u32 width, u32 h xattr.override_redirect = False; XChangeWindowAttributes(global.x11_d, xw->window, CWOverrideRedirect, &xattr); - XMapWindow(global.x11_d, xw->window); - XFlush(global.x11_d); - XWindowAttributes gwa; XGetWindowAttributes(global.x11_d, xw->window, &gwa); al_assert(gwa.width > 0 && gwa.height > 0); @@ -158,16 +155,10 @@ static bool window_x11_create_window(struct stl_window *window, u32 width, u32 h if (flags & STELA_WINDOW_WALLPAPER) { Atom net_wm_type = XInternAtom(global.x11_d, "_NET_WM_WINDOW_TYPE", False); if (net_wm_type) { - Atom desktop_type = XInternAtom(global.x11_d, "_NET_WM_WINDOW_TYPE_DESKTOP", False); + //Atom window_type = XInternAtom(global.x11_d, "_NET_WM_WINDOW_TYPE_DESKTOP", False); + Atom window_type = XInternAtom(global.x11_d, "_NET_WM_WINDOW_TYPE_SPLASH", False); XChangeProperty(global.x11_d, xw->window, net_wm_type, XA_ATOM, 32, - PropModeReplace, (u8 *)&desktop_type, 1); - } - - Atom net_wm_state = XInternAtom(global.x11_d, "_NET_WM_STATE", False); - if (net_wm_state) { - Atom net_wm_sticky = XInternAtom(global.x11_d, "_NET_WM_STATE_STICKY", False); - XChangeProperty(global.x11_d, xw->window, net_wm_state, XA_ATOM, 32, - PropModeAppend, (u8*)&net_wm_sticky, 1); + PropModeReplace, (u8 *)&window_type, 1); } Atom motif_wm_hints = XInternAtom(global.x11_d, "_MOTIF_WM_HINTS", False); @@ -185,6 +176,16 @@ static bool window_x11_create_window(struct stl_window *window, u32 width, u32 h PropModeReplace, (u8 *)&hints, sizeof(hints) / sizeof(long)); } + Atom net_wm_state = XInternAtom(global.x11_d, "_NET_WM_STATE", False); + if (net_wm_state) { + Atom net_wm_below = XInternAtom(global.x11_d, "_NET_WM_STATE_BELOW", False); + XChangeProperty(global.x11_d, xw->window, net_wm_state, XA_ATOM, 32, + PropModeAppend, (u8 *)&net_wm_below, 1); + Atom net_wm_sticky = XInternAtom(global.x11_d, "_NET_WM_STATE_STICKY", False); + XChangeProperty(global.x11_d, xw->window, net_wm_state, XA_ATOM, 32, + PropModeAppend, (u8 *)&net_wm_sticky, 1); + } + Atom net_wm_desktop = XInternAtom(global.x11_d, "_NET_WM_DESKTOP", False); if (net_wm_desktop) { ulong all_desktops = XWIN_ALL_DESKTOPS; @@ -193,6 +194,55 @@ static bool window_x11_create_window(struct stl_window *window, u32 width, u32 h } } + XMapWindow(global.x11_d, xw->window); + XFlush(global.x11_d); + + if (flags & STELA_WINDOW_WALLPAPER) { + Window root = DefaultRootWindow(global.x11_d); + + /* + XEvent event; + event.xclient.type = ClientMessage; + event.xclient.serial = 0; + event.xclient.send_event = True; + event.xclient.display = global.x11_d; + event.xclient.window = xw->window; + event.xclient.message_type = XInternAtom(global.x11_d, "_NET_WM_STATE", False); + event.xclient.format = 32; + + event.xclient.data.l[0] = _NET_WM_STATE_ADD; + event.xclient.data.l[1] = XInternAtom(global.x11_d, "_NET_WM_STATE_BELOW", False); + event.xclient.data.l[2] = 0; + event.xclient.data.l[3] = 0; + event.xclient.data.l[4] = 0; + XSendEvent(global.x11_d, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &event); + + //event.xclient.data.l[1] = XInternAtom(global.x11_d, "_NET_WM_STATE_STICKY", False); + //XSendEvent(global.x11_d, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &event); + */ + + // Enable click-through by making the window shape 0x0. + Window win = xw->window; + while (win != None) { + Region region; + if ((region = XCreateRegion())) { + XShapeCombineRegion(global.x11_d, xw->window, ShapeInput, 0, 0, region, ShapeSet); + XDestroyRegion(region); + } + + Window parent, *children = NULL; + u32 num_children; + if (XQueryTree(global.x11_d, win, &root, &parent, &children, &num_children)) { + if (children) XFree(children); + } + + win = (parent == root) ? None : parent; + } + + // Not sure if this flush matters. + XFlush(global.x11_d); + } + #ifdef STELA_API_OPENGL if (!x11_egl_init(xw)) return false; #endif diff --git a/src/window_x11.h b/src/window_x11.h index f8305dd..32749cd 100644 --- a/src/window_x11.h +++ b/src/window_x11.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "window.h" #include "egl_common.h" diff --git a/subprojects/libnaunet.wrap b/subprojects/libnaunet.wrap index 8388a93..462c1a7 100644 --- a/subprojects/libnaunet.wrap +++ b/subprojects/libnaunet.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://git.akon.city/libnaunet -revision = 393e266f6bfceb25a97cd1cf28dfc72cac9e9f81 +revision = fc8df3fe9cd15fe7b0b86c6584e0b3fb487d6886 depth = 1 -- cgit v1.2.3-101-g0448