From 9edb8d86fb5a5c3fa3141edb811bf4b444468e5e Mon Sep 17 00:00:00 2001 From: step Date: Fri, 30 Jan 2026 08:59:28 +0100 Subject: [PATCH] Add xresources-xdefaults patch (#195) * Add xresources-xdefaults patch This patch adds the ability to configure st via Xdefaults, in addition to Xresources, like the rxvt-unicode terminal. At startup, st will read and apply the system and user's local Xdefault files, the XServer's Xresources, and the screen and per-host Xdefaults. This patch depends on XRESOURCES_PATCH and is compatible with XRESOURCES_RELOAD_PATCH. I used the following script to stress test this patch. You can also use the script to demo what the patch does. To be simple, it only tests the user's .Xdefaults and .Xresources files, without throwing in the system and per-host files. The script cycles st's background through red, green and blue indefinitely. BACKUP YOUR ~/.Xdefaults and ~/.Xresources FILES BEFORE TESTING. ```sh unset pid if [ -n "$1" ]; then pid=$1 elif pid=$(pgrep -f ^valgrind) && [ -n "$pid" ]; then : else pid=$(pgrep -n ^st$) fi if [ -z "$pid" -o "x$pid" = "x-h" -o "x$pid" = "x--help" ]; then echo "usage: $0 [pid] If pid is omitted valgrind's is used falling back to st's. --------------------------------------------------------------- BACKUP YOUR ~/.Xdefaults and ~/.Xresources FILES BEFORE TESTING ---------------------------------------------------------------" exit 0 fi printf "Attaching pid=%d\n\t%s\n" "$pid" "$(ps -h -ocmd "$pid")" >&2 seconds=0.25 red='#800000' green='#008000' blue='#000080' echo "St.background: $red" >> $HOME/.Xdefaults while true; do sed -i "\$s/$red/$green/" $HOME/.Xdefaults kill -USR1 $pid sleep $seconds sed -i "\$s/$green/$red/" $HOME/.Xdefaults kill -USR1 $pid sleep $seconds echo "St.background: $blue" >> $HOME/.Xresources xrdb -load $HOME/.Xresources kill -USR1 $pid sleep $seconds sed -i '$d' $HOME/.Xresources xrdb -load $HOME/.Xresources kill -USR1 $pid sleep $seconds done ``` * Minor refactoring and freeing / destroying the Xrm database with XrmDestroyDatabase --------- Co-authored-by: Bakkeby --- README.md | 5 +++ patch/xresources.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++ patch/xresources.h | 3 ++ patches.def.h | 7 ++++ 4 files changed, 113 insertions(+) diff --git a/README.md b/README.md index f1b88b8..a3d670a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the ### Changelog: +2026-01-08 - Added the xresources-xdefaults patch + 2025-10-28 - Added the selectionbg-alpha patch 2025-02-20 - Added the drag-n-drop and open-selected-text patches @@ -340,3 +342,6 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the - [xresources](https://st.suckless.org/patches/xresources/) - adds the ability to configure st via Xresources - during startup, st will read and apply the resources named in the resources[] array in config.h + + - xresources-xdefaults + - allows .Xdefaults to be read as well in addition to the RESOURCE_MANAGER property on the root window \ No newline at end of file diff --git a/patch/xresources.c b/patch/xresources.c index acdad4d..a294795 100644 --- a/patch/xresources.c +++ b/patch/xresources.c @@ -35,6 +35,102 @@ resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) return 0; } +#if XRESOURCES_XDEFAULTS_PATCH +/* Returns an XrmDatabase that needs to be freed by the caller. */ +static XrmDatabase +get_resources(Display *dpy) +{ + /*******************************************************************/ + /* Adapted from rxvt-unicode-9.31 rxvttoolkit.C get_resources() */ + /*******************************************************************/ + char *homedir = getenv("HOME"); + char fname[1024]; + + char *displayResource, *xe; + XrmDatabase rdb1; + XrmDatabase database = XrmGetStringDatabase(""); + + /* For ordering, see for example http://www.faqs.org/faqs/Xt-FAQ/ Subject: 20 */ + + /* 6. System wide per application default file. */ + + /* Add in $XAPPLRESDIR/St only; not bothering with XUSERFILESEARCHPATH */ + if ((xe = getenv("XAPPLRESDIR")) || (xe = "/etc/X11/app-defaults")) + { + snprintf(fname, sizeof(fname), "%s/%s", xe, "St"); + + if ((rdb1 = XrmGetFileDatabase(fname))) + XrmMergeDatabases(rdb1, &database); + } + + /* 5. User's per application default file. None. */ + + /* 4. User's defaults file. */ + if (homedir) + { + snprintf(fname, sizeof(fname), "%s/.Xdefaults", homedir); + + if ((rdb1 = XrmGetFileDatabase(fname))) + XrmMergeDatabases(rdb1, &database); + } + + /* Get any Xserver Resources (xrdb). */ + displayResource = XResourceManagerString(dpy); + + if (displayResource) + { + if ((rdb1 = XrmGetStringDatabase(displayResource))) + XrmMergeDatabases(rdb1, &database); + } + + /* Get screen specific resources. */ + displayResource = XScreenResourceString(ScreenOfDisplay(dpy, DefaultScreen(dpy))); + + if (displayResource) + { + if ((rdb1 = XrmGetStringDatabase(displayResource))) + XrmMergeDatabases(rdb1, &database); + + XFree(displayResource); + } + + /* 3. User's per host defaults file. */ + /* Add in XENVIRONMENT file */ + if ((xe = getenv("XENVIRONMENT")) && (rdb1 = XrmGetFileDatabase(xe))) + XrmMergeDatabases(rdb1, &database); + else if (homedir) + { + struct utsname un; + + if (!uname(&un)) + { + snprintf(fname, sizeof(fname), "%s/.Xdefaults-%s", homedir, un.nodename); + + if ((rdb1 = XrmGetFileDatabase(fname))) + XrmMergeDatabases(rdb1, &database); + } + } + + return database; +} + +void +config_init(Display *dpy) +{ + XrmDatabase db; + ResourcePref *p; + + XrmInitialize(); + db = get_resources(dpy); + + for (p = resources; p < resources + LEN(resources); p++) + resource_load(db, p->name, p->type, p->dst); + + XrmDestroyDatabase(db); +} + +#else // !XRESOURCES_XDEFAULTS_PATCH + void config_init(Display *dpy) { @@ -43,6 +139,7 @@ config_init(Display *dpy) ResourcePref *p; XrmInitialize(); + resm = XResourceManagerString(dpy); if (!resm) return; @@ -56,6 +153,7 @@ config_init(Display *dpy) XrmDestroyDatabase(db); } +#endif // XRESOURCES_XDEFAULTS_PATCH #if XRESOURCES_RELOAD_PATCH void diff --git a/patch/xresources.h b/patch/xresources.h index c184852..91d5093 100644 --- a/patch/xresources.h +++ b/patch/xresources.h @@ -1,4 +1,7 @@ #include +#if XRESOURCES_XDEFAULTS_PATCH +#include +#endif // XRESOURCES_XDEFAULTS_PATCH /* Xresources preferences */ enum resource_type { diff --git a/patches.def.h b/patches.def.h index 691e45f..7bf33cc 100644 --- a/patches.def.h +++ b/patches.def.h @@ -535,3 +535,10 @@ * Depends on the XRESOURCES_PATCH. */ #define XRESOURCES_RELOAD_PATCH 0 + +/* This patch adds the ability to configure st via Xdefaults, in addition to Xresources, + * like the rxvt-unicode terminal. At startup, st will read and apply the system and user's + * local Xdefault files, the XServer's Xresources, and the screen and per-host Xdefaults. + * This patch depends on XRESOURCES_PATCH and is compatible with XRESOURCES_RELOAD_PATCH. + */ +#define XRESOURCES_XDEFAULTS_PATCH 0