wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

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:
cmd/wmii/bar.c | 48++++++++++++++++++++++++++++++++----------------
cmd/wmii/client.c | 69+++++++++++++++++++++++++++++++++++++++++++++++----------------------
cmd/wmii/dat.h | 4+++-
cmd/wmii/fns.h | 4++--
cmd/wmii/main.c | 2+-
cmd/wmii/message.c | 10++++++----
include/stuff/x11.h | 3+++
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), \