aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWynn Wolf Arbor2020-03-18 19:47:55 +0100
committerWolfgang Müller2021-04-27 12:28:35 +0200
commit13377b4e34be6d298eeb41a55df939f39ee7f5a7 (patch)
tree6db3350aafcb6156361550436dfddb93c2f104d1
parent5ff1dc2b8f6ec0ab2ebdd132ba1b56cebeb9626c (diff)
downloadcwm-13377b4e34be6d298eeb41a55df939f39ee7f5a7.tar.gz
Calculate colors using the client's visual and colormap
As cwm was using the screen's default visual and colormap to draw all client borders, borders for windows that had a depth of 32 bits were not rendered correctly. The same happened with text in the popup menus which were recently changed to be drawn in the context of the client. This commit introduces a Visual reference for each client, and allocates all potential colors for a client's specific visual and colormap in the client_ctx struct. These colors are then used to draw client borders and popup menus. Additionally, since we touch the drawing code anyway, borders are reintroduced to the popup menus for better contrast.
-rw-r--r--calmwm.h4
-rw-r--r--client.c16
-rw-r--r--conf.c21
-rw-r--r--kbfunc.c4
-rw-r--r--screen.c10
5 files changed, 41 insertions, 14 deletions
diff --git a/calmwm.h b/calmwm.h
index 17ea203..98dee6e 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -138,6 +138,7 @@ struct client_ctx {
struct group_ctx *gc;
Window win;
Colormap colormap;
+ Visual *visual;
int bwidth; /* border width */
int obwidth; /* original border width */
struct geom geom, savegeom, fullgeom;
@@ -191,6 +192,7 @@ struct client_ctx {
char *res_class; /* class hint */
char *res_name; /* class hint */
int initial_state; /* wm hint */
+ XftColor xftcolor[CWM_COLOR_NITEMS];
};
TAILQ_HEAD(client_q, client_ctx);
@@ -480,7 +482,7 @@ void screen_assert_clients_within(struct screen_ctx *);
struct geom screen_area(struct screen_ctx *, int, int, int);
struct screen_ctx *screen_find(Window);
void screen_init(int);
-void screen_prop_win_create(struct screen_ctx *, Window);
+void screen_prop_win_create(struct screen_ctx *, struct client_ctx *);
void screen_prop_win_destroy(struct screen_ctx *);
void screen_prop_win_draw(struct screen_ctx *,
const char *, ...)
diff --git a/client.c b/client.c
index 676b40f..507478b 100644
--- a/client.c
+++ b/client.c
@@ -79,6 +79,7 @@ client_init(Window win, struct screen_ctx *sc)
cc->geom.w = wattr.width;
cc->geom.h = wattr.height;
cc->colormap = wattr.colormap;
+ cc->visual = wattr.visual;
cc->obwidth = wattr.border_width;
cc->bwidth = Conf.bwidth;
@@ -208,6 +209,10 @@ void
client_remove(struct client_ctx *cc)
{
struct screen_ctx *sc = cc->sc;
+ unsigned int i;
+
+ for (i = 0; i < CWM_COLOR_NITEMS; i++)
+ XftColorFree(X_Dpy, cc->visual, cc->colormap, &cc->xftcolor[i]);
TAILQ_REMOVE(&sc->clientq, cc, entry);
@@ -566,26 +571,25 @@ client_urgency(struct client_ctx *cc)
void
client_draw_border(struct client_ctx *cc)
{
- struct screen_ctx *sc = cc->sc;
unsigned long pixel;
if (cc->flags & CLIENT_ACTIVE)
switch (cc->flags & CLIENT_HIGHLIGHT) {
case CLIENT_GROUP:
- pixel = sc->xftcolor[CWM_COLOR_BORDER_GROUP].pixel;
+ pixel = cc->xftcolor[CWM_COLOR_BORDER_GROUP].pixel;
break;
case CLIENT_UNGROUP:
- pixel = sc->xftcolor[CWM_COLOR_BORDER_UNGROUP].pixel;
+ pixel = cc->xftcolor[CWM_COLOR_BORDER_UNGROUP].pixel;
break;
default:
- pixel = sc->xftcolor[CWM_COLOR_BORDER_ACTIVE].pixel;
+ pixel = cc->xftcolor[CWM_COLOR_BORDER_ACTIVE].pixel;
break;
}
else
- pixel = sc->xftcolor[CWM_COLOR_BORDER_INACTIVE].pixel;
+ pixel = cc->xftcolor[CWM_COLOR_BORDER_INACTIVE].pixel;
if (cc->flags & CLIENT_URGENCY)
- pixel = sc->xftcolor[CWM_COLOR_BORDER_URGENCY].pixel;
+ pixel = cc->xftcolor[CWM_COLOR_BORDER_URGENCY].pixel;
XSetWindowBorderWidth(X_Dpy, cc->win, (unsigned int)cc->bwidth);
XSetWindowBorder(X_Dpy, cc->win, pixel);
diff --git a/conf.c b/conf.c
index 6f66ba4..0d0a852 100644
--- a/conf.c
+++ b/conf.c
@@ -447,6 +447,8 @@ void
conf_client(struct client_ctx *cc)
{
struct winname *wn;
+ unsigned int i;
+ XftColor xc;
TAILQ_FOREACH(wn, &Conf.ignoreq, entry) {
if (strncasecmp(wn->name, cc->name, strlen(wn->name)) == 0) {
@@ -454,6 +456,25 @@ conf_client(struct client_ctx *cc)
break;
}
}
+
+ for (i = 0; i < nitems(color_binds); i++) {
+ if (i == CWM_COLOR_MENU_FONT_SEL && *Conf.color[i] == '\0') {
+ xu_xorcolor(cc->xftcolor[CWM_COLOR_MENU_BG],
+ cc->xftcolor[CWM_COLOR_MENU_FG], &xc);
+ xu_xorcolor(cc->xftcolor[CWM_COLOR_MENU_FONT], xc, &xc);
+ if (!XftColorAllocValue(X_Dpy, cc->visual, cc->colormap,
+ &xc.color, &cc->xftcolor[CWM_COLOR_MENU_FONT_SEL]))
+ warnx("XftColorAllocValue: %s", Conf.color[i]);
+ break;
+ }
+ if (!XftColorAllocName(X_Dpy, cc->visual, cc->colormap,
+ Conf.color[i], &cc->xftcolor[i])) {
+ warnx("XftColorAllocName: %s", Conf.color[i]);
+ XftColorAllocName(X_Dpy, cc->visual, cc->colormap,
+ color_binds[i], &cc->xftcolor[i]);
+ }
+ }
+
}
void
diff --git a/kbfunc.c b/kbfunc.c
index 1ce473e..c68aa8c 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -167,7 +167,7 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
CurrentTime) != GrabSuccess)
return;
- screen_prop_win_create(sc, cc->win);
+ screen_prop_win_create(sc, cc);
screen_prop_win_draw(sc, "%+5d%+5d", cc->geom.x, cc->geom.y);
while (move) {
XMaskEvent(X_Dpy, MOUSEMASK, &ev);
@@ -256,7 +256,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
CurrentTime) != GrabSuccess)
return;
- screen_prop_win_create(sc, cc->win);
+ screen_prop_win_create(sc, cc);
screen_prop_win_draw(sc, "%4d x %-4d", cc->dim.w, cc->dim.h);
while (resize) {
XMaskEvent(X_Dpy, MOUSEMASK, &ev);
diff --git a/screen.c b/screen.c
index afd294c..0135449 100644
--- a/screen.c
+++ b/screen.c
@@ -265,13 +265,13 @@ screen_assert_clients_within(struct screen_ctx *sc)
}
void
-screen_prop_win_create(struct screen_ctx *sc, Window win)
+screen_prop_win_create(struct screen_ctx *sc, struct client_ctx *cc)
{
- sc->prop.win = XCreateSimpleWindow(X_Dpy, win, 0, 0, 1, 1, 0,
- sc->xftcolor[CWM_COLOR_MENU_BG].pixel,
- sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
+ sc->prop.win = XCreateSimpleWindow(X_Dpy, cc->win, 0, 0, 1, 1, Conf.bwidth,
+ cc->xftcolor[CWM_COLOR_MENU_FG].pixel,
+ cc->xftcolor[CWM_COLOR_MENU_BG].pixel);
sc->prop.xftdraw = XftDrawCreate(X_Dpy, sc->prop.win,
- sc->visual, sc->colormap);
+ cc->visual, cc->colormap);
XMapWindow(X_Dpy, sc->prop.win);
}