Add unified Xresources theme engine, Default.xth export, and xthemes manager plugin

This commit is contained in:
Luxferre
2026-10-21 20:36:27 +03:00
parent f615c6ddbe
commit a31595070c
60 changed files with 3692 additions and 419 deletions
+153 -35
View File
@@ -272,7 +272,8 @@ static void clienttagpush(const Arg *arg);
static void shiftview(const Arg *arg);
static void pushup(const Arg *arg);
static void pushdown(const Arg *arg);
static void readxresources();
static void readxresources(void);
static void reload_dwm_theme(void);
static void load_plugins(void);
static void unload_plugins(void);
@@ -320,6 +321,7 @@ static Window root, wmcheckwin;
/* Empty arrays to be filled from command line, Xresources, and defaults, in decreasing order of precedence */
static char *colors[4][3]; /* 4 schemes, 3 colors each */
static char active_font[256];
static xcb_connection_t *xcon;
@@ -2258,6 +2260,8 @@ propertynotify(XEvent *e)
if (ev->window == root) {
if (ev->atom == XA_WM_NAME)
updatestatus();
else if (ev->atom == XA_RESOURCE_MANAGER)
reload_dwm_theme();
else
drawbars();
} else if (ev->state == PropertyDelete)
@@ -2657,6 +2661,7 @@ setup(void)
root = RootWindow(dpy, screen);
drw = drw_create(dpy, screen, root, sw, sh);
snprintf(active_font, sizeof(active_font), "%s", font);
readxresources();
/* Apply defaults to font and colors*/
for (i = 0; i <= SchemeTabInactive; ++i){
@@ -2666,7 +2671,7 @@ setup(void)
}
}
if (!drw_font_create(drw, font))
if (!drw_font_create(drw, active_font))
die("no fonts could be loaded.");
lrpad = 6;
bh = MAX(drw->font->h + 4, 24);
@@ -2697,6 +2702,10 @@ setup(void)
for (j = 0; j <= SchemeTabInactive; ++j) {
free(colors[j][ColFg]);
free(colors[j][ColBg]);
free(colors[j][ColBorder]);
colors[j][ColFg] = NULL;
colors[j][ColBg] = NULL;
colors[j][ColBorder] = NULL;
}
/* init bars */
updatebars();
@@ -3429,46 +3438,155 @@ zoom(const Arg *arg)
}
static void
set_color_slot(int scm, int col, const char *val)
{
if (!val || !val[0])
return;
free(colors[scm][col]);
colors[scm][col] = strdup(val);
}
static const char *
xrm_lookup_any(XrmDatabase xdb, const char *k1, const char *k2, const char *k3)
{
char *type = NULL;
XrmValue xval;
if (k1 && XrmGetResource(xdb, k1, "*", &type, &xval) && xval.addr && xval.addr[0])
return xval.addr;
if (k2 && XrmGetResource(xdb, k2, "*", &type, &xval) && xval.addr && xval.addr[0])
return xval.addr;
if (k3 && XrmGetResource(xdb, k3, "*", &type, &xval) && xval.addr && xval.addr[0])
return xval.addr;
return NULL;
}
void
readxresources() {
XrmInitialize();
readxresources(void)
{
XrmInitialize();
char* xrm;
if ((xrm = XResourceManagerString(drw->dpy))) {
char *type;
XrmDatabase xdb = XrmGetStringDatabase(xrm);
XrmValue xval;
XrmDatabase xdb = NULL;
Atom actual_type = None;
int actual_format = 0;
unsigned long nitems = 0, bytes_after = 0;
unsigned char *prop = NULL;
if (XrmGetResource(xdb, "dwm.background", "*", &type, &xval) && !colors[SchemeNorm][ColBg] )
colors[SchemeNorm][ColBg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dwm.foreground", "*", &type, &xval) && !colors[SchemeNorm][ColFg] )
colors[SchemeNorm][ColFg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dwm.border", "*", &type, &xval) && !colors[SchemeNorm][ColBorder] )
colors[SchemeNorm][ColBorder] = strdup(xval.addr);
const char *home = getenv("HOME");
char path[512];
snprintf(path, sizeof(path), "%s/.Xresources", (home && home[0]) ? home : "/home/user");
xdb = XrmGetFileDatabase(path);
if (XrmGetResource(xdb, "dwm.selbackground", "*", &type, &xval) && !colors[SchemeSel][ColBg] )
colors[SchemeSel][ColBg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dwm.selforeground", "*", &type, &xval) && !colors[SchemeSel][ColFg] )
colors[SchemeSel][ColFg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dwm.selborder", "*", &type, &xval) && !colors[SchemeSel][ColBorder] )
colors[SchemeSel][ColBorder] = strdup(xval.addr);
if (!xdb && XGetWindowProperty(dpy, root, XA_RESOURCE_MANAGER, 0L, 65536L, False,
XA_STRING, &actual_type, &actual_format,
&nitems, &bytes_after, &prop) == Success && prop) {
if (actual_type == XA_STRING && actual_format == 8 && nitems > 0)
xdb = XrmGetStringDatabase((const char *)prop);
XFree(prop);
}
if (!xdb) {
char *xrm = XResourceManagerString(drw->dpy);
if (xrm)
xdb = XrmGetStringDatabase(xrm);
}
if (XrmGetResource(xdb, "dwm.tabactivebackground", "*", &type, &xval) && !colors[SchemeTabActive][ColBg] )
colors[SchemeTabActive][ColBg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dwm.tabactiveforeground", "*", &type, &xval) && !colors[SchemeTabActive][ColFg] )
colors[SchemeTabActive][ColFg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dwm.tabactiveborder", "*", &type, &xval) && !colors[SchemeTabActive][ColBorder] )
colors[SchemeTabActive][ColBorder] = strdup(xval.addr);
if (xdb) {
const char *ff = xrm_lookup_any(xdb, "theme.fontFace", NULL, NULL);
const char *icf = xrm_lookup_any(xdb, "theme.iconFontFace", NULL, NULL);
const char *bsz = xrm_lookup_any(xdb, "theme.baseFontSize", NULL, NULL);
const char *dwmf = xrm_lookup_any(xdb, "dwm.font", NULL, NULL);
if (XrmGetResource(xdb, "dwm.tabinactivebackground", "*", &type, &xval) && !colors[SchemeTabInactive][ColBg] )
colors[SchemeTabInactive][ColBg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dwm.tabinactiveforeground", "*", &type, &xval) && !colors[SchemeTabInactive][ColFg] )
colors[SchemeTabInactive][ColFg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dwm.tabinactiveborder", "*", &type, &xval) && !colors[SchemeTabInactive][ColBorder] )
colors[SchemeTabInactive][ColBorder] = strdup(xval.addr);
if (ff || bsz) {
int sz = bsz ? atoi(bsz) : 15;
if (sz < 8 || sz > 32)
sz = 15;
snprintf(active_font, sizeof(active_font), "%s, %s %dpx",
ff ? ff : "Fira Code",
icf ? icf : "DejaVuSansM Nerd Font",
sz);
} else if (dwmf) {
snprintf(active_font, sizeof(active_font), "%s", dwmf);
} else {
snprintf(active_font, sizeof(active_font), "%s", font);
}
XrmDestroyDatabase(xdb);
}
set_color_slot(SchemeNorm, ColBg,
xrm_lookup_any(xdb, "theme.bgBar", "dwm.background", "dwm.normbgcolor"));
set_color_slot(SchemeNorm, ColFg,
xrm_lookup_any(xdb, "theme.fgMain", "dwm.foreground", "dwm.normfgcolor"));
set_color_slot(SchemeNorm, ColBorder,
xrm_lookup_any(xdb, "theme.border", "dwm.border", "dwm.normbordercolor"));
set_color_slot(SchemeSel, ColBg,
xrm_lookup_any(xdb, "theme.selBg", "dwm.selbackground", "dwm.selbgcolor"));
set_color_slot(SchemeSel, ColFg,
xrm_lookup_any(xdb, "theme.selFg", "dwm.selforeground", "dwm.selfgcolor"));
set_color_slot(SchemeSel, ColBorder,
xrm_lookup_any(xdb, "theme.accent", "dwm.selborder", "dwm.selbordercolor"));
set_color_slot(SchemeTabActive, ColBg,
xrm_lookup_any(xdb, "theme.selBg", "dwm.tabactivebackground", "dwm.selbgcolor"));
set_color_slot(SchemeTabActive, ColFg,
xrm_lookup_any(xdb, "theme.selFg", "dwm.tabactiveforeground", "dwm.selfgcolor"));
set_color_slot(SchemeTabActive, ColBorder,
xrm_lookup_any(xdb, "theme.accent", "dwm.tabactiveborder", "dwm.selbordercolor"));
set_color_slot(SchemeTabInactive, ColBg,
xrm_lookup_any(xdb, "theme.bgBar", "dwm.tabinactivebackground", "dwm.normbgcolor"));
set_color_slot(SchemeTabInactive, ColFg,
xrm_lookup_any(xdb, "theme.fgMain", "dwm.tabinactiveforeground", "dwm.normfgcolor"));
set_color_slot(SchemeTabInactive, ColBorder,
xrm_lookup_any(xdb, "theme.border", "dwm.tabinactiveborder", "dwm.normbordercolor"));
XrmDestroyDatabase(xdb);
}
}
static void
reload_dwm_theme(void)
{
int i, j;
Monitor *m;
Client *c;
readxresources();
for (i = 0; i <= SchemeTabInactive; ++i) {
for (j = 0; j <= ColBorder; ++j) {
if (!colors[i][j])
colors[i][j] = strdup(defaultcolors[i][j]);
}
}
if (drw->font) {
drw_font_free(drw->font);
drw->font = NULL;
}
if (!drw_font_create(drw, active_font))
drw_font_create(drw, font);
for (i = 0; i < LENGTH(colors); i++) {
free(scheme[i]);
scheme[i] = drw_scm_create(drw, (const char **)colors[i], 3);
}
for (j = 0; j <= SchemeTabInactive; ++j) {
free(colors[j][ColFg]);
free(colors[j][ColBg]);
free(colors[j][ColBorder]);
colors[j][ColFg] = NULL;
colors[j][ColBg] = NULL;
colors[j][ColBorder] = NULL;
}
for (m = mons; m; m = m->next) {
for (c = m->clients; c; c = c->next) {
if (c == m->sel)
XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
else
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
}
}
drawbars();
}
int