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 <bakkeby@gmail.com>
This commit is contained in:
step 2026-01-30 08:59:28 +01:00 committed by GitHub
parent b8056cbf24
commit 9edb8d86fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 113 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -1,4 +1,7 @@
#include <X11/Xresource.h>
#if XRESOURCES_XDEFAULTS_PATCH
#include <sys/utsname.h>
#endif // XRESOURCES_XDEFAULTS_PATCH
/* Xresources preferences */
enum resource_type {

View file

@ -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