dwm-winicon-6.3-v2.1.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) 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 {