shod

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 43c2a82f736c97280dda1b07abda703c8fcf1471
parent 5440d9166a67ff7f69efda1a9e3e3ebaa6255034
Author: Lucas de Sena <lucas@seninha.org>
Date:   Sat,  8 Apr 2023 17:26:11 -0300

fix resource loading; fix #37

Diffstat:
Mconfig.c | 16++++++++++------
Mshod.c | 6++++--
Mshod.h | 14+++++++-------
Mxdraw.c | 325+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mxevents.c | 8+++-----
5 files changed, 208 insertions(+), 161 deletions(-)

diff --git a/config.c b/config.c @@ -27,7 +27,6 @@ struct Config config = { .dockwidth = 64, /* width of the dock (or its height, if it is horizontal) */ .dockspace = 64, /* size of each dockapp (64 for windowmaker dockapps) */ .dockgravity = "E", /* placement of the dock */ - .dockcolors = {"#121212", "#2E3436"}, /* notification configuration */ .notifgap = 3, /* gap, in pixels, between notifications */ @@ -35,14 +34,19 @@ struct Config config = { /* title bar */ .titlewidth = 17, - .foreground = "#FFFFFF", /* border */ .borderwidth = 6, - .bordercolors = { - [FOCUSED] = {"#3465A4", "#729FCF", "#204A87"}, - [UNFOCUSED] = {"#555753", "#888A85", "#2E3436"}, - [URGENT] = {"#CC0000", "#EF2929", "#A40000"}, + + /* colors */ + .colors = { + /* (border) MIDDLE LIGHT DARK */ + [FOCUSED] = {"#3465A4", "#729FCF", "#204A87"}, + [UNFOCUSED] = {"#555753", "#888A85", "#2E3436"}, + [URGENT] = {"#CC0000", "#EF2929", "#A40000"}, + + /* (dock, text) BACKGROUND BORDER FOREGROUND */ + [STYLE_OTHER] = {"#CC0000", "#EF2929", "#A40000"}, }, /* size of 3D shadow effect, must be less than borderwidth */ diff --git a/shod.c b/shod.c @@ -198,10 +198,13 @@ initxrm(void) XrmInitialize(); wm.application.class = XrmPermStringToQuark("Shod"); wm.application.name = XrmPermStringToQuark("shod"); + wm.anyresource = XrmPermStringToQuark("?"); for (i = 0; i < NRESOURCES; i++) { wm.resources[i].class = XrmPermStringToQuark(resourceids[i].class); wm.resources[i].name = XrmPermStringToQuark(resourceids[i].name); } + if (!settheme()) + exit(EXIT_FAILURE); setresources(XResourceManagerString(dpy)); } @@ -383,11 +386,10 @@ main(int argc, char *argv[]) initsignal(); initcursors(); initatoms(); - initxrm(); initroot(); initdummywindows(); initdock(); - inittheme(); + initxrm(); /* set up list of monitors */ monupdate(); diff --git a/shod.h b/shod.h @@ -29,7 +29,6 @@ #define RESOURCES \ /* CLASS NAME */\ - X(RES_ANY, "?", "?" )\ X(RES_TYPE, "Type", "type" )\ X(RES_STATE, "State", "state" )\ X(RES_DOCK_POS, "Dockpos", "dockpos" )\ @@ -114,8 +113,9 @@ enum { enum { /* color array indices */ - COLOR_DEF = 0, - COLOR_ALT = 1, + COLOR_BG = 0, + COLOR_BORD = 1, + COLOR_FG = 2, COLOR_MID = 0, COLOR_LIGHT = 1, @@ -128,6 +128,7 @@ enum { FOCUSED, UNFOCUSED, URGENT, + STYLE_OTHER, STYLE_LAST }; @@ -584,6 +585,7 @@ struct WM { XrmClass class; XrmName name; } application, resources[NRESOURCES]; + XrmQuark anyresource; /* * Xrandr information. @@ -674,9 +676,7 @@ struct Config { /* font and color names */ const char *font; - const char *foreground; - const char *dockcolors[2]; - const char *bordercolors[STYLE_LAST][COLOR_LAST]; + const char *colors[STYLE_LAST][COLOR_LAST]; /* hardcoded rules */ struct Rule { @@ -792,9 +792,9 @@ void drawdock(Pixmap pix, int w, int h); void buttonleftdecorate(Window button, Pixmap pix, int style, int pressed); void buttonrightdecorate(Window button, Pixmap pix, int style, int pressed); void copypixmap(Window win); -void inittheme(void); void cleantheme(void); void setresources(char *xrm); +int settheme(void); /* window management routines */ Managefunc managedockapp; diff --git a/xdraw.c b/xdraw.c @@ -1,34 +1,33 @@ #include <err.h> +#include <stdlib.h> #include "shod.h" static GC gc; static struct Theme { XftFont *font; - XftColor fg[STYLE_LAST][2]; - unsigned long border[STYLE_LAST][COLOR_LAST]; - unsigned long dock[2]; + XftColor colors[STYLE_LAST][COLOR_LAST]; } theme; -/* get color from color string */ -static unsigned long -ealloccolor(const char *s) +static int +alloccolor(const char *s, XftColor *color) { - XColor color; - - if(!XAllocNamedColor(dpy, colormap, s, &color, &color)) { + if(!XftColorAllocName(dpy, visual, colormap, s, color)) { warnx("could not allocate color: %s", s); - return BlackPixel(dpy, screen); + return 0; } - return color.pixel; + return 1; } -/* get XftColor from color string */ -static void -eallocxftcolor(const char *s, XftColor *color) +static XftFont * +openfont(const char *s) { - if(!XftColorAllocName(dpy, visual, colormap, s, color)) - errx(1, "could not allocate color: %s", s); + XftFont *font = NULL; + + if ((font = XftFontOpenXlfd(dpy, screen, s)) == NULL) + if ((font = XftFontOpenName(dpy, screen, s)) == NULL) + warnx("could not open font: %s", s); + return font; } /* win was exposed, return the pixmap of its contents and the pixmap's size */ @@ -163,9 +162,12 @@ drawtitle(Drawable pix, const char *text, int w, int drawlines, int style, int p unsigned int top, bot; int i, x, y; - top = theme.border[style][pressed ? COLOR_DARK : COLOR_LIGHT]; - bot = theme.border[style][pressed ? COLOR_LIGHT : COLOR_DARK]; - color = &theme.fg[style][ismenu ? 1 : drawlines]; + top = theme.colors[style][pressed ? COLOR_DARK : COLOR_LIGHT].pixel; + bot = theme.colors[style][pressed ? COLOR_LIGHT : COLOR_DARK].pixel; + if (ismenu || drawlines) + color = &theme.colors[style][COLOR_LIGHT]; + else + color = &theme.colors[STYLE_OTHER][COLOR_FG]; draw = XftDrawCreate(dpy, pix, visual, colormap); len = strlen(text); XftTextExtentsUtf8(dpy, theme.font, text, len, &box); @@ -193,21 +195,21 @@ drawborders(Pixmap pix, int w, int h, int style) { XGCValues val; XRectangle *recs; - unsigned long *decor; + XftColor *decor; int partw, parth; int i; if (w <= 0 || h <= 0) return; - decor = theme.border[style]; + decor = theme.colors[style]; partw = w - 2 * config.borderwidth; parth = h - 2 * config.borderwidth; recs = ecalloc(config.shadowthickness * 4, sizeof(*recs)); /* draw background */ - val.foreground = decor[COLOR_MID]; + val.foreground = decor[COLOR_MID].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangle(dpy, pix, gc, 0, 0, w, h); @@ -218,7 +220,7 @@ drawborders(Pixmap pix, int w, int h, int style) recs[i * 4 + 2] = (XRectangle){.x = w - config.borderwidth + i, .y = config.borderwidth - 1 - i, .width = 1, .height = parth + 2 * (i + 1)}; recs[i * 4 + 3] = (XRectangle){.x = config.borderwidth - 1 - i, .y = h - config.borderwidth + i, .width = partw + 2 * (i + 1), .height = 1}; } - val.foreground = decor[COLOR_LIGHT]; + val.foreground = decor[COLOR_LIGHT].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 4); @@ -229,7 +231,7 @@ drawborders(Pixmap pix, int w, int h, int style) recs[i * 4 + 2] = (XRectangle){.x = config.borderwidth - 1 - i, .y = config.borderwidth - 1 - i, .width = 1, .height = parth + 1 + i * 2}; recs[i * 4 + 3] = (XRectangle){.x = config.borderwidth - 1 - i, .y = config.borderwidth - 1 - i, .width = partw + 1 + i * 2, .height = 1}; } - val.foreground = decor[COLOR_DARK]; + val.foreground = decor[COLOR_DARK].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 4); @@ -242,7 +244,7 @@ drawbackground(Pixmap pix, int x, int y, int w, int h, int style) { XGCValues val; - val.foreground = theme.border[style][COLOR_MID]; + val.foreground = theme.colors[style][COLOR_MID].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangle(dpy, pix, gc, x, y, w, h); } @@ -259,8 +261,8 @@ drawshadow(Pixmap pix, int x, int y, int w, int h, int style, int pressed) if (w <= 0 || h <= 0) return; - top = theme.border[style][pressed ? COLOR_DARK : COLOR_LIGHT]; - bot = theme.border[style][pressed ? COLOR_LIGHT : COLOR_DARK]; + top = theme.colors[style][pressed ? COLOR_DARK : COLOR_LIGHT].pixel; + bot = theme.colors[style][pressed ? COLOR_LIGHT : COLOR_DARK].pixel; recs = ecalloc(config.shadowthickness * 2, sizeof(*recs)); /* draw light shadow */ @@ -289,10 +291,10 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) { XRectangle *recs; XGCValues val; - unsigned long *decor; + XftColor *decor; int x, y, i; - decor = theme.border[style]; + decor = theme.colors[style]; recs = ecalloc(config.shadowthickness * 5, sizeof(*recs)); /* top edge */ @@ -315,7 +317,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 3 + 1] = (XRectangle){.x = x + 0, .y = i, .width = config.corner - 1 - i, .height = 1}; recs[i * 3 + 2] = (XRectangle){.x = x + config.borderwidth - 1 - i, .y = h - config.borderwidth + i, .width = config.titlewidth, .height = 1}; } - val.foreground = (o & W) ? decor[COLOR_DARK] : decor[COLOR_LIGHT]; + val.foreground = (o & W) ? decor[COLOR_DARK].pixel : decor[COLOR_LIGHT].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 3); for (i = 0; i < config.shadowthickness; i++) { @@ -325,7 +327,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 5 + 3] = (XRectangle){.x = x + config.corner - 1 - i, .y = h - config.borderwidth + i, .width = 1, .height = config.borderwidth - i}; recs[i * 5 + 4] = (XRectangle){.x = x + i, .y = h - 1 - i, .width = config.corner - i, .height = 1}; } - val.foreground = (o & W) ? decor[COLOR_LIGHT] : decor[COLOR_DARK]; + val.foreground = (o & W) ? decor[COLOR_LIGHT].pixel : decor[COLOR_DARK].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 5); @@ -338,7 +340,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 5 + 3] = (XRectangle){.x = x + i, .y = h - config.borderwidth + i, .width = config.titlewidth + 1, .height = 1}; recs[i * 5 + 4] = (XRectangle){.x = x + i, .y = h - config.borderwidth + i, .width = 1, .height = config.borderwidth - 1 - i * 2}; } - val.foreground = (o == E) ? decor[COLOR_DARK] : decor[COLOR_LIGHT]; + val.foreground = (o == E) ? decor[COLOR_DARK].pixel : decor[COLOR_LIGHT].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 5); for (i = 0; i < config.shadowthickness; i++) { @@ -346,7 +348,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 3 + 1] = (XRectangle){.x = x + i, .y = config.borderwidth - 1 - i, .width = config.titlewidth, .height = 1}; recs[i * 3 + 2] = (XRectangle){.x = x + i, .y = h - 1 - i, .width = config.corner - i, .height = 1}; } - val.foreground = (o == E) ? decor[COLOR_LIGHT] : decor[COLOR_DARK]; + val.foreground = (o == E) ? decor[COLOR_LIGHT].pixel : decor[COLOR_DARK].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 3); } else { @@ -356,7 +358,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 2 + 0] = (XRectangle){.x = x + i, .y = y + 0, .width = 1, .height = config.corner - 1 - i}; recs[i * 2 + 1] = (XRectangle){.x = x + 0, .y = y + i, .width = config.corner - 1 - i, .height = 1}; } - val.foreground = (o == NW) ? decor[COLOR_DARK] : decor[COLOR_LIGHT]; + val.foreground = (o == NW) ? decor[COLOR_DARK].pixel : decor[COLOR_LIGHT].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 2); for (i = 0; i < config.shadowthickness; i++) { @@ -365,7 +367,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 4 + 2] = (XRectangle){.x = x + config.corner - 1 - i, .y = y + i, .width = 1, .height = config.borderwidth - i}; recs[i * 4 + 3] = (XRectangle){.x = x + i, .y = y + config.corner - 1 - i, .width = config.borderwidth - i, .height = 1}; } - val.foreground = (o == NW) ? decor[COLOR_LIGHT] : decor[COLOR_DARK]; + val.foreground = (o == NW) ? decor[COLOR_LIGHT].pixel : decor[COLOR_DARK].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 4); @@ -377,7 +379,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 3 + 1] = (XRectangle){.x = x + 0, .y = y + i, .width = config.borderwidth - 1 - i, .height = 1}; recs[i * 3 + 2] = (XRectangle){.x = x + config.borderwidth - 1 - i, .y = y + config.titlewidth + i, .width = config.titlewidth, .height = 1}; } - val.foreground = (o == SW) ? decor[COLOR_DARK] : decor[COLOR_LIGHT]; + val.foreground = (o == SW) ? decor[COLOR_DARK].pixel : decor[COLOR_LIGHT].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 3); for (i = 0; i < config.shadowthickness; i++) { @@ -385,7 +387,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 3 + 1] = (XRectangle){.x = x + i, .y = y + config.corner - 1 - i, .width = config.corner - i, .height = 1}; recs[i * 3 + 2] = (XRectangle){.x = x + config.corner - 1 - i, .y = y + config.titlewidth + i, .width = 1, .height = config.borderwidth - i}; } - val.foreground = (o == SW) ? decor[COLOR_LIGHT] : decor[COLOR_DARK]; + val.foreground = (o == SW) ? decor[COLOR_LIGHT].pixel : decor[COLOR_DARK].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 3); @@ -397,7 +399,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 3 + 1] = (XRectangle){.x = x + 0, .y = y + i, .width = config.corner - 1 - i, .height = 1}; recs[i * 3 + 2] = (XRectangle){.x = x + config.titlewidth + i, .y = y + config.borderwidth - 1 - i, .width = 1, .height = config.titlewidth}; } - val.foreground = (o == NE) ? decor[COLOR_DARK] : decor[COLOR_LIGHT]; + val.foreground = (o == NE) ? decor[COLOR_DARK].pixel : decor[COLOR_LIGHT].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 3); for (i = 0; i < config.shadowthickness; i++) { @@ -405,7 +407,7 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 3 + 1] = (XRectangle){.x = x + i, .y = y + config.borderwidth - 1 - i, .width = config.titlewidth, .height = 1}; recs[i * 3 + 2] = (XRectangle){.x = x + config.titlewidth + i, .y = y + config.corner - 1 - i, .width = config.borderwidth - i, .height = 1}; } - val.foreground = (o == NE) ? decor[COLOR_LIGHT] : decor[COLOR_DARK]; + val.foreground = (o == NE) ? decor[COLOR_LIGHT].pixel : decor[COLOR_DARK].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 3); @@ -418,14 +420,14 @@ drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style) recs[i * 4 + 2] = (XRectangle){.x = x + config.titlewidth + i, .y = y + i, .width = 1, .height = config.titlewidth + 1}; recs[i * 4 + 3] = (XRectangle){.x = x + i, .y = y + config.titlewidth + i, .width = config.titlewidth + 1, .height = 1}; } - val.foreground = (o == SE) ? decor[COLOR_DARK] : decor[COLOR_LIGHT]; + val.foreground = (o == SE) ? decor[COLOR_DARK].pixel : decor[COLOR_LIGHT].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 4); for (i = 0; i < config.shadowthickness; i++) { recs[i * 2 + 0] = (XRectangle){.x = x + config.corner - 1 - i, .y = y + i, .width = 1, .height = config.corner - i}; recs[i * 2 + 1] = (XRectangle){.x = x + i, .y = y + config.corner - 1 - i, .width = config.corner - i, .height = 1}; } - val.foreground = (o == SE) ? decor[COLOR_LIGHT] : decor[COLOR_DARK]; + val.foreground = (o == SE) ? decor[COLOR_LIGHT].pixel : decor[COLOR_DARK].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 2); } @@ -449,7 +451,7 @@ drawprompt(Pixmap pix, int w, int h) recs[i * 3 + 1] = (XRectangle){.x = w - config.borderwidth + i, .y = 0, .width = 1, .height = parth + config.borderwidth + i}; recs[i * 3 + 2] = (XRectangle){.x = config.borderwidth - 1 - i, .y = h - config.borderwidth + i, .width = partw + 2 + i * 2, .height = 1}; } - val.foreground = theme.border[FOCUSED][COLOR_LIGHT]; + val.foreground = theme.colors[FOCUSED][COLOR_LIGHT].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 3); @@ -459,7 +461,7 @@ drawprompt(Pixmap pix, int w, int h) recs[i * 3 + 1] = (XRectangle){.x = i, .y = h - 1 - i, .width = w - i * 2, .height = 1}; recs[i * 3 + 2] = (XRectangle){.x = config.borderwidth - 1 - i, .y = i, .width = 1, .height = parth + config.borderwidth}; } - val.foreground = theme.border[FOCUSED][COLOR_DARK]; + val.foreground = theme.colors[FOCUSED][COLOR_DARK].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangles(dpy, pix, gc, recs, config.shadowthickness * 3); @@ -477,11 +479,11 @@ drawdock(Pixmap pix, int w, int h) return; recs = ecalloc(DOCKBORDER * 3, sizeof(*recs)); - val.foreground = theme.dock[COLOR_DEF]; + val.foreground = theme.colors[STYLE_OTHER][COLOR_BG].pixel; XChangeGC(dpy, gc, GCForeground, &val); XFillRectangle(dpy, pix, gc, 0, 0, w, h); - val.foreground = theme.dock[COLOR_ALT]; + val.foreground = theme.colors[STYLE_OTHER][COLOR_BORD].pixel; XChangeGC(dpy, gc, GCForeground, &val); if (config.dockgravity[0] != '\0' && (config.dockgravity[1] == 'F' || config.dockgravity[1] == 'f')) { @@ -609,11 +611,11 @@ buttonleftdecorate(Window button, Pixmap pix, int style, int pressed) w = config.titlewidth - 9; if (pressed) { - top = theme.border[style][COLOR_DARK]; - bot = theme.border[style][COLOR_LIGHT]; + top = theme.colors[style][COLOR_DARK].pixel; + bot = theme.colors[style][COLOR_LIGHT].pixel; } else { - top = theme.border[style][COLOR_LIGHT]; - bot = theme.border[style][COLOR_DARK]; + top = theme.colors[style][COLOR_LIGHT].pixel; + bot = theme.colors[style][COLOR_DARK].pixel; } /* draw background */ @@ -648,13 +650,13 @@ buttonrightdecorate(Window button, Pixmap pix, int style, int pressed) int w; w = (config.titlewidth - 11) / 2; - mid = theme.border[style][COLOR_MID]; + mid = theme.colors[style][COLOR_MID].pixel; if (pressed) { - top = theme.border[style][COLOR_DARK]; - bot = theme.border[style][COLOR_LIGHT]; + top = theme.colors[style][COLOR_DARK].pixel; + bot = theme.colors[style][COLOR_LIGHT].pixel; } else { - top = theme.border[style][COLOR_LIGHT]; - bot = theme.border[style][COLOR_DARK]; + top = theme.colors[style][COLOR_LIGHT].pixel; + bot = theme.colors[style][COLOR_DARK].pixel; } /* draw background */ @@ -707,12 +709,10 @@ copypixmap(Window win) } } -/* initialize decoration pixmap */ void -inittheme(void) +reloadtheme(void) { Pixmap pix; - int i, j; pix = XCreatePixmap( dpy, @@ -721,26 +721,9 @@ inittheme(void) 2 * config.borderwidth + config.titlewidth, depth ); - gc = XCreateGC(dpy, wm.dragwin, GCFillStyle, &(XGCValues){.fill_style = FillSolid}); config.corner = config.borderwidth + config.titlewidth; config.divwidth = config.borderwidth; wm.minsize = config.corner * 2 + 10; - for (i = 0; i < STYLE_LAST; i++) { - for (j = 0; j < COLOR_LAST; j++) { - theme.border[i][j] = ealloccolor(config.bordercolors[i][j]); - } - eallocxftcolor(config.bordercolors[i][COLOR_LIGHT], &theme.fg[i][0]); - eallocxftcolor(config.foreground, &theme.fg[i][1]); - } - for (j = 0; j < 2; j++) - theme.dock[j] = ealloccolor(config.dockcolors[j]); - theme.font = XftFontOpenXlfd(dpy, screen, config.font); - if (theme.font == NULL) { - theme.font = XftFontOpenName(dpy, screen, config.font); - if (theme.font == NULL) { - errx(1, "could not open font: %s", config.font); - } - } drawbackground( pix, 0, 0, @@ -768,19 +751,36 @@ inittheme(void) XFreePixmap(dpy, pix); } +/* initialize decoration pixmap */ +int +settheme(void) +{ + int i, j, error; + + error = 0; + gc = XCreateGC(dpy, wm.dragwin, GCFillStyle, &(XGCValues){.fill_style = FillSolid}); + for (i = 0; i < STYLE_LAST; i++) + for (j = 0; j < COLOR_LAST; j++) + if (!alloccolor(config.colors[i][j], &theme.colors[i][j])) + error = 1; + if ((theme.font = openfont(config.font)) == NULL) + error = 1; + if (error) + return 0; + reloadtheme(); + return 1; +} + /* free font */ void cleantheme(void) { - int i; + int i, j; XftFontClose(dpy, theme.font); - for (i = 0; i < STYLE_LAST; i++) { - XFreeColors(dpy, colormap, theme.border[i], COLOR_LAST, 0); - XftColorFree(dpy, visual, colormap, &theme.fg[i][0]); - XftColorFree(dpy, visual, colormap, &theme.fg[i][1]); - } - XFreeColors(dpy, colormap, theme.dock, 2, 0); + for (i = 0; i < STYLE_LAST; i++) + for (j = 0; j < COLOR_LAST; j++) + XftColorFree(dpy, visual, colormap, &theme.colors[i][j]); XFreeGC(dpy, gc); } @@ -793,72 +793,115 @@ queryrdb(int res) return getresource(xdb, class, name); } +static void +setcolor(char *value, int style, int ncolor) +{ + XftColor color; + + if (!alloccolor(value, &color)) + return; + XftColorFree(dpy, visual, colormap, &theme.colors[style][ncolor]); + theme.colors[style][ncolor] = color; +} + void setresources(char *xrm) { + XftFont *font; long n; char *value; + enum Resource resource; + xdb = NULL; if (xrm == NULL || (xdb = XrmGetStringDatabase(xrm)) == NULL) return; - - if ((value = queryrdb(RES_FACE_NAME)) != NULL) - config.font = value; - if ((value = queryrdb(RES_FOREGROUND)) != NULL) - config.foreground = value; - - if ((value = queryrdb(RES_DOCK_BACKGROUND)) != NULL) - config.dockcolors[COLOR_DEF] = value; - if ((value = queryrdb(RES_DOCK_BORDER)) != NULL) - config.dockcolors[COLOR_ALT] = value; - - if ((value = queryrdb(RES_ACTIVE_BG)) != NULL) - config.bordercolors[FOCUSED][COLOR_MID] = value; - if ((value = queryrdb(RES_ACTIVE_TOP)) != NULL) - config.bordercolors[FOCUSED][COLOR_LIGHT] = value; - if ((value = queryrdb(RES_ACTIVE_BOT)) != NULL) - config.bordercolors[FOCUSED][COLOR_DARK] = value; - - if ((value = queryrdb(RES_INACTIVE_BG)) != NULL) - config.bordercolors[UNFOCUSED][COLOR_MID] = value; - if ((value = queryrdb(RES_INACTIVE_TOP)) != NULL) - config.bordercolors[UNFOCUSED][COLOR_LIGHT] = value; - if ((value = queryrdb(RES_INACTIVE_BOT)) != NULL) - config.bordercolors[UNFOCUSED][COLOR_DARK] = value; - - if ((value = queryrdb(RES_URGENT_BG)) != NULL) - config.bordercolors[URGENT][COLOR_MID] = value; - if ((value = queryrdb(RES_URGENT_TOP)) != NULL) - config.bordercolors[URGENT][COLOR_LIGHT] = value; - if ((value = queryrdb(RES_URGENT_BOT)) != NULL) - config.bordercolors[URGENT][COLOR_DARK] = value; - - if ((value = queryrdb(RES_BORDER_WIDTH)) != NULL) - if ((n = strtol(value, NULL, 10)) > 0 && n < 100) - config.borderwidth = n; - if ((value = queryrdb(RES_SHADOW_WIDTH)) != NULL) - if ((n = strtol(value, NULL, 10)) > 0 && n < 100) - config.shadowthickness = n; - if ((value = queryrdb(RES_TITLE_WIDTH)) != NULL) - if ((n = strtol(value, NULL, 10)) > 0 && n < 100) - config.titlewidth = n; - if ((value = queryrdb(RES_DOCK_WIDTH)) != NULL) - if ((n = strtol(value, NULL, 10)) > 0) - config.dockwidth = n; - if ((value = queryrdb(RES_DOCK_SPACE)) != NULL) - if ((n = strtol(value, NULL, 10)) > 0) - config.dockspace = n; - if ((value = queryrdb(RES_DOCK_GRAVITY)) != NULL) - config.dockgravity = value; - if ((value = queryrdb(RES_NOTIFY_GAP)) != NULL) - if ((n = strtol(value, NULL, 10)) > 0) - config.notifgap = n; - if ((value = queryrdb(RES_NOTIFY_GRAVITY)) != NULL) - config.notifgravity = value; - if ((value = queryrdb(RES_NDESKTOPS)) != NULL) - if ((n = strtol(value, NULL, 10)) > 0 && n < 100) - config.ndesktops = n; - if ((value = queryrdb(RES_SNAP_PROXIMITY)) != NULL) - if ((n = strtol(value, NULL, 10)) >= 0 && n < 100) - config.snap = n; + for (resource = 0; resource < NRESOURCES; resource++) { + value = queryrdb(resource); + if (value == NULL) + continue; + switch (resource) { + case RES_FACE_NAME: + if ((font = openfont(value)) != NULL) { + XftFontClose(dpy, theme.font); + theme.font = font; + } + break; + case RES_FOREGROUND: + setcolor(value, STYLE_OTHER, COLOR_FG); + break; + case RES_DOCK_BACKGROUND: + setcolor(value, STYLE_OTHER, COLOR_BG); + break; + case RES_DOCK_BORDER: + setcolor(value, STYLE_OTHER, COLOR_BORD); + break; + case RES_ACTIVE_BG: + setcolor(value, FOCUSED, COLOR_MID); + break; + case RES_ACTIVE_TOP: + setcolor(value, FOCUSED, COLOR_LIGHT); + break; + case RES_ACTIVE_BOT: + setcolor(value, FOCUSED, COLOR_DARK); + break; + case RES_INACTIVE_BG: + setcolor(value, UNFOCUSED, COLOR_MID); + break; + case RES_INACTIVE_TOP: + setcolor(value, UNFOCUSED, COLOR_LIGHT); + break; + case RES_INACTIVE_BOT: + setcolor(value, UNFOCUSED, COLOR_DARK); + break; + case RES_URGENT_BG: + setcolor(value, URGENT, COLOR_MID); + break; + case RES_URGENT_TOP: + setcolor(value, URGENT, COLOR_LIGHT); + break; + case RES_URGENT_BOT: + setcolor(value, URGENT, COLOR_DARK); + break; + case RES_BORDER_WIDTH: + if ((n = strtol(value, NULL, 10)) > 0 && n < 100) + config.borderwidth = n; + break; + case RES_SHADOW_WIDTH: + if ((n = strtol(value, NULL, 10)) > 0 && n < 100) + config.shadowthickness = n; + break; + case RES_TITLE_WIDTH: + if ((n = strtol(value, NULL, 10)) > 0 && n < 100) + config.titlewidth = n; + break; + case RES_DOCK_WIDTH: + if ((n = strtol(value, NULL, 10)) > 0) + config.dockwidth = n; + break; + case RES_DOCK_SPACE: + if ((n = strtol(value, NULL, 10)) > 0) + config.dockspace = n; + break; + case RES_DOCK_GRAVITY: + config.dockgravity = value; + break; + case RES_NOTIFY_GAP: + if ((n = strtol(value, NULL, 10)) > 0) + config.notifgap = n; + break; + case RES_NOTIFY_GRAVITY: + config.notifgravity = value; + break; + case RES_NDESKTOPS: + if ((n = strtol(value, NULL, 10)) > 0 && n < 100) + config.ndesktops = n; + break; + case RES_SNAP_PROXIMITY: + if ((n = strtol(value, NULL, 10)) >= 0 && n < 100) + config.snap = n; + break; + default: + break; + } + } } diff --git a/xevents.c b/xevents.c @@ -430,15 +430,15 @@ getwintype(Window *win_ret, Window *leader, struct Tab **tab, int *state, XRecta if (classh.res_class != NULL) class[I_CLASS] = name[I_CLASS] = XrmStringToQuark(classh.res_class); else - class[I_CLASS] = name[I_CLASS] = wm.resources[RES_ANY].name; + class[I_CLASS] = name[I_CLASS] = wm.anyresource; if (classh.res_name != NULL) class[I_INSTANCE] = name[I_INSTANCE] = XrmStringToQuark(classh.res_name); else - class[I_INSTANCE] = name[I_INSTANCE] = wm.resources[RES_ANY].name; + class[I_INSTANCE] = name[I_INSTANCE] = wm.anyresource; if (role != NULL) class[I_ROLE] = name[I_ROLE] = XrmStringToQuark(role); else - class[I_ROLE] = name[I_ROLE] = wm.resources[RES_ANY].name; + class[I_ROLE] = name[I_ROLE] = wm.anyresource; free(role); XFree(classh.res_class); XFree(classh.res_name); @@ -1773,8 +1773,6 @@ xeventpropertynotify(XEvent *e) XrmDestroyDatabase(xdb); setresources(str); free(str); - cleantheme(); - inittheme(); TAILQ_FOREACH(c, &wm.focusq, entry) containerdecorate(c, NULL, NULL, 1, C); TAILQ_FOREACH(obj, &wm.menuq, entry)