commit 05e71d0715b0280420747639807ab9d28b1a8f0a
parent b86ca7ea66ceb6a3e44b9c37d591aa2019ef6f6c
Author: Kris Maglione <kris@suckless.org>
Date: Fri, 9 Jul 2010 19:59:40 -0400
Use RGBA windows only when required. Closes issue #203.
Diffstat:
7 files changed, 94 insertions(+), 46 deletions(-)
diff --git a/cmd/wmii/bar.c b/cmd/wmii/bar.c
@@ -11,13 +11,16 @@ static Handlers handlers;
for((b)=(s)->bar[__bar_n]; (b); (b)=(b)->next)
void
-bar_init(WMScreen *s) {
+bar_init(WMScreen *s, bool force) {
WinAttr wa;
- if(s->barwin) {
- bar_resize(s);
- return;
- }
+ if(s->barwin)
+ if(force)
+ destroywindow(s->barwin);
+ else {
+ bar_resize(s);
+ return;
+ }
s->brect = s->r;
s->brect.min.y = s->brect.max.y - labelh(def.font);
@@ -27,9 +30,14 @@ bar_init(WMScreen *s) {
| ButtonPressMask
| ButtonReleaseMask
| FocusChangeMask;
- s->barwin = createwindow(&scr.root, s->brect, scr.depth, InputOutput,
- &wa, CWOverrideRedirect
- | CWEventMask);
+ if(s->barwin_rgba)
+ s->barwin = createwindow_rgba(&scr.root, s->brect,
+ &wa, CWOverrideRedirect
+ | CWEventMask);
+ else
+ s->barwin = createwindow(&scr.root, s->brect, scr.depth, InputOutput,
+ &wa, CWOverrideRedirect
+ | CWEventMask);
s->barwin->aux = s;
xdnd_initwindow(s->barwin);
sethandler(s->barwin, &handlers);
@@ -91,9 +99,9 @@ bar_create(Bar **bp, const char *name) {
b = emallocz(sizeof *b);
b->id = id++;
utflcpy(b->name, name, sizeof b->name);
- b->col = def.normcolor;
+ b->colors = def.normcolor;
- strlcat(b->buf, b->col.colstr, sizeof b->buf);
+ strlcat(b->buf, b->colors.colstr, sizeof b->buf);
strlcat(b->buf, " ", sizeof b->buf);
strlcat(b->buf, b->text, sizeof b->buf);
@@ -128,6 +136,7 @@ bar_destroy(Bar **bp, Bar *b) {
void
bar_draw(WMScreen *s) {
Bar *b, *tb, *largest, **pb;
+ Image *ibuf;
Rectangle r;
Align align;
uint width, tw;
@@ -137,6 +146,7 @@ bar_draw(WMScreen *s) {
largest = nil;
width = 0;
+ s->barwin_rgba = false;
foreach_bar(s, b) {
b->r.min = ZP;
b->r.max.y = Dy(s->brect);
@@ -144,6 +154,7 @@ bar_draw(WMScreen *s) {
if(b->text && strlen(b->text))
b->r.max.x += textwidth(def.font, b->text);
width += Dx(b->r);
+ s->barwin_rgba += RGBA_P(b->colors);
}
if(width > Dx(s->brect)) { /* Not enough room. Shrink bars until they all fit. */
@@ -180,18 +191,23 @@ bar_draw(WMScreen *s) {
tb = b;
}
+ ibuf = s->barwin_rgba ? disp.ibuf32 : disp.ibuf;
+
r = rectsubpt(s->brect, s->brect.min);
- fill(disp.ibuf, r, &def.normcolor.bg);
- border(disp.ibuf, r, 1, &def.normcolor.border);
+ fill(ibuf, r, &def.normcolor.bg);
+ border(ibuf, r, 1, &def.normcolor.border);
foreach_bar(s, b) {
align = Center;
if(b == s->bar[BRight])
align = East;
- fill(disp.ibuf, b->r, &b->col.bg);
- drawstring(disp.ibuf, def.font, b->r, align, b->text, &b->col.fg);
- border(disp.ibuf, b->r, 1, &b->col.border);
+ fill(ibuf, b->r, &b->colors.bg);
+ drawstring(ibuf, def.font, b->r, align, b->text, &b->colors.fg);
+ border(ibuf, b->r, 1, &b->colors.border);
}
- copyimage(s->barwin, r, disp.ibuf, ZP);
+
+ if(s->barwin_rgba != (s->barwin->depth == 32))
+ bar_init(s, true);
+ copyimage(s->barwin, r, ibuf, ZP);
}
Bar*
diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c
@@ -95,7 +95,6 @@ group_leader(Group *g) {
Client*
client_create(XWindow w, XWindowAttributes *wa) {
Client **t, *c;
- WinAttr fwa;
char **host = nil;
ulong *pid = nil;
@@ -109,6 +108,7 @@ client_create(XWindow w, XWindowAttributes *wa) {
c->w.type = WWindow;
c->w.xid = w;
c->w.r = c->r;
+ c->w.aux = c;
setborder(&c->w, 0, &(Color){0});
@@ -127,27 +127,9 @@ client_create(XWindow w, XWindowAttributes *wa) {
freestringlist(host);
free(pid);
- fwa.background_pixmap = None;
- fwa.bit_gravity = NorthWestGravity;
- fwa.event_mask = ButtonPressMask
- | ButtonReleaseMask
- | EnterWindowMask
- | ExposureMask
- | PointerMotionMask
- | StructureNotifyMask
- | SubstructureNotifyMask
- | SubstructureRedirectMask;
- fwa.override_redirect = true;
- c->framewin = createwindow_rgba(&scr.root, c->r,
- &fwa, CWBackPixmap
- | CWBitGravity
- | CWEventMask
- | CWOverrideRedirect);
+ c->rgba = render_argb_p(c->w.visual);
+ client_reparent(c);
- c->framewin->aux = c;
- c->w.aux = c;
- sethandler(c->framewin, &framehandler);
- pushhandler(c->framewin, &ignorehandlers, nil);
sethandler(&c->w, &handlers);
pushhandler(&c->w, &ignorehandlers, nil);
@@ -173,7 +155,6 @@ client_create(XWindow w, XWindowAttributes *wa) {
*/
traperrors(true);
XAddToSaveSet(display, w);
- reparentwindow(&c->w, c->framewin, ZP);
if(traperrors(false)) {
client_destroy(c);
return nil;
@@ -186,6 +167,50 @@ client_create(XWindow w, XWindowAttributes *wa) {
return c;
}
+void
+client_reparent(Client *c) {
+ Window *fw;
+ WinAttr wa;
+ bool rgba;
+
+ rgba = c->rgba | RGBA_P(def.normcolor) | RGBA_P(def.focuscolor);
+
+ fw = c->framewin;
+ if(fw && (fw->depth == 32) == rgba)
+ return;
+
+ wa.background_pixmap = None;
+ wa.bit_gravity = NorthWestGravity;
+ wa.event_mask = ButtonPressMask
+ | ButtonReleaseMask
+ | EnterWindowMask
+ | ExposureMask
+ | PointerMotionMask
+ | StructureNotifyMask
+ | SubstructureNotifyMask
+ | SubstructureRedirectMask;
+ wa.override_redirect = true;
+ if(rgba)
+ c->framewin = createwindow_rgba(&scr.root, c->r,
+ &wa, CWBackPixmap
+ | CWBitGravity
+ | CWEventMask
+ | CWOverrideRedirect);
+ else
+ c->framewin = createwindow(&scr.root, c->r, scr.depth, InputOutput,
+ &wa, CWBackPixmap
+ | CWBitGravity
+ | CWEventMask
+ | CWOverrideRedirect);
+
+ c->framewin->aux = c;
+ sethandler(c->framewin, &framehandler);
+ pushhandler(c->framewin, &ignorehandlers, nil);
+ reparentwindow(&c->w, c->framewin, ZP);
+ if(fw)
+ destroywindow(fw);
+}
+
static bool
apply_rules(Client *c) {
IxpMsg m;
diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h
@@ -161,7 +161,7 @@ struct Bar {
char name[256];
int bar;
ushort id;
- CTuple col;
+ CTuple colors;
Rectangle r;
WMScreen* screen;
};
@@ -198,6 +198,7 @@ struct Client {
bool fixedsize;
bool nofocus;
bool noinput;
+ bool rgba;
bool titleless;
bool urgent;
};
@@ -327,6 +328,7 @@ enum {
EXTERN struct WMScreen {
Bar* bar[2];
Window* barwin;
+ bool barwin_rgba;
bool showing;
int barpos;
int idx;
diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h
@@ -68,7 +68,7 @@ Bar* bar_create(Bar**, const char*);
void bar_destroy(Bar**, Bar*);
void bar_draw(WMScreen*);
Bar* bar_find(Bar*, const char*);
-void bar_init(WMScreen*);
+void bar_init(WMScreen*, bool);
void bar_resize(WMScreen*);
void bar_sety(WMScreen*, int);
void bar_setbounds(WMScreen*, int, int);
@@ -88,7 +88,7 @@ void client_manage(Client*);
void client_map(Client*);
void client_message(Client*, char*, long);
bool client_prop(Client*, Atom);
-void client_reparent(Client*, Window*, Point);
+void client_reparent(Client*);
void client_resize(Client*, Rectangle);
void client_setcursor(Client*, Cursor);
void client_seturgent(Client*, int, int);
diff --git a/cmd/wmii/main.c b/cmd/wmii/main.c
@@ -210,7 +210,7 @@ init_screens(void) {
for(v=view; v; v=v->next)
view_init(v, i);
def.snap = Dy(screen->r) / 63;
- bar_init(screens[i]);
+ bar_init(screens[i], false);
}
screen = screens[0];
if(selview)
diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c
@@ -478,7 +478,7 @@ getframe(View *v, int scrn, IxpMsg *m) {
char*
readctl_bar(Bar *b) {
bufclear();
- bufprint("colors %s\n", b->col.colstr);
+ bufprint("colors %s\n", b->colors.colstr);
bufprint("label %s\n", b->text);
return buffer;
}
@@ -488,7 +488,7 @@ message_bar(Bar *b, IxpMsg *m) {
switch(getsym(msg_getword(m, nil))) {
case LCOLORS:
- msg_parsecolors(m, &b->col);
+ msg_parsecolors(m, &b->colors);
break;
case LLABEL:
utflcpy(b->text, (char*)m->pos, sizeof b->text);
@@ -627,8 +627,7 @@ message_root(void *p, IxpMsg *m) {
break;
case LFOCUSCOLORS:
msg_parsecolors(m, &def.focuscolor);
- view_update(selview);
- break;
+ goto updatecolors;
case LFONT:
fn = loadfont(m->pos);
if(fn) {
@@ -666,6 +665,9 @@ message_root(void *p, IxpMsg *m) {
break;
case LNORMCOLORS:
msg_parsecolors(m, &def.normcolor);
+ updatecolors:
+ for(Client *c=client; c; c=c->next)
+ client_reparent(c);
view_update(selview);
break;
case LSELCOLORS:
diff --git a/include/stuff/x11.h b/include/stuff/x11.h
@@ -226,6 +226,9 @@ extern Xft* xft;
XRectangle XRect(Rectangle r);
+#define RGBA_P(tuple) (\
+ ((long)(tuple).fg.alpha + (long)(tuple).bg.alpha + (long)(tuple).border.alpha) < 3 * 0xff00)
+
#define changeprop(w, prop, type, data, n) \
changeproperty(w, prop, type, \
((sizeof(*(data)) == 8 ? 4 : sizeof(*(data))) * 8), \