Add window icons, enable it by default
This commit is contained in:
parent
71eedeb85b
commit
c9585c6314
|
@ -13,7 +13,11 @@ draw_title_basic(Bar *bar, BarDrawArg *a)
|
|||
Monitor *m = bar->mon;
|
||||
|
||||
if (m->sel) {
|
||||
if (colorselectedtitle)
|
||||
drw_setscheme(drw, scheme[m == selmon ? SchemeTitleSel : SchemeTitleNorm]);
|
||||
else
|
||||
drw_setscheme(drw, scheme[m == selmon ? SchemeTitleNorm : SchemeTitleNorm]);
|
||||
|
||||
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0, False);
|
||||
if (m->sel->isfloating)
|
||||
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
|
||||
|
|
12
bar/title.c
12
bar/title.c
|
@ -22,8 +22,10 @@ draw_title(Bar *bar, BarDrawArg *a)
|
|||
for (i = 0, c = bar->mon->clients; c; c = c->next, i++) {
|
||||
if (!ISVISIBLE(c))
|
||||
continue;
|
||||
if (bar->mon->sel == c)
|
||||
if (bar->mon->sel == c && colorselectedtitle)
|
||||
scm = SchemeTitleSel;
|
||||
else if (!colorselectedtitle)
|
||||
scm = SchemeTitleNorm;
|
||||
else if (HIDDEN(c))
|
||||
scm = SchemeTitleHidden;
|
||||
else
|
||||
|
@ -34,7 +36,13 @@ draw_title(Bar *bar, BarDrawArg *a)
|
|||
padding = (tabw - TEXTW(c->name) + lrpad) / 2;
|
||||
|
||||
drw_setscheme(drw, scheme[scm]);
|
||||
drw_text(drw, x, 0, tabw + (i < remainder ? 1 : 0), bh, padding, c->name, 0, False);
|
||||
#if USEWINICON
|
||||
drw_text(drw, x, 0, tabw + (i < remainder ? 1 : 0), bh, padding + (c->name ? c->icw + iconspacing : 0), c->name, 0, False);
|
||||
if (c->icon)
|
||||
drw_pic(drw, x + padding, (bh - c->ich) / 2, c->icw, c->ich, c->icon);
|
||||
#else
|
||||
drw_text(drw, x, 0, tabw + padding (i < remainder ? 1 : 0), bh, padding, c->name, 0, False);
|
||||
#endif
|
||||
x += tabw + (i < remainder ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
|
149
draw.c
149
draw.c
|
@ -24,13 +24,12 @@
|
|||
/* toggle */
|
||||
#include "toggle.h"
|
||||
|
||||
/* imlib - for rendering window icons */
|
||||
unsigned int ew;
|
||||
|
||||
#if USEWINICON
|
||||
#include <Imlib2.h>
|
||||
#endif
|
||||
|
||||
unsigned int ew;
|
||||
|
||||
/* transition scheme for powerlines */
|
||||
Clr transcheme[3];
|
||||
|
||||
|
@ -79,6 +78,77 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if USEWINICON
|
||||
Picture
|
||||
drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int srch, unsigned int dstw, unsigned int dsth) {
|
||||
Pixmap pm;
|
||||
Picture pic;
|
||||
GC gc;
|
||||
|
||||
if (srcw <= (dstw << 1u) && srch <= (dsth << 1u)) {
|
||||
XImage img = {
|
||||
srcw, srch, 0, ZPixmap, src,
|
||||
ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
|
||||
32, 0, 32,
|
||||
0, 0, 0
|
||||
};
|
||||
XInitImage(&img);
|
||||
|
||||
pm = XCreatePixmap(drw->dpy, drw->root, srcw, srch, 32);
|
||||
gc = XCreateGC(drw->dpy, pm, 0, NULL);
|
||||
XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, srcw, srch);
|
||||
XFreeGC(drw->dpy, gc);
|
||||
|
||||
pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
|
||||
XFreePixmap(drw->dpy, pm);
|
||||
|
||||
XRenderSetPictureFilter(drw->dpy, pic, FilterBilinear, NULL, 0);
|
||||
XTransform xf;
|
||||
xf.matrix[0][0] = (srcw << 16u) / dstw; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0;
|
||||
xf.matrix[1][0] = 0; xf.matrix[1][1] = (srch << 16u) / dsth; xf.matrix[1][2] = 0;
|
||||
xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = 65536;
|
||||
XRenderSetPictureTransform(drw->dpy, pic, &xf);
|
||||
} else {
|
||||
Imlib_Image origin = imlib_create_image_using_data(srcw, srch, (DATA32 *)src);
|
||||
if (!origin) return None;
|
||||
imlib_context_set_image(origin);
|
||||
imlib_image_set_has_alpha(1);
|
||||
Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, srcw, srch, dstw, dsth);
|
||||
imlib_free_image_and_decache();
|
||||
if (!scaled) return None;
|
||||
imlib_context_set_image(scaled);
|
||||
imlib_image_set_has_alpha(1);
|
||||
|
||||
XImage img = {
|
||||
dstw, dsth, 0, ZPixmap, (char *)imlib_image_get_data_for_reading_only(),
|
||||
ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
|
||||
32, 0, 32,
|
||||
0, 0, 0
|
||||
};
|
||||
XInitImage(&img);
|
||||
|
||||
pm = XCreatePixmap(drw->dpy, drw->root, dstw, dsth, 32);
|
||||
gc = XCreateGC(drw->dpy, pm, 0, NULL);
|
||||
XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, dstw, dsth);
|
||||
imlib_free_image_and_decache();
|
||||
XFreeGC(drw->dpy, gc);
|
||||
|
||||
pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
|
||||
XFreePixmap(drw->dpy, pm);
|
||||
}
|
||||
|
||||
return pic;
|
||||
}
|
||||
|
||||
void
|
||||
drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic)
|
||||
{
|
||||
if (!drw)
|
||||
return;
|
||||
XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture, 0, 0, 0, 0, x, y, w, h);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* drawing powerline arrows */
|
||||
void
|
||||
drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash)
|
||||
|
@ -238,68 +308,6 @@ drw_setscheme(Drw *drw, Clr *scm)
|
|||
drw->scheme = scm;
|
||||
}
|
||||
|
||||
#if USEWINICON
|
||||
Picture
|
||||
drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int srch, unsigned int dstw, unsigned int dsth) {
|
||||
Pixmap pm;
|
||||
Picture pic;
|
||||
GC gc;
|
||||
|
||||
if (srcw <= (dstw << 1u) && srch <= (dsth << 1u)) {
|
||||
XImage img = {
|
||||
srcw, srch, 0, ZPixmap, src,
|
||||
ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
|
||||
32, 0, 32,
|
||||
0, 0, 0
|
||||
};
|
||||
XInitImage(&img);
|
||||
|
||||
pm = XCreatePixmap(drw->dpy, drw->root, srcw, srch, 32);
|
||||
gc = XCreateGC(drw->dpy, pm, 0, NULL);
|
||||
XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, srcw, srch);
|
||||
XFreeGC(drw->dpy, gc);
|
||||
|
||||
pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
|
||||
XFreePixmap(drw->dpy, pm);
|
||||
|
||||
XRenderSetPictureFilter(drw->dpy, pic, FilterBilinear, NULL, 0);
|
||||
XTransform xf;
|
||||
xf.matrix[0][0] = (srcw << 16u) / dstw; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0;
|
||||
xf.matrix[1][0] = 0; xf.matrix[1][1] = (srch << 16u) / dsth; xf.matrix[1][2] = 0;
|
||||
xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = 65536;
|
||||
XRenderSetPictureTransform(drw->dpy, pic, &xf);
|
||||
} else {
|
||||
Imlib_Image origin = imlib_create_image_using_data(srcw, srch, (DATA32 *)src);
|
||||
if (!origin) return None;
|
||||
imlib_context_set_image(origin);
|
||||
imlib_image_set_has_alpha(1);
|
||||
Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, srcw, srch, dstw, dsth);
|
||||
imlib_free_image_and_decache();
|
||||
if (!scaled) return None;
|
||||
imlib_context_set_image(scaled);
|
||||
imlib_image_set_has_alpha(1);
|
||||
|
||||
XImage img = {
|
||||
dstw, dsth, 0, ZPixmap, (char *)imlib_image_get_data_for_reading_only(),
|
||||
ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
|
||||
32, 0, 32,
|
||||
0, 0, 0
|
||||
};
|
||||
XInitImage(&img);
|
||||
|
||||
pm = XCreatePixmap(drw->dpy, drw->root, dstw, dsth, 32);
|
||||
gc = XCreateGC(drw->dpy, pm, 0, NULL);
|
||||
XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, dstw, dsth);
|
||||
imlib_free_image_and_decache();
|
||||
XFreeGC(drw->dpy, gc);
|
||||
|
||||
pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
|
||||
XFreePixmap(drw->dpy, pm);
|
||||
}
|
||||
|
||||
return pic;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
|
||||
|
@ -402,17 +410,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
|||
return x + (render ? w : 0);
|
||||
}
|
||||
|
||||
/* draw image */
|
||||
#if USEWINICON
|
||||
void
|
||||
drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic)
|
||||
{
|
||||
if (!drw)
|
||||
return;
|
||||
XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture, 0, 0, 0, 0, x, y, w, h);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* map out area */
|
||||
void
|
||||
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
|
||||
|
|
15
draw.h
15
draw.h
|
@ -32,6 +32,10 @@ typedef struct {
|
|||
Fnt *font;
|
||||
} Drw;
|
||||
|
||||
#if USEWINICON
|
||||
Picture drw_picture_create_resized(Drw *drw, char *src, unsigned int src_w, unsigned int src_h, unsigned int dst_w, unsigned int dst_h);
|
||||
#endif
|
||||
|
||||
/* Drawable abstraction */
|
||||
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||
|
@ -43,6 +47,10 @@ void drw_font_free(Fnt* set);
|
|||
unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup);
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup);
|
||||
|
||||
#if USEWINICON
|
||||
void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic);
|
||||
#endif
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
|
||||
Clr *drw_scm_create(Drw *drw, char *clrnames[], const unsigned int alphas[], size_t clrcount);
|
||||
|
@ -55,18 +63,11 @@ void drw_cur_free(Drw *drw, Cur *cursor);
|
|||
void drw_setscheme(Drw *drw, Clr *scm);
|
||||
void drw_settrans(Drw *drw, Clr *psc, Clr *nsc);
|
||||
|
||||
#if USEWINICON
|
||||
Picture drw_picture_create_resized(Drw *drw, char *src, unsigned int src_w, unsigned int src_h, unsigned int dst_w, unsigned int dst_h);
|
||||
#endif
|
||||
|
||||
/* Drawing functions */
|
||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
|
||||
void drw_polygon(Drw *drw, int x, int y, int ow, int oh, int sw, int sh, const XPoint *points, int npoints, int shape, int filled);
|
||||
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup);
|
||||
void drw_arrow(Drw* drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash);
|
||||
#if USEWINICON
|
||||
void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic);
|
||||
#endif
|
||||
|
||||
/* Map functions */
|
||||
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
|
||||
|
|
106
speedwm.c
106
speedwm.c
|
@ -108,6 +108,9 @@ enum { NetSupported, NetWMName,
|
|||
#if USESYSTRAY
|
||||
NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation,
|
||||
NetSystemTrayVisual, NetWMWindowTypeDock, NetSystemTrayOrientationHorz,
|
||||
#endif
|
||||
#if USEWINICON
|
||||
NetWMIcon,
|
||||
#endif
|
||||
NetClientListStacking, NetClientInfo, NetLast }; /* EWMH atoms */
|
||||
|
||||
|
@ -210,6 +213,9 @@ struct Client {
|
|||
int hintsvalid; /* https://git.suckless.org/dwm/commit/8806b6e2379372900e3d9e0bf6604bc7f727350b.html */
|
||||
int bw, oldbw;
|
||||
unsigned int tags; /* tags */
|
||||
#if USEWINICON
|
||||
unsigned int icw, ich; Picture icon;
|
||||
#endif
|
||||
int isfixed,
|
||||
ispermanent,
|
||||
isfloating,
|
||||
|
@ -464,6 +470,12 @@ static int getrootptr(int *x, int *y);
|
|||
static long getstate(Window w);
|
||||
static unsigned int getsystraywidth();
|
||||
|
||||
#if USEWINICON
|
||||
static Picture geticonprop(Window w, unsigned int *icw, unsigned int *ich);
|
||||
static void freeicon(Client *c);
|
||||
static void updateicon(Client *c);
|
||||
#endif
|
||||
|
||||
#if USESYSTRAY
|
||||
static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
|
||||
#else
|
||||
|
@ -2534,6 +2546,85 @@ getatomprop(Client *c, Atom prop)
|
|||
return atom;
|
||||
}
|
||||
|
||||
#if USEWINICON
|
||||
static uint32_t prealpha(uint32_t p) {
|
||||
uint8_t a = p >> 24u;
|
||||
uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u;
|
||||
uint32_t g = (a * (p & 0x00FF00u)) >> 8u;
|
||||
return (rb & 0xFF00FFu) | (g & 0x00FF00u) | (a << 24u);
|
||||
}
|
||||
|
||||
Picture
|
||||
geticonprop(Window win, unsigned int *picw, unsigned int *pich)
|
||||
{
|
||||
int format;
|
||||
unsigned long n, extra, *p = NULL;
|
||||
Atom real;
|
||||
|
||||
if (XGetWindowProperty(dpy, win, netatom[NetWMIcon], 0L, LONG_MAX, False, AnyPropertyType,
|
||||
&real, &format, &n, &extra, (unsigned char **)&p) != Success)
|
||||
return None;
|
||||
if (n == 0 || format != 32) { XFree(p); return None; }
|
||||
|
||||
unsigned long *bstp = NULL;
|
||||
uint32_t w, h, sz;
|
||||
{
|
||||
unsigned long *i; const unsigned long *end = p + n;
|
||||
uint32_t bstd = UINT32_MAX, d, m;
|
||||
for (i = p; i < end - 1; i += sz) {
|
||||
if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
|
||||
if ((sz = w * h) > end - i) break;
|
||||
if ((m = w > h ? w : h) >= iconsize && (d = m - iconsize) < bstd) { bstd = d; bstp = i; }
|
||||
}
|
||||
if (!bstp) {
|
||||
for (i = p; i < end - 1; i += sz) {
|
||||
if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
|
||||
if ((sz = w * h) > end - i) break;
|
||||
if ((d = iconsize - (w > h ? w : h)) < bstd) { bstd = d; bstp = i; }
|
||||
}
|
||||
}
|
||||
if (!bstp) { XFree(p); return None; }
|
||||
}
|
||||
|
||||
if ((w = *(bstp - 2)) == 0 || (h = *(bstp - 1)) == 0) { XFree(p); return None; }
|
||||
|
||||
uint32_t icw, ich;
|
||||
if (w <= h) {
|
||||
ich = iconsize; icw = w * iconsize / h;
|
||||
if (icw == 0) icw = 1;
|
||||
}
|
||||
else {
|
||||
icw = iconsize; ich = h * iconsize / w;
|
||||
if (ich == 0) ich = 1;
|
||||
}
|
||||
*picw = icw; *pich = ich;
|
||||
|
||||
uint32_t i, *bstp32 = (uint32_t *)bstp;
|
||||
for (sz = w * h, i = 0; i < sz; ++i) bstp32[i] = prealpha(bstp[i]);
|
||||
|
||||
Picture ret = drw_picture_create_resized(drw, (char *)bstp, w, h, icw, ich);
|
||||
XFree(p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
freeicon(Client *c)
|
||||
{
|
||||
if (c->icon) {
|
||||
XRenderFreePicture(dpy, c->icon);
|
||||
c->icon = None;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
updateicon(Client *c)
|
||||
{
|
||||
freeicon(c);
|
||||
c->icon = geticonprop(c->win, &c->icw, &c->ich);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
getrootptr(int *x, int *y)
|
||||
{
|
||||
|
@ -3259,6 +3350,9 @@ manage(Window w, XWindowAttributes *wa)
|
|||
c->oldbw = wa->border_width;
|
||||
c->cfact = 1.0;
|
||||
|
||||
#if USEWINICON
|
||||
updateicon(c);
|
||||
#endif
|
||||
updatetitle(c);
|
||||
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
|
||||
c->mon = t->mon;
|
||||
|
@ -4316,7 +4410,11 @@ propertynotify(XEvent *e)
|
|||
if (c == c->mon->sel && !selmon->hidetitle)
|
||||
drawbaritems(c->mon);
|
||||
}
|
||||
if (ev->atom == netatom[NetWMWindowType])
|
||||
else if (ev->atom == netatom[NetWMIcon]) {
|
||||
updateicon(c);
|
||||
if (c == c->mon->sel)
|
||||
drawbaritems(c->mon);
|
||||
} if (ev->atom == netatom[NetWMWindowType])
|
||||
updatewindowtype(c);
|
||||
if (ev->atom == motifatom)
|
||||
updatemotifhints(c);
|
||||
|
@ -5172,6 +5270,9 @@ setup(void)
|
|||
netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
|
||||
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
|
||||
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
|
||||
#if USEWINICON
|
||||
netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False);
|
||||
#endif
|
||||
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
|
||||
|
||||
#if USESYSTRAY
|
||||
|
@ -5791,6 +5892,9 @@ unmanage(Client *c, int destroyed)
|
|||
|
||||
detach(c);
|
||||
detachstack(c);
|
||||
#if USEWINICON
|
||||
freeicon(c);
|
||||
#endif
|
||||
if (!destroyed) {
|
||||
wc.border_width = c->oldbw;
|
||||
XGrabServer(dpy); /* avoid race conditions */
|
||||
|
|
2
toggle.h
2
toggle.h
|
@ -31,5 +31,5 @@ Not compatible with BSDs so for those, set this to 0. */
|
|||
* If you wish to disable them though, set them to 0.
|
||||
*/
|
||||
#define USEIMLIB2 1 /* Whether or not to include imlib2. Required by USEWINICON and USETAGPREVIEW. */
|
||||
#define USEWINICON 0 /* Whether or not to include window icons. Requires imlib to be enabled in toggle.mk and it must be installed. */
|
||||
#define USEWINICON 1 /* Whether or not to include window icons. Requires imlib to be enabled in toggle.mk and it must be installed. */
|
||||
#define USETAGPREVIEW 0 /* Whether or not to include tag previews. Requires imlib to be enabled in toggle.mk and it must be installed. */
|
||||
|
|
Loading…
Reference in a new issue