diff --git a/render.c b/render.c index 94dc3d3..ea99e53 100644 --- a/render.c +++ b/render.c @@ -703,6 +703,8 @@ struct renderer* rd_new(const char** paths, const char* entry, const char* force int shader_version = 330; const char* module = force_mod; char* xwintype = NULL, * wintitle = "GLava"; + char** xwinstates = malloc(1); + size_t xwinstates_sz = 0; bool loading_module = true; struct gl_sfbo* current = NULL; size_t t_count = 0; @@ -770,6 +772,14 @@ struct renderer* rd_new(const char** paths, const char* entry, const char* force gl->geometry[3] = *(int*) args[3]; }) }, + { + .name = "addxwinstate", .fmt = "s", + .handler = RHANDLER(name, args, { + ++xwinstates_sz; + xwinstates = realloc(xwinstates, sizeof(*xwinstates) * xwinstates_sz); + xwinstates[xwinstates_sz - 1] = strdup((char*) args[0]); + }) + }, { .name = "setsource", .fmt = "s", .handler = RHANDLER(name, args, { r->audio_source_request = strdup((char*) args[0]); }) }, @@ -1094,7 +1104,12 @@ struct renderer* rd_new(const char** paths, const char* entry, const char* force xwin_settype(r, xwintype); free(xwintype); } - + + for (size_t t = 0; t < xwinstates_sz; ++t) { + xwin_addstate(r, xwinstates[t]); + free(xwinstates); + } + return r; } diff --git a/shaders/rc.glsl b/shaders/rc.glsl index b3cc740..1bd18c0 100644 --- a/shaders/rc.glsl +++ b/shaders/rc.glsl @@ -66,6 +66,27 @@ */ #request setxwintype "normal" +/* (X11 only) EWMH Window state atoms (multiple can be specified). + Possible values are: + + "modal", "sticky", "maximized_vert", "maximized_horz", + "shaded", "skip_taskbar", "skip_pager", "hidden", "fullscreen", + "above", "below", "demands_attention", "focused" + + This will add _NET_WM_STATE_(TYPE) atoms to _NET_WM_STATE, + where (TYPE) is one of the window states listed (after being + converted to uppercase). + + The lines below (commented out by default) are of relevance + if you are trying to get GLava to behave as a desktop widget + and your WM is not correctly responding to the "desktop" value + for `setxwintype`. +*/ +// #request addxwinstate "sticky" +// #request addxwinstate "skip_taskbar" +// #request addxwinstate "skip_pager" +// #request addxwinstate "above" + /* PulseAudio source. Can be a number or a name of an audio sink or device to record from. Set to "auto" to use the default output device. */ diff --git a/xwin.c b/xwin.c index 6ed1d9e..a749091 100644 --- a/xwin.c +++ b/xwin.c @@ -64,10 +64,10 @@ bool xwin_should_render(void) { /* Set window types defined by the EWMH standard, possible values: -> "desktop", "dock", "toolbar", "menu", "utility", "splash", "dialog", "normal" */ -void xwin_settype(struct renderer* rd, const char* type) { +static void xwin_changeatom(struct renderer* rd, const char* type, const char* atom, const char* fmt, int mode) { Window w = glfwGetX11Window((GLFWwindow*) rd_get_impl_window(rd)); Display* d = XOpenDisplay(0); - Atom wtype = XInternAtom(d, "_NET_WM_WINDOW_TYPE", false); + Atom wtype = XInternAtom(d, atom, false); size_t len = strlen(type), t; char formatted[len + 1]; for (t = 0; t < len + 1; ++t) { @@ -78,12 +78,20 @@ void xwin_settype(struct renderer* rd, const char* type) { } } char buf[256]; - snprintf(buf, sizeof(buf), "_NET_WM_WINDOW_TYPE_%s", formatted); + snprintf(buf, sizeof(buf), fmt, formatted); Atom desk = XInternAtom(d, buf, false); - XChangeProperty(d, w, wtype, XA_ATOM, 32, PropModeReplace, (unsigned char*) &desk, 1); + XChangeProperty(d, w, wtype, XA_ATOM, 32, mode, (unsigned char*) &desk, 1); XCloseDisplay(d); } +void xwin_settype(struct renderer* rd, const char* type) { + xwin_changeatom(rd, type, "_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_%s", PropModeReplace); +} + +void xwin_addstate(struct renderer* rd, const char* state) { + xwin_changeatom(rd, state, "_NET_WM_STATE", "_NET_WM_STATE_%s", PropModeAppend); +} + static Pixmap get_pixmap(Display* d, Window w) { Pixmap p; Atom act_type; diff --git a/xwin.h b/xwin.h index 01824a0..16f2d43 100644 --- a/xwin.h +++ b/xwin.h @@ -1,4 +1,5 @@ bool xwin_should_render(void); void xwin_settype(struct renderer* rd, const char* type); +void xwin_addstate(struct renderer* rd, const char* state); unsigned int xwin_copyglbg(struct renderer* rd, unsigned int texture);