winpl

LD_PRELOAD-based X11 window manipulator
git clone https://git.sinitax.com/sinitax/winpl
Log | Files | Refs | LICENSE | sfeed.txt

commit bb0f4dae1f153f5ce1873c40589c06e064cbb3f2
parent 3d8f53f4fbed3bb3073d97f3b3aa8dfd706ad493
Author: Louis Burda <quent.burda@gmail.com>
Date:   Fri, 24 May 2024 17:05:05 +0200

Make name setting more robust

Diffstat:
MMakefile | 5+++--
Mwinpl.c | 64+++++++++++++++++++++++++++++++++++++++++++---------------------
2 files changed, 46 insertions(+), 23 deletions(-)

diff --git a/Makefile b/Makefile @@ -2,8 +2,9 @@ PREFIX ?= /usr/local BINDIR ?= /bin CFLAGS = -Wunused-variable -Wunused-function -g -LIB_FLAGS = $(CFLAGS) -nostartfiles -fPIC -shared -Wl,-soname,xwrap.so -LOADER_FLAGS = $(CFLAGS) +LDFLAGS = -Wl,-soname,xwrap.so -Wl,-init,winpl_init +LIB_FLAGS = $(CFLAGS) $(LDFLAGS) -nostartfiles -fPIC -shared +LOADER_FLAGS = $(CFLAGS) $(LDFLAGS) LDLIBS = -ldl -lX11 -lXinerama all: winpl diff --git a/winpl.c b/winpl.c @@ -27,7 +27,10 @@ static const char prefix[] = "WINPL_"; static const int prefixlen = sizeof(prefix) - 1; static void *lib_xlib = NULL; -static void (*setwmname)(Display *display, Window window, XTextProperty *text); +static void (*setwmname)(Display *, Window, XTextProperty *) = NULL; +static int (*changeprop)(Display *, Window, Atom, Atom, int, int, const unsigned char *, int) = NULL; + +static bool hook_name = false; static void warn(const char *fmt, ...) @@ -151,13 +154,13 @@ monitor_from_focussed(Display *display, XineramaScreenInfo *info, int mcount) static void set_prop(Display *display, Window window, const char *name, - int type, size_t size, void *val) + int type, size_t size, void *val, int count) { int atom; atom = XInternAtom(display, name, False); - XChangeProperty(display, window, atom, type, size, - PropModeReplace, val, 1); + changeprop(display, window, atom, type, size, + PropModeReplace, val, count); } static void @@ -175,9 +178,6 @@ set_props(Display *display, Window window) pid_t pid, ppid; uid_t uid; - if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); - if (!setwmname) setwmname = dlsym (lib_xlib, "XSetWMName"); - uid = getuid(); pid = getpid(); ppid = getppid(); @@ -282,12 +282,18 @@ set_props(Display *display, Window window) atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); set_prop(display, window, "_NET_WM_WINDOW_TYPE", - XA_ATOM, 32, &atom); + XA_ATOM, 32, &atom, 1); } else if (!strncmp(key, "NAME", keylen)) { /* window name / title */ + hook_name = true; XTextProperty name; XStringListToTextProperty((char**)&val, 1, &name); setwmname(display, window, &name); + set_prop(display, window, "_NET_WM_NAME", + XInternAtom(display, "UTF8_STRING", False), + 8, (void*)val, strlen(val)); + set_prop(display, window, "WM_NAME", + XA_STRING, 8, (void*)val, strlen(val)); } else if (!strncmp(key, "NO_INPUT", keylen)) { /* never take input (focus) */ hints.flags = InputHint; @@ -300,12 +306,9 @@ set_props(Display *display, Window window) } /* set basic properties */ - set_prop(display, window, "_NET_WM_UID", - XA_CARDINAL, 32, &uid); - set_prop(display, window, "_NET_WM_PID", - XA_CARDINAL, 32, &pid); - set_prop(display, window, "_NET_WM_PPID", - XA_CARDINAL, 32, &ppid); + set_prop(display, window, "_NET_WM_UID", XA_CARDINAL, 32, &uid, 1); + set_prop(display, window, "_NET_WM_PID", XA_CARDINAL, 32, &pid, 1); + set_prop(display, window, "_NET_WM_PPID", XA_CARDINAL, 32, &ppid, 1); /* update window pos and geometry */ XMoveResizeWindow(display, window, wx, wy, ww, wh); @@ -325,8 +328,7 @@ XCreateWindow(Display *display, Window parent, int x, int y, Window window; int i; - if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); - if (!func) func = dlsym (lib_xlib, "XCreateWindow"); + if (!func) func = dlsym(lib_xlib, "XCreateWindow"); for (i = 0; i < ScreenCount(display); i++) { /* for toplevel windows */ @@ -355,8 +357,7 @@ XCreateSimpleWindow(Display *display, Window parent, int x, int y, Window window; int i; - if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); - if (!func) func = dlsym (lib_xlib, "XCreateSimpleWindow"); + if (!func) func = dlsym(lib_xlib, "XCreateSimpleWindow"); for (i = 0; i < ScreenCount(display); i++) { /* for toplevel windows */ @@ -380,8 +381,7 @@ XReparentWindow(Display *display, Window window, Window parent, int x, int y) int x, int y) = NULL; int i; - if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); - if (!func) func = dlsym (lib_xlib, "XReparentWindow"); + if (!func) func = dlsym(lib_xlib, "XReparentWindow"); for (i = 0; i < ScreenCount(display); i++) { /* for toplevel windows */ @@ -398,5 +398,27 @@ XReparentWindow(Display *display, Window window, Window parent, int x, int y) void XSetWMName(Display *display, Window window, XTextProperty *text) { - /* keep value set in set_props */ + if (!hook_name) setwmname(display, window, text); +} + +int +XChangeProperty(Display *display, Window window, Atom property, Atom type, int format, int mode, const unsigned char *data, int n) +{ + static Atom name_atom = 0; + static Atom net_name_atom = 0; + + if (!name_atom) name_atom = XInternAtom(display, "WM_NAME", False); + if (!net_name_atom) net_name_atom = XInternAtom(display, "_NET_WM_NAME", False); + if (hook_name && property == name_atom) return 0; + if (hook_name && property == net_name_atom) return 0; + + return changeprop(display, window, property, type, format, mode, data, n); +} + +void +winpl_init(void) +{ + if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); + if (!setwmname) setwmname = dlsym(lib_xlib, "XSetWMName"); + if (!changeprop) changeprop = dlsym(lib_xlib, "XChangeProperty"); }