sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dwm-winicon-6.2-v1.3.diff (10257B)


      1 diff --git a/config.def.h b/config.def.h
      2 index 1c0b587..5385e27 100644
      3 --- a/config.def.h
      4 +++ b/config.def.h
      5 @@ -5,6 +5,8 @@ static const unsigned int borderpx  = 1;        /* border pixel of windows */
      6  static const unsigned int snap      = 32;       /* snap pixel */
      7  static const int showbar            = 1;        /* 0 means no bar */
      8  static const int topbar             = 1;        /* 0 means bottom bar */
      9 +#define ICONSIZE 20   /* icon size */
     10 +#define ICONSPACING 5 /* space between icon and title */
     11  static const char *fonts[]          = { "monospace:size=10" };
     12  static const char dmenufont[]       = "monospace:size=10";
     13  static const char col_gray1[]       = "#222222";
     14 diff --git a/config.mk b/config.mk
     15 index 6d36cb7..c5d08de 100644
     16 --- a/config.mk
     17 +++ b/config.mk
     18 @@ -20,9 +20,12 @@ FREETYPEINC = /usr/include/freetype2
     19  # OpenBSD (uncomment)
     20  #FREETYPEINC = ${X11INC}/freetype2
     21  
     22 +# Imlib2
     23 +IMLIB2LIBS = -lImlib2
     24 +
     25  # includes and libs
     26  INCS = -I${X11INC} -I${FREETYPEINC}
     27 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
     28 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${IMLIB2LIBS}
     29  
     30  # flags
     31  CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
     32 diff --git a/drw.c b/drw.c
     33 index 8fd1ca4..bb6cfab 100644
     34 --- a/drw.c
     35 +++ b/drw.c
     36 @@ -2,6 +2,7 @@
     37  #include <stdio.h>
     38  #include <stdlib.h>
     39  #include <string.h>
     40 +#include <stdint.h>
     41  #include <X11/Xlib.h>
     42  #include <X11/Xft/Xft.h>
     43  
     44 @@ -378,6 +379,26 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
     45  	return x + (render ? w : 0);
     46  }
     47  
     48 +static uint32_t blend(uint32_t p1rb, uint32_t p1g, uint32_t p2) {
     49 +	uint8_t a = p2 >> 24u;
     50 +	uint32_t rb = (p2 & 0xFF00FFu) + ( (a * p1rb) >> 8u );
     51 +	uint32_t g = (p2 & 0x00FF00u) + ( (a * p1g) >> 8u );
     52 +	return (rb & 0xFF00FFu) | (g & 0x00FF00u);
     53 +}
     54 +
     55 +void
     56 +drw_img(Drw *drw, int x, int y, XImage *img, uint32_t *tmp) 
     57 +{
     58 +	if (!drw || !drw->scheme)
     59 +		return;
     60 +	uint32_t *data = (uint32_t *)img->data, p = drw->scheme[ColBg].pixel, prb = p & 0xFF00FFu, pg = p & 0x00FF00u;
     61 +	int icsz = img->width * img->height, i;
     62 +	for (i = 0; i < icsz; ++i) tmp[i] = blend(prb, pg, data[i]);
     63 +	img->data = (char *) tmp;
     64 +	XPutImage(drw->dpy, drw->drawable, drw->gc, img, 0, 0, x, y, img->width, img->height);
     65 +	img->data = (char *) data;
     66 +}
     67 +
     68  void
     69  drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
     70  {
     71 diff --git a/drw.h b/drw.h
     72 index 4bcd5ad..07b6433 100644
     73 --- a/drw.h
     74 +++ b/drw.h
     75 @@ -52,6 +52,7 @@ void drw_setscheme(Drw *drw, Clr *scm);
     76  /* Drawing functions */
     77  void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
     78  int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
     79 +void drw_img(Drw *drw, int x, int y, XImage *img, uint32_t *tmp);
     80  
     81  /* Map functions */
     82  void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
     83 diff --git a/dwm.c b/dwm.c
     84 index 4465af1..b02a80c 100644
     85 --- a/dwm.c
     86 +++ b/dwm.c
     87 @@ -28,6 +28,8 @@
     88  #include <stdlib.h>
     89  #include <string.h>
     90  #include <unistd.h>
     91 +#include <limits.h>
     92 +#include <stdint.h>
     93  #include <sys/types.h>
     94  #include <sys/wait.h>
     95  #include <X11/cursorfont.h>
     96 @@ -40,6 +42,7 @@
     97  #include <X11/extensions/Xinerama.h>
     98  #endif /* XINERAMA */
     99  #include <X11/Xft/Xft.h>
    100 +#include <Imlib2.h>
    101  
    102  #include "drw.h"
    103  #include "util.h"
    104 @@ -60,7 +63,7 @@
    105  /* enums */
    106  enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
    107  enum { SchemeNorm, SchemeSel }; /* color schemes */
    108 -enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
    109 +enum { NetSupported, NetWMName, NetWMIcon, NetWMState, NetWMCheck,
    110         NetWMFullscreen, NetActiveWindow, NetWMWindowType,
    111         NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
    112  enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
    113 @@ -93,6 +96,7 @@ struct Client {
    114  	int bw, oldbw;
    115  	unsigned int tags;
    116  	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
    117 +	XImage *icon;
    118  	Client *next;
    119  	Client *snext;
    120  	Monitor *mon;
    121 @@ -171,6 +175,7 @@ static void focusmon(const Arg *arg);
    122  static void focusstack(const Arg *arg);
    123  static int getrootptr(int *x, int *y);
    124  static long getstate(Window w);
    125 +static XImage *geticonprop(Window win);
    126  static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
    127  static void grabbuttons(Client *c, int focused);
    128  static void grabkeys(void);
    129 @@ -213,6 +218,7 @@ static void togglebar(const Arg *arg);
    130  static void togglefloating(const Arg *arg);
    131  static void toggletag(const Arg *arg);
    132  static void toggleview(const Arg *arg);
    133 +static void freeicon(Client *c);
    134  static void unfocus(Client *c, int setfocus);
    135  static void unmanage(Client *c, int destroyed);
    136  static void unmapnotify(XEvent *e);
    137 @@ -224,6 +230,7 @@ static void updatenumlockmask(void);
    138  static void updatesizehints(Client *c);
    139  static void updatestatus(void);
    140  static void updatetitle(Client *c);
    141 +static void updateicon(Client *c);
    142  static void updatewindowtype(Client *c);
    143  static void updatewmhints(Client *c);
    144  static void view(const Arg *arg);
    145 @@ -731,7 +738,9 @@ drawbar(Monitor *m)
    146  	if ((w = m->ww - sw - x) > bh) {
    147  		if (m->sel) {
    148  			drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
    149 -			drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
    150 +			drw_text(drw, x, 0, w, bh, lrpad / 2 + (m->sel->icon ? m->sel->icon->width + ICONSPACING : 0), m->sel->name, 0);
    151 +			static uint32_t tmp[ICONSIZE * ICONSIZE];
    152 +			if (m->sel->icon) drw_img(drw, x + lrpad / 2, (bh - m->sel->icon->height) / 2, m->sel->icon, tmp);
    153  			if (m->sel->isfloating)
    154  				drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
    155  		} else {
    156 @@ -899,6 +908,85 @@ getstate(Window w)
    157  	return result;
    158  }
    159  
    160 +static uint32_t prealpha(uint32_t p) {
    161 +	uint8_t a = p >> 24u;
    162 +	uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u;
    163 +	uint32_t g = (a * (p & 0x00FF00u)) >> 8u;
    164 +	return (rb & 0xFF00FFu) | (g & 0x00FF00u) | ((~a) << 24u);
    165 +}
    166 +
    167 +XImage *
    168 +geticonprop(Window win)
    169 +{
    170 +	int format;
    171 +	unsigned long n, extra, *p = NULL;
    172 +	Atom real;
    173 +
    174 +	if (XGetWindowProperty(dpy, win, netatom[NetWMIcon], 0L, LONG_MAX, False, AnyPropertyType, 
    175 +						   &real, &format, &n, &extra, (unsigned char **)&p) != Success)
    176 +		return NULL; 
    177 +	if (n == 0 || format != 32) { XFree(p); return NULL; }
    178 +
    179 +	unsigned long *bstp = NULL;
    180 +	uint32_t w, h, sz;
    181 +
    182 +	{
    183 +		const unsigned long *end = p + n;
    184 +		unsigned long *i;
    185 +		uint32_t bstd = UINT32_MAX, d, m;
    186 +		for (i = p; i < end - 1; i += sz) {
    187 +			if ((w = *i++) > UINT16_MAX || (h = *i++) > UINT16_MAX) { XFree(p); return NULL; }
    188 +			if ((sz = w * h) > end - i) break;
    189 +			if ((m = w > h ? w : h) >= ICONSIZE && (d = m - ICONSIZE) < bstd) { bstd = d; bstp = i; }
    190 +		}
    191 +		if (!bstp) {
    192 +			for (i = p; i < end - 1; i += sz) {
    193 +				if ((w = *i++) > UINT16_MAX || (h = *i++) > UINT16_MAX) { XFree(p); return NULL; }
    194 +				if ((sz = w * h) > end - i) break;
    195 +				if ((d = ICONSIZE - (w > h ? w : h)) < bstd) { bstd = d; bstp = i; }
    196 +			}
    197 +		}
    198 +		if (!bstp) { XFree(p); return NULL; }
    199 +	}
    200 +
    201 +	if ((w = *(bstp - 2)) == 0 || (h = *(bstp - 1)) == 0) { XFree(p); return NULL; }
    202 +
    203 +	uint32_t icw, ich, icsz;
    204 +	if (w <= h) {
    205 +		ich = ICONSIZE; icw = w * ICONSIZE / h;
    206 +		if (icw == 0) icw = 1;
    207 +	}
    208 +	else {
    209 +		icw = ICONSIZE; ich = h * ICONSIZE / w;
    210 +		if (ich == 0) ich = 1;
    211 +	}
    212 +	icsz = icw * ich;
    213 +
    214 +	uint32_t i;
    215 +#if ULONG_MAX > UINT32_MAX
    216 +	uint32_t *bstp32 = (uint32_t *)bstp;
    217 +	for (sz = w * h, i = 0; i < sz; ++i) bstp32[i] = bstp[i];
    218 +#endif
    219 +	uint32_t *icbuf = malloc(icsz << 2); if(!icbuf) { XFree(p); return NULL; }
    220 +	if (w == icw && h == ich) memcpy(icbuf, bstp, icsz << 2);
    221 +	else {
    222 +		Imlib_Image origin = imlib_create_image_using_data(w, h, (DATA32 *)bstp);
    223 +		if (!origin) { XFree(p); free(icbuf); return NULL; }
    224 +		imlib_context_set_image(origin);
    225 +		imlib_image_set_has_alpha(1);
    226 +		Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, w, h, icw, ich);
    227 +		imlib_free_image_and_decache();
    228 +		if (!scaled) { XFree(p); free(icbuf); return NULL; }
    229 +		imlib_context_set_image(scaled);
    230 +		imlib_image_set_has_alpha(1);
    231 +		memcpy(icbuf, imlib_image_get_data_for_reading_only(), icsz << 2);
    232 +		imlib_free_image_and_decache();
    233 +	}
    234 +	XFree(p);
    235 +	for (i = 0; i < icsz; ++i) icbuf[i] = prealpha(icbuf[i]);
    236 +	return XCreateImage(dpy, DefaultVisual(dpy, screen), DefaultDepth(dpy, screen), ZPixmap, 0, (char *)icbuf, icw, ich, 32, 0);
    237 +}
    238 +
    239  int
    240  gettextprop(Window w, Atom atom, char *text, unsigned int size)
    241  {
    242 @@ -1030,6 +1118,8 @@ manage(Window w, XWindowAttributes *wa)
    243  	c->h = c->oldh = wa->height;
    244  	c->oldbw = wa->border_width;
    245  
    246 +	c->icon = NULL;
    247 +	updateicon(c);
    248  	updatetitle(c);
    249  	if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
    250  		c->mon = t->mon;
    251 @@ -1240,6 +1330,11 @@ propertynotify(XEvent *e)
    252  			if (c == c->mon->sel)
    253  				drawbar(c->mon);
    254  		}
    255 +		else if (ev->atom == netatom[NetWMIcon]) {
    256 +			updateicon(c);
    257 +			if (c == c->mon->sel)
    258 +				drawbar(c->mon);
    259 +		}
    260  		if (ev->atom == netatom[NetWMWindowType])
    261  			updatewindowtype(c);
    262  	}
    263 @@ -1556,6 +1651,7 @@ setup(void)
    264  	netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
    265  	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
    266  	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
    267 +	netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False);
    268  	netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
    269  	netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
    270  	netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
    271 @@ -1746,6 +1842,15 @@ toggleview(const Arg *arg)
    272  	}
    273  }
    274  
    275 +void
    276 +freeicon(Client *c)
    277 +{
    278 +	if (c->icon) {
    279 +		XDestroyImage(c->icon);
    280 +		c->icon = NULL;
    281 +	}
    282 +}
    283 +
    284  void
    285  unfocus(Client *c, int setfocus)
    286  {
    287 @@ -1767,6 +1872,7 @@ unmanage(Client *c, int destroyed)
    288  
    289  	detach(c);
    290  	detachstack(c);
    291 +	freeicon(c);
    292  	if (!destroyed) {
    293  		wc.border_width = c->oldbw;
    294  		XGrabServer(dpy); /* avoid race conditions */
    295 @@ -2001,6 +2107,13 @@ updatetitle(Client *c)
    296  		strcpy(c->name, broken);
    297  }
    298  
    299 +void
    300 +updateicon(Client *c)
    301 +{
    302 +	freeicon(c);
    303 +	c->icon = geticonprop(c->win);
    304 +}
    305 +
    306  void
    307  updatewindowtype(Client *c)
    308  {