sites

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

dwm-winicon-6.3-v2.1.diff (12527B)


      1 diff --git a/config.def.h b/config.def.h
      2 index a2ac963..322d181 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 16   /* 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 b6eb7e0..f3c01b0 100644
     16 --- a/config.mk
     17 +++ b/config.mk
     18 @@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2
     19  
     20  # includes and libs
     21  INCS = -I${X11INC} -I${FREETYPEINC}
     22 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
     23 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender -lImlib2
     24  
     25  # flags
     26  CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
     27 diff --git a/drw.c b/drw.c
     28 index 4cdbcbe..9b474c5 100644
     29 --- a/drw.c
     30 +++ b/drw.c
     31 @@ -4,6 +4,7 @@
     32  #include <string.h>
     33  #include <X11/Xlib.h>
     34  #include <X11/Xft/Xft.h>
     35 +#include <Imlib2.h>
     36  
     37  #include "drw.h"
     38  #include "util.h"
     39 @@ -71,6 +72,7 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
     40  	drw->w = w;
     41  	drw->h = h;
     42  	drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
     43 +	drw->picture = XRenderCreatePicture(dpy, drw->drawable, XRenderFindVisualFormat(dpy, DefaultVisual(dpy, screen)), 0, NULL);
     44  	drw->gc = XCreateGC(dpy, root, 0, NULL);
     45  	XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
     46  
     47 @@ -85,14 +87,18 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
     48  
     49  	drw->w = w;
     50  	drw->h = h;
     51 +	if (drw->picture)
     52 +		XRenderFreePicture(drw->dpy, drw->picture);
     53  	if (drw->drawable)
     54  		XFreePixmap(drw->dpy, drw->drawable);
     55  	drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
     56 +	drw->picture = XRenderCreatePicture(drw->dpy, drw->drawable, XRenderFindVisualFormat(drw->dpy, DefaultVisual(drw->dpy, drw->screen)), 0, NULL);
     57  }
     58  
     59  void
     60  drw_free(Drw *drw)
     61  {
     62 +	XRenderFreePicture(drw->dpy, drw->picture);
     63  	XFreePixmap(drw->dpy, drw->drawable);
     64  	XFreeGC(drw->dpy, drw->gc);
     65  	drw_fontset_free(drw->fonts);
     66 @@ -236,6 +242,67 @@ drw_setscheme(Drw *drw, Clr *scm)
     67  		drw->scheme = scm;
     68  }
     69  
     70 +Picture
     71 +drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int srch, unsigned int dstw, unsigned int dsth) {
     72 +	Pixmap pm;
     73 +	Picture pic;
     74 +	GC gc;
     75 +
     76 +	if (srcw <= (dstw << 1u) && srch <= (dsth << 1u)) {
     77 +		XImage img = {
     78 +			srcw, srch, 0, ZPixmap, src,
     79 +			ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
     80 +			32, 0, 32,
     81 +			0, 0, 0
     82 +		};
     83 +		XInitImage(&img);
     84 +
     85 +		pm = XCreatePixmap(drw->dpy, drw->root, srcw, srch, 32);
     86 +		gc = XCreateGC(drw->dpy, pm, 0, NULL);
     87 +		XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, srcw, srch);
     88 +		XFreeGC(drw->dpy, gc);
     89 +
     90 +		pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
     91 +		XFreePixmap(drw->dpy, pm);
     92 +
     93 +		XRenderSetPictureFilter(drw->dpy, pic, FilterBilinear, NULL, 0);
     94 +		XTransform xf;
     95 +		xf.matrix[0][0] = (srcw << 16u) / dstw; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0;
     96 +		xf.matrix[1][0] = 0; xf.matrix[1][1] = (srch << 16u) / dsth; xf.matrix[1][2] = 0;
     97 +		xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = 65536;
     98 +		XRenderSetPictureTransform(drw->dpy, pic, &xf);
     99 +	} else {
    100 +		Imlib_Image origin = imlib_create_image_using_data(srcw, srch, (DATA32 *)src);
    101 +		if (!origin) return None;
    102 +		imlib_context_set_image(origin);
    103 +		imlib_image_set_has_alpha(1);
    104 +		Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, srcw, srch, dstw, dsth);
    105 +		imlib_free_image_and_decache();
    106 +		if (!scaled) return None;
    107 +		imlib_context_set_image(scaled);
    108 +		imlib_image_set_has_alpha(1);
    109 +
    110 +		XImage img = {
    111 +		    dstw, dsth, 0, ZPixmap, (char *)imlib_image_get_data_for_reading_only(),
    112 +		    ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
    113 +		    32, 0, 32,
    114 +		    0, 0, 0
    115 +		};
    116 +		XInitImage(&img);
    117 +
    118 +		pm = XCreatePixmap(drw->dpy, drw->root, dstw, dsth, 32);
    119 +		gc = XCreateGC(drw->dpy, pm, 0, NULL);
    120 +		XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, dstw, dsth);
    121 +		imlib_free_image_and_decache();
    122 +		XFreeGC(drw->dpy, gc);
    123 +
    124 +		pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
    125 +		XFreePixmap(drw->dpy, pm);
    126 +	}
    127 +
    128 +	return pic;
    129 +}
    130 +
    131  void
    132  drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
    133  {
    134 @@ -379,6 +446,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
    135  	return x + (render ? w : 0);
    136  }
    137  
    138 +void
    139 +drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic)
    140 +{
    141 +	if (!drw)
    142 +		return;
    143 +	XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture, 0, 0, 0, 0, x, y, w, h);
    144 +}
    145 +
    146  void
    147  drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
    148  {
    149 diff --git a/drw.h b/drw.h
    150 index 4bcd5ad..71aefa2 100644
    151 --- a/drw.h
    152 +++ b/drw.h
    153 @@ -21,6 +21,7 @@ typedef struct {
    154  	int screen;
    155  	Window root;
    156  	Drawable drawable;
    157 +	Picture picture;
    158  	GC gc;
    159  	Clr *scheme;
    160  	Fnt *fonts;
    161 @@ -49,9 +50,12 @@ void drw_cur_free(Drw *drw, Cur *cursor);
    162  void drw_setfontset(Drw *drw, Fnt *set);
    163  void drw_setscheme(Drw *drw, Clr *scm);
    164  
    165 +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);
    166 +
    167  /* Drawing functions */
    168  void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
    169  int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
    170 +void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic);
    171  
    172  /* Map functions */
    173  void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
    174 diff --git a/dwm.c b/dwm.c
    175 index a96f33c..033ccec 100644
    176 --- a/dwm.c
    177 +++ b/dwm.c
    178 @@ -28,6 +28,8 @@
    179  #include <stdlib.h>
    180  #include <string.h>
    181  #include <unistd.h>
    182 +#include <limits.h>
    183 +#include <stdint.h>
    184  #include <sys/types.h>
    185  #include <sys/wait.h>
    186  #include <X11/cursorfont.h>
    187 @@ -60,7 +62,7 @@
    188  /* enums */
    189  enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
    190  enum { SchemeNorm, SchemeSel }; /* color schemes */
    191 -enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
    192 +enum { NetSupported, NetWMName, NetWMIcon, NetWMState, NetWMCheck,
    193         NetWMFullscreen, NetActiveWindow, NetWMWindowType,
    194         NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
    195  enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
    196 @@ -93,6 +95,7 @@ struct Client {
    197  	int bw, oldbw;
    198  	unsigned int tags;
    199  	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
    200 +	unsigned int icw, ich; Picture icon;
    201  	Client *next;
    202  	Client *snext;
    203  	Monitor *mon;
    204 @@ -170,6 +173,7 @@ static void focusin(XEvent *e);
    205  static void focusmon(const Arg *arg);
    206  static void focusstack(const Arg *arg);
    207  static Atom getatomprop(Client *c, Atom prop);
    208 +static Picture geticonprop(Window w, unsigned int *icw, unsigned int *ich);
    209  static int getrootptr(int *x, int *y);
    210  static long getstate(Window w);
    211  static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
    212 @@ -214,6 +218,7 @@ static void togglebar(const Arg *arg);
    213  static void togglefloating(const Arg *arg);
    214  static void toggletag(const Arg *arg);
    215  static void toggleview(const Arg *arg);
    216 +static void freeicon(Client *c);
    217  static void unfocus(Client *c, int setfocus);
    218  static void unmanage(Client *c, int destroyed);
    219  static void unmapnotify(XEvent *e);
    220 @@ -225,6 +230,7 @@ static void updatenumlockmask(void);
    221  static void updatesizehints(Client *c);
    222  static void updatestatus(void);
    223  static void updatetitle(Client *c);
    224 +static void updateicon(Client *c);
    225  static void updatewindowtype(Client *c);
    226  static void updatewmhints(Client *c);
    227  static void view(const Arg *arg);
    228 @@ -735,7 +741,8 @@ drawbar(Monitor *m)
    229  	if ((w = m->ww - tw - x) > bh) {
    230  		if (m->sel) {
    231  			drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
    232 -			drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
    233 +			drw_text(drw, x, 0, w, bh, lrpad / 2 + (m->sel->icon ? m->sel->icw + ICONSPACING : 0), m->sel->name, 0);
    234 +			if (m->sel->icon) drw_pic(drw, x + lrpad / 2, (bh - m->sel->ich) / 2, m->sel->icw, m->sel->ich, m->sel->icon);
    235  			if (m->sel->isfloating)
    236  				drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
    237  		} else {
    238 @@ -875,6 +882,67 @@ getatomprop(Client *c, Atom prop)
    239  	return atom;
    240  }
    241  
    242 +static uint32_t prealpha(uint32_t p) {
    243 +	uint8_t a = p >> 24u;
    244 +	uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u;
    245 +	uint32_t g = (a * (p & 0x00FF00u)) >> 8u;
    246 +	return (rb & 0xFF00FFu) | (g & 0x00FF00u) | (a << 24u);
    247 +}
    248 +
    249 +Picture
    250 +geticonprop(Window win, unsigned int *picw, unsigned int *pich)
    251 +{
    252 +	int format;
    253 +	unsigned long n, extra, *p = NULL;
    254 +	Atom real;
    255 +
    256 +	if (XGetWindowProperty(dpy, win, netatom[NetWMIcon], 0L, LONG_MAX, False, AnyPropertyType, 
    257 +						   &real, &format, &n, &extra, (unsigned char **)&p) != Success)
    258 +		return None; 
    259 +	if (n == 0 || format != 32) { XFree(p); return None; }
    260 +
    261 +	unsigned long *bstp = NULL;
    262 +	uint32_t w, h, sz;
    263 +	{
    264 +		unsigned long *i; const unsigned long *end = p + n;
    265 +		uint32_t bstd = UINT32_MAX, d, m;
    266 +		for (i = p; i < end - 1; i += sz) {
    267 +			if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
    268 +			if ((sz = w * h) > end - i) break;
    269 +			if ((m = w > h ? w : h) >= ICONSIZE && (d = m - ICONSIZE) < bstd) { bstd = d; bstp = i; }
    270 +		}
    271 +		if (!bstp) {
    272 +			for (i = p; i < end - 1; i += sz) {
    273 +				if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
    274 +				if ((sz = w * h) > end - i) break;
    275 +				if ((d = ICONSIZE - (w > h ? w : h)) < bstd) { bstd = d; bstp = i; }
    276 +			}
    277 +		}
    278 +		if (!bstp) { XFree(p); return None; }
    279 +	}
    280 +
    281 +	if ((w = *(bstp - 2)) == 0 || (h = *(bstp - 1)) == 0) { XFree(p); return None; }
    282 +
    283 +	uint32_t icw, ich;
    284 +	if (w <= h) {
    285 +		ich = ICONSIZE; icw = w * ICONSIZE / h;
    286 +		if (icw == 0) icw = 1;
    287 +	}
    288 +	else {
    289 +		icw = ICONSIZE; ich = h * ICONSIZE / w;
    290 +		if (ich == 0) ich = 1;
    291 +	}
    292 +	*picw = icw; *pich = ich;
    293 +
    294 +	uint32_t i, *bstp32 = (uint32_t *)bstp;
    295 +	for (sz = w * h, i = 0; i < sz; ++i) bstp32[i] = prealpha(bstp[i]);
    296 +
    297 +	Picture ret = drw_picture_create_resized(drw, (char *)bstp, w, h, icw, ich);
    298 +	XFree(p);
    299 +
    300 +	return ret;
    301 +}
    302 +
    303  int
    304  getrootptr(int *x, int *y)
    305  {
    306 @@ -1034,6 +1102,7 @@ manage(Window w, XWindowAttributes *wa)
    307  	c->h = c->oldh = wa->height;
    308  	c->oldbw = wa->border_width;
    309  
    310 +	updateicon(c);
    311  	updatetitle(c);
    312  	if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
    313  		c->mon = t->mon;
    314 @@ -1244,6 +1313,11 @@ propertynotify(XEvent *e)
    315  			if (c == c->mon->sel)
    316  				drawbar(c->mon);
    317  		}
    318 +		else if (ev->atom == netatom[NetWMIcon]) {
    319 +			updateicon(c);
    320 +			if (c == c->mon->sel)
    321 +				drawbar(c->mon);
    322 +		}
    323  		if (ev->atom == netatom[NetWMWindowType])
    324  			updatewindowtype(c);
    325  	}
    326 @@ -1560,6 +1634,7 @@ setup(void)
    327  	netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
    328  	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
    329  	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
    330 +	netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False);
    331  	netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
    332  	netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
    333  	netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
    334 @@ -1752,6 +1827,15 @@ toggleview(const Arg *arg)
    335  	}
    336  }
    337  
    338 +void
    339 +freeicon(Client *c)
    340 +{
    341 +	if (c->icon) {
    342 +		XRenderFreePicture(dpy, c->icon);
    343 +		c->icon = None;
    344 +	}
    345 +}
    346 +
    347  void
    348  unfocus(Client *c, int setfocus)
    349  {
    350 @@ -1773,6 +1857,7 @@ unmanage(Client *c, int destroyed)
    351  
    352  	detach(c);
    353  	detachstack(c);
    354 +	freeicon(c);
    355  	if (!destroyed) {
    356  		wc.border_width = c->oldbw;
    357  		XGrabServer(dpy); /* avoid race conditions */
    358 @@ -2007,6 +2092,13 @@ updatetitle(Client *c)
    359  		strcpy(c->name, broken);
    360  }
    361  
    362 +void
    363 +updateicon(Client *c)
    364 +{
    365 +	freeicon(c);
    366 +	c->icon = geticonprop(c->win, &c->icw, &c->ich);
    367 +}
    368 +
    369  void
    370  updatewindowtype(Client *c)
    371  {