dwm-winicon-6.3-v2.1.diff - 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; /* borde… | |
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 -lIm… | |
24 | |
25 # flags | |
26 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -D… | |
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, unsi… | |
40 drw->w = w; | |
41 drw->h = h; | |
42 drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy… | |
43 + drw->picture = XRenderCreatePicture(dpy, drw->drawable, XRender… | |
44 drw->gc = XCreateGC(dpy, root, 0, NULL); | |
45 XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMit… | |
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, Defaul… | |
56 + drw->picture = XRenderCreatePicture(drw->dpy, drw->drawable, XR… | |
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, unsi… | |
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),… | |
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, src… | |
88 + XFreeGC(drw->dpy, gc); | |
89 + | |
90 + pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindSta… | |
91 + XFreePixmap(drw->dpy, pm); | |
92 + | |
93 + XRenderSetPictureFilter(drw->dpy, pic, FilterBilinear, … | |
94 + XTransform xf; | |
95 + xf.matrix[0][0] = (srcw << 16u) / dstw; xf.matrix[0][1]… | |
96 + xf.matrix[1][0] = 0; xf.matrix[1][1] = (srch << 16u) / … | |
97 + xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][… | |
98 + XRenderSetPictureTransform(drw->dpy, pic, &xf); | |
99 + } else { | |
100 + Imlib_Image origin = imlib_create_image_using_data(srcw… | |
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(… | |
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_dat… | |
112 + ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), Bit… | |
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, dst… | |
121 + imlib_free_image_and_decache(); | |
122 + XFreeGC(drw->dpy, gc); | |
123 + | |
124 + pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindSta… | |
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 fi… | |
133 { | |
134 @@ -379,6 +446,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, un… | |
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… | |
140 +{ | |
141 + if (!drw) | |
142 + return; | |
143 + XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture,… | |
144 +} | |
145 + | |
146 void | |
147 drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned in… | |
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 sr… | |
166 + | |
167 /* Drawing functions */ | |
168 void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, i… | |
169 int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, un… | |
170 +void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Pi… | |
171 | |
172 /* Map functions */ | |
173 void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsign… | |
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 }; /* defaul… | |
196 @@ -93,6 +95,7 @@ struct Client { | |
197 int bw, oldbw; | |
198 unsigned int tags; | |
199 int isfixed, isfloating, isurgent, neverfocus, oldstate, isfull… | |
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 *i… | |
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 si… | |
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 ? SchemeS… | |
232 - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->n… | |
233 + drw_text(drw, x, 0, w, bh, lrpad / 2 + (m->sel-… | |
234 + if (m->sel->icon) drw_pic(drw, x + lrpad / 2, (… | |
235 if (m->sel->isfloating) | |
236 drw_rect(drw, x + boxs, boxs, boxw, box… | |
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_M… | |
257 + &real, &format, &n, … | |
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)… | |
268 + if ((sz = w * h) > end - i) break; | |
269 + if ((m = w > h ? w : h) >= ICONSIZE && (d = m -… | |
270 + } | |
271 + if (!bstp) { | |
272 + for (i = p; i < end - 1; i += sz) { | |
273 + if ((w = *i++) >= 16384 || (h = *i++) >… | |
274 + if ((sz = w * h) > end - i) break; | |
275 + if ((d = ICONSIZE - (w > h ? w : h)) < … | |
276 + } | |
277 + } | |
278 + if (!bstp) { XFree(p); return None; } | |
279 + } | |
280 + | |
281 + if ((w = *(bstp - 2)) == 0 || (h = *(bstp - 1)) == 0) { XFree(p… | |
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[… | |
296 + | |
297 + Picture ret = drw_picture_create_resized(drw, (char *)bstp, w, … | |
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(tr… | |
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… | |
328 netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", Fals… | |
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_CHEC… | |
333 netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULL… | |
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 { |