sites

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

dwm-winicon-6.2-v1.2.diff (9990B)


      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..173504b 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,87 @@ 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) { XFree(p); return NULL; }
    178 +
    179 +	unsigned long *bstp = NULL, w, h;
    180 +
    181 +	{
    182 +		const unsigned long *end = p + n;
    183 +		unsigned long *i;
    184 +		int bstd = INT_MAX, d, m;
    185 +		for (i = p; i < end; ) {
    186 +			w = *i++; h = *i++;
    187 +			m = w > h ? w : h;
    188 +			if (m >= ICONSIZE && (d = m - ICONSIZE) < bstd) { bstd = d; bstp = i; }
    189 +			i += (w * h);
    190 +		}
    191 +		if (!bstp) {
    192 +			for (i = p; i < end; ) {
    193 +				w = *i++; h = *i++;
    194 +				m = w > h ? w : h;
    195 +				if ((d = ICONSIZE - m) < bstd) { bstd = d; bstp = i; }
    196 +				i += (w * h);
    197 +			}
    198 +		}
    199 +		if (!bstp) { XFree(p); return NULL; }
    200 +	}
    201 +
    202 +	w = *(bstp - 2); h = *(bstp - 1);
    203 +
    204 +	int icw, ich, icsz;
    205 +	if (w <= h) {
    206 +		ich = ICONSIZE; icw = w * ICONSIZE / h;
    207 +		if (icw < 1) icw = 1;
    208 +	}
    209 +	else {
    210 +		icw = ICONSIZE; ich = h * ICONSIZE / w;
    211 +		if (ich < 1) ich = 1;
    212 +	}
    213 +	icsz = icw * ich;
    214 +
    215 +	int i;
    216 +#if ULONG_MAX > UINT32_MAX
    217 +	int sz = w * h;
    218 +	uint32_t *bstp32 = (uint32_t *)bstp;
    219 +	for (i = 0; i < sz; ++i) bstp32[i] = bstp[i];
    220 +#endif
    221 +	uint32_t *icbuf = malloc(icsz << 2); if(!icbuf) { XFree(p); return NULL; }
    222 +	if (w == icw && h == ich) memcpy(icbuf, bstp, icsz << 2);
    223 +	else {
    224 +		Imlib_Image origin = imlib_create_image_using_data(w, h, (DATA32 *)bstp);
    225 +		if (!origin) { XFree(p); free(icbuf); return NULL; }
    226 +		imlib_context_set_image(origin);
    227 +		imlib_image_set_has_alpha(1);
    228 +		Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, w, h, icw, ich);
    229 +		imlib_free_image_and_decache();
    230 +		if (!scaled) { XFree(p); free(icbuf); return NULL; }
    231 +		imlib_context_set_image(scaled);
    232 +		imlib_image_set_has_alpha(1);
    233 +		memcpy(icbuf, imlib_image_get_data_for_reading_only(), icsz << 2);
    234 +		imlib_free_image_and_decache();
    235 +	}
    236 +	XFree(p);
    237 +	for (i = 0; i < icsz; ++i) icbuf[i] = prealpha(icbuf[i]);
    238 +	return XCreateImage(dpy, DefaultVisual(dpy, screen), DefaultDepth(dpy, screen), ZPixmap, 0, (char *)icbuf, icw, ich, 32, 0);
    239 +}
    240 +
    241  int
    242  gettextprop(Window w, Atom atom, char *text, unsigned int size)
    243  {
    244 @@ -1030,6 +1120,8 @@ manage(Window w, XWindowAttributes *wa)
    245  	c->h = c->oldh = wa->height;
    246  	c->oldbw = wa->border_width;
    247  
    248 +	c->icon = NULL;
    249 +	updateicon(c);
    250  	updatetitle(c);
    251  	if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
    252  		c->mon = t->mon;
    253 @@ -1240,6 +1332,11 @@ propertynotify(XEvent *e)
    254  			if (c == c->mon->sel)
    255  				drawbar(c->mon);
    256  		}
    257 +		else if (ev->atom == netatom[NetWMIcon]) {
    258 +			updateicon(c);
    259 +			if (c == c->mon->sel)
    260 +				drawbar(c->mon);
    261 +		}
    262  		if (ev->atom == netatom[NetWMWindowType])
    263  			updatewindowtype(c);
    264  	}
    265 @@ -1556,6 +1653,7 @@ setup(void)
    266  	netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
    267  	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
    268  	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
    269 +	netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False);
    270  	netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
    271  	netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
    272  	netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
    273 @@ -1746,6 +1844,15 @@ toggleview(const Arg *arg)
    274  	}
    275  }
    276  
    277 +void
    278 +freeicon(Client *c)
    279 +{
    280 +	if (c->icon) {
    281 +		XDestroyImage(c->icon);
    282 +		c->icon = NULL;
    283 +	}
    284 +}
    285 +
    286  void
    287  unfocus(Client *c, int setfocus)
    288  {
    289 @@ -1767,6 +1874,7 @@ unmanage(Client *c, int destroyed)
    290  
    291  	detach(c);
    292  	detachstack(c);
    293 +	freeicon(c);
    294  	if (!destroyed) {
    295  		wc.border_width = c->oldbw;
    296  		XGrabServer(dpy); /* avoid race conditions */
    297 @@ -2001,6 +2109,13 @@ updatetitle(Client *c)
    298  		strcpy(c->name, broken);
    299  }
    300  
    301 +void
    302 +updateicon(Client *c)
    303 +{
    304 +	freeicon(c);
    305 +	c->icon = geticonprop(c->win);
    306 +}
    307 +
    308  void
    309  updatewindowtype(Client *c)
    310  {