Use RGBA windows only when required. Closes issue #203.

This commit is contained in:
Kris Maglione 2010-07-09 19:59:40 -04:00
parent b86ca7ea66
commit 05e71d0715
7 changed files with 94 additions and 46 deletions

View File

@ -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*

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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:

View File

@ -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), \