Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-systray-6.0.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-systray-6.0.diff (19982B)
---
1 Author: Jan Christoph Ebersbach <[email protected]>, inspired by http://code.…
2 URL: http://dwm.suckless.org/patches/systray
3 Implements a system tray for dwm.
4
5 diff -r ec4baab78314 config.def.h
6 --- a/config.def.h Mon Dec 19 15:38:30 2011 +0100
7 +++ b/config.def.h Fri Apr 06 08:25:40 2012 +0200
8 @@ -10,6 +10,8 @@
9 static const char selfgcolor[] = "#eeeeee";
10 static const unsigned int borderpx = 1; /* border pixel of wind…
11 static const unsigned int snap = 32; /* snap pixel */
12 +static const unsigned int systrayspacing = 2; /* systray spacing */
13 +static const Bool showsystray = True; /* False means no systr…
14 static const Bool showbar = True; /* False means no bar */
15 static const Bool topbar = True; /* False means bottom b…
16
17 diff -r ec4baab78314 dwm.c
18 --- a/dwm.c Mon Dec 19 15:38:30 2011 +0100
19 +++ b/dwm.c Fri Apr 06 08:25:40 2012 +0200
20 @@ -55,12 +55,30 @@
21 #define TAGMASK ((1 << LENGTH(tags)) - 1)
22 #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height)
23
24 +#define SYSTEM_TRAY_REQUEST_DOCK 0
25 +#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
26 +
27 +/* XEMBED messages */
28 +#define XEMBED_EMBEDDED_NOTIFY 0
29 +#define XEMBED_WINDOW_ACTIVATE 1
30 +#define XEMBED_FOCUS_IN 4
31 +#define XEMBED_MODALITY_ON 10
32 +
33 +#define XEMBED_MAPPED (1 << 0)
34 +#define XEMBED_WINDOW_ACTIVATE 1
35 +#define XEMBED_WINDOW_DEACTIVATE 2
36 +
37 +#define VERSION_MAJOR 0
38 +#define VERSION_MINOR 0
39 +#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
40 +
41 /* enums */
42 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
43 enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
44 -enum { NetSupported, NetWMName, NetWMState,
45 - NetWMFullscreen, NetActiveWindow, NetWMWindowType,
46 - NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */
47 +enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrien…
48 + NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, Net…
49 + NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */
50 +enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
51 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* defaul…
52 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
53 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
54 @@ -154,6 +172,12 @@
55 int monitor;
56 } Rule;
57
58 +typedef struct Systray Systray;
59 +struct Systray {
60 + Window win;
61 + Client *icons;
62 +};
63 +
64 /* function declarations */
65 static void applyrules(Client *c);
66 static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, B…
67 @@ -186,9 +210,11 @@
68 static void focusin(XEvent *e);
69 static void focusmon(const Arg *arg);
70 static void focusstack(const Arg *arg);
71 +static Atom getatomprop(Client *c, Atom prop);
72 static unsigned long getcolor(const char *colstr);
73 static Bool getrootptr(int *x, int *y);
74 static long getstate(Window w);
75 +static unsigned int getsystraywidth();
76 static Bool gettextprop(Window w, Atom atom, char *text, unsigned int s…
77 static void grabbuttons(Client *c, Bool focused);
78 static void grabkeys(void);
79 @@ -207,13 +233,16 @@
80 static void propertynotify(XEvent *e);
81 static void quit(const Arg *arg);
82 static Monitor *recttomon(int x, int y, int w, int h);
83 +static void removesystrayicon(Client *i);
84 static void resize(Client *c, int x, int y, int w, int h, Bool interact…
85 +static void resizebarwin(Monitor *m);
86 static void resizeclient(Client *c, int x, int y, int w, int h);
87 static void resizemouse(const Arg *arg);
88 +static void resizerequest(XEvent *e);
89 static void restack(Monitor *m);
90 static void run(void);
91 static void scan(void);
92 -static Bool sendevent(Client *c, Atom proto);
93 +static Bool sendevent(Window w, Atom proto, int m, long d0, long d1, lo…
94 static void sendmon(Client *c, Monitor *m);
95 static void setclientstate(Client *c, long state);
96 static void setfocus(Client *c);
97 @@ -241,18 +270,24 @@
98 static void updatenumlockmask(void);
99 static void updatesizehints(Client *c);
100 static void updatestatus(void);
101 +static void updatesystray(void);
102 +static void updatesystrayicongeom(Client *i, int w, int h);
103 +static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
104 static void updatewindowtype(Client *c);
105 static void updatetitle(Client *c);
106 static void updatewmhints(Client *c);
107 static void view(const Arg *arg);
108 static Client *wintoclient(Window w);
109 static Monitor *wintomon(Window w);
110 +static Client *wintosystrayicon(Window w);
111 static int xerror(Display *dpy, XErrorEvent *ee);
112 static int xerrordummy(Display *dpy, XErrorEvent *ee);
113 static int xerrorstart(Display *dpy, XErrorEvent *ee);
114 static void zoom(const Arg *arg);
115
116 /* variables */
117 +static Systray *systray = NULL;
118 +static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_…
119 static const char broken[] = "broken";
120 static char stext[256];
121 static int screen;
122 @@ -274,9 +309,10 @@
123 [MapRequest] = maprequest,
124 [MotionNotify] = motionnotify,
125 [PropertyNotify] = propertynotify,
126 + [ResizeRequest] = resizerequest,
127 [UnmapNotify] = unmapnotify
128 };
129 -static Atom wmatom[WMLast], netatom[NetLast];
130 +static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
131 static Bool running = True;
132 static Cursor cursor[CurLast];
133 static Display *dpy;
134 @@ -497,6 +533,11 @@
135 XFreeCursor(dpy, cursor[CurMove]);
136 while(mons)
137 cleanupmon(mons);
138 + if(showsystray) {
139 + XUnmapWindow(dpy, systray->win);
140 + XDestroyWindow(dpy, systray->win);
141 + free(systray);
142 + }
143 XSync(dpy, False);
144 XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTi…
145 }
146 @@ -530,9 +572,49 @@
147
148 void
149 clientmessage(XEvent *e) {
150 + XWindowAttributes wa;
151 + XSetWindowAttributes swa;
152 XClientMessageEvent *cme = &e->xclient;
153 Client *c = wintoclient(cme->window);
154
155 + if(showsystray && cme->window == systray->win && cme->message_t…
156 + /* add systray icons */
157 + if(cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
158 + if(!(c = (Client *)calloc(1, sizeof(Client))))
159 + die("fatal: could not malloc() %u bytes…
160 + c->win = cme->data.l[2];
161 + c->mon = selmon;
162 + c->next = systray->icons;
163 + systray->icons = c;
164 + XGetWindowAttributes(dpy, c->win, &wa);
165 + c->x = c->oldx = c->y = c->oldy = 0;
166 + c->w = c->oldw = wa.width;
167 + c->h = c->oldh = wa.height;
168 + c->oldbw = wa.border_width;
169 + c->bw = 0;
170 + c->isfloating = True;
171 + /* reuse tags field as mapped status */
172 + c->tags = 1;
173 + updatesizehints(c);
174 + updatesystrayicongeom(c, wa.width, wa.height);
175 + XAddToSaveSet(dpy, c->win);
176 + XSelectInput(dpy, c->win, StructureNotifyMask |…
177 + XReparentWindow(dpy, c->win, systray->win, 0, 0…
178 + /* use parents background pixmap */
179 + swa.background_pixmap = ParentRelative;
180 + swa.background_pixel = dc.norm[ColBG];
181 + XChangeWindowAttributes(dpy, c->win, CWBackPixm…
182 + sendevent(c->win, netatom[Xembed], StructureNot…
183 + /* FIXME not sure if I have to send these event…
184 + sendevent(c->win, netatom[Xembed], StructureNot…
185 + sendevent(c->win, netatom[Xembed], StructureNot…
186 + sendevent(c->win, netatom[Xembed], StructureNot…
187 + resizebarwin(selmon);
188 + updatesystray();
189 + setclientstate(c, NormalState);
190 + }
191 + return;
192 + }
193 if(!c)
194 return;
195 if(cme->message_type == netatom[NetWMState]) {
196 @@ -583,7 +663,7 @@
197 dc.drawable = XCreatePixmap(dpy, root, sw, bh, …
198 updatebars();
199 for(m = mons; m; m = m->next)
200 - XMoveResizeWindow(dpy, m->barwin, m->wx…
201 + resizebarwin(m);
202 focus(NULL);
203 arrange(NULL);
204 }
205 @@ -667,6 +747,11 @@
206
207 if((c = wintoclient(ev->window)))
208 unmanage(c, True);
209 + else if((c = wintosystrayicon(ev->window))) {
210 + removesystrayicon(c);
211 + resizebarwin(selmon);
212 + updatesystray();
213 + }
214 }
215
216 void
217 @@ -722,6 +807,7 @@
218 unsigned long *col;
219 Client *c;
220
221 + resizebarwin(m);
222 for(c = m->clients; c; c = c->next) {
223 occ |= c->tags;
224 if(c->isurgent)
225 @@ -743,6 +829,9 @@
226 if(m == selmon) { /* status is only drawn on selected monitor */
227 dc.w = TEXTW(stext);
228 dc.x = m->ww - dc.w;
229 + if(showsystray && m == selmon) {
230 + dc.x -= getsystraywidth();
231 + }
232 if(dc.x < x) {
233 dc.x = x;
234 dc.w = m->ww - x;
235 @@ -771,6 +860,7 @@
236
237 for(m = mons; m; m = m->next)
238 drawbar(m);
239 + updatesystray();
240 }
241
242 void
243 @@ -917,10 +1007,17 @@
244 unsigned long dl;
245 unsigned char *p = NULL;
246 Atom da, atom = None;
247 + /* FIXME getatomprop should return the number of items and a po…
248 + * the stored data instead of this workaround */
249 + Atom req = XA_ATOM;
250 + if(prop == xatom[XembedInfo])
251 + req = xatom[XembedInfo];
252
253 - if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False…
254 + if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False…
255 &da, &di, &dl, &dl, &p) == Success && p) {
256 atom = *(Atom *)p;
257 + if(da == xatom[XembedInfo] && dl == 2)
258 + atom = ((Atom *)p)[1];
259 XFree(p);
260 }
261 return atom;
262 @@ -962,6 +1059,15 @@
263 return result;
264 }
265
266 +unsigned int
267 +getsystraywidth() {
268 + unsigned int w = 0;
269 + Client *i;
270 + if(showsystray)
271 + for(i = systray->icons; i; w += i->w + systrayspacing, …
272 + return w ? w + systrayspacing : 1;
273 +}
274 +
275 Bool
276 gettextprop(Window w, Atom atom, char *text, unsigned int size) {
277 char **list = NULL;
278 @@ -1096,7 +1202,7 @@
279 killclient(const Arg *arg) {
280 if(!selmon->sel)
281 return;
282 - if(!sendevent(selmon->sel, wmatom[WMDelete])) {
283 + if(!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, …
284 XGrabServer(dpy);
285 XSetErrorHandler(xerrordummy);
286 XSetCloseDownMode(dpy, DestroyAll);
287 @@ -1180,6 +1286,12 @@
288 maprequest(XEvent *e) {
289 static XWindowAttributes wa;
290 XMapRequestEvent *ev = &e->xmaprequest;
291 + Client *i;
292 + if((i = wintosystrayicon(ev->window))) {
293 + sendevent(i->win, netatom[Xembed], StructureNotifyMask,…
294 + resizebarwin(selmon);
295 + updatesystray();
296 + }
297
298 if(!XGetWindowAttributes(dpy, ev->window, &wa))
299 return;
300 @@ -1293,6 +1405,16 @@
301 Window trans;
302 XPropertyEvent *ev = &e->xproperty;
303
304 + if((c = wintosystrayicon(ev->window))) {
305 + if(ev->atom == XA_WM_NORMAL_HINTS) {
306 + updatesizehints(c);
307 + updatesystrayicongeom(c, c->w, c->h);
308 + }
309 + else
310 + updatesystrayiconstate(c, ev);
311 + resizebarwin(selmon);
312 + updatesystray();
313 + }
314 if((ev->window == root) && (ev->atom == XA_WM_NAME))
315 updatestatus();
316 else if(ev->state == PropertyDelete)
317 @@ -1342,12 +1464,33 @@
318 }
319
320 void
321 +removesystrayicon(Client *i) {
322 + Client **ii;
323 +
324 + if(!showsystray || !i)
325 + return;
326 + for(ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
327 + if(ii)
328 + *ii = i->next;
329 + free(i);
330 +}
331 +
332 +
333 +void
334 resize(Client *c, int x, int y, int w, int h, Bool interact) {
335 if(applysizehints(c, &x, &y, &w, &h, interact))
336 resizeclient(c, x, y, w, h);
337 }
338
339 void
340 +resizebarwin(Monitor *m) {
341 + unsigned int w = m->ww;
342 + if(showsystray && m == selmon)
343 + w -= getsystraywidth();
344 + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
345 +}
346 +
347 +void
348 resizeclient(Client *c, int x, int y, int w, int h) {
349 XWindowChanges wc;
350
351 @@ -1412,6 +1555,18 @@
352 }
353
354 void
355 +resizerequest(XEvent *e) {
356 + XResizeRequestEvent *ev = &e->xresizerequest;
357 + Client *i;
358 +
359 + if((i = wintosystrayicon(ev->window))) {
360 + updatesystrayicongeom(i, ev->width, ev->height);
361 + resizebarwin(selmon);
362 + updatesystray();
363 + }
364 +}
365 +
366 +void
367 restack(Monitor *m) {
368 Client *c;
369 XEvent ev;
370 @@ -1495,25 +1650,35 @@
371 }
372
373 Bool
374 -sendevent(Client *c, Atom proto) {
375 +sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, lo…
376 int n;
377 - Atom *protocols;
378 + Atom *protocols, mt;
379 Bool exists = False;
380 XEvent ev;
381
382 - if(XGetWMProtocols(dpy, c->win, &protocols, &n)) {
383 - while(!exists && n--)
384 - exists = protocols[n] == proto;
385 - XFree(protocols);
386 + if(proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
387 + mt = wmatom[WMProtocols];
388 + if(XGetWMProtocols(dpy, w, &protocols, &n)) {
389 + while(!exists && n--)
390 + exists = protocols[n] == proto;
391 + XFree(protocols);
392 + }
393 + }
394 + else {
395 + exists = True;
396 + mt = proto;
397 }
398 if(exists) {
399 ev.type = ClientMessage;
400 - ev.xclient.window = c->win;
401 - ev.xclient.message_type = wmatom[WMProtocols];
402 + ev.xclient.window = w;
403 + ev.xclient.message_type = mt;
404 ev.xclient.format = 32;
405 - ev.xclient.data.l[0] = proto;
406 - ev.xclient.data.l[1] = CurrentTime;
407 - XSendEvent(dpy, c->win, False, NoEventMask, &ev);
408 + ev.xclient.data.l[0] = d0;
409 + ev.xclient.data.l[1] = d1;
410 + ev.xclient.data.l[2] = d2;
411 + ev.xclient.data.l[3] = d3;
412 + ev.xclient.data.l[4] = d4;
413 + XSendEvent(dpy, w, False, mask, &ev);
414 }
415 return exists;
416 }
417 @@ -1522,7 +1687,7 @@
418 setfocus(Client *c) {
419 if(!c->neverfocus)
420 XSetInputFocus(dpy, c->win, RevertToPointerRoot, Curren…
421 - sendevent(c, wmatom[WMTakeFocus]);
422 + sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTa…
423 }
424
425 void
426 @@ -1602,11 +1767,17 @@
427 wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
428 netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW…
429 netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", Fals…
430 + netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0"…
431 + netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_O…
432 + netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYST…
433 netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
434 netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
435 netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULL…
436 netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYP…
437 netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WIND…
438 + xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
439 + xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
440 + xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
441 /* init cursors */
442 cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
443 cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
444 @@ -1623,6 +1794,8 @@
445 XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter…
446 if(!dc.font.set)
447 XSetFont(dpy, dc.gc, dc.font.xfont->fid);
448 + /* init system tray */
449 + updatesystray();
450 /* init bars */
451 updatebars();
452 updatestatus();
453 @@ -1731,7 +1904,18 @@
454 togglebar(const Arg *arg) {
455 selmon->showbar = !selmon->showbar;
456 updatebarpos(selmon);
457 - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, …
458 + resizebarwin(selmon);
459 + if(showsystray) {
460 + XWindowChanges wc;
461 + if(!selmon->showbar)
462 + wc.y = -bh;
463 + else if(selmon->showbar) {
464 + wc.y = 0;
465 + if(!selmon->topbar)
466 + wc.y = selmon->mh - bh;
467 + }
468 + XConfigureWindow(dpy, systray->win, CWY, &wc);
469 + }
470 arrange(selmon);
471 }
472
473 @@ -1816,18 +2000,28 @@
474 else
475 unmanage(c, False);
476 }
477 + else if((c = wintosystrayicon(ev->window))) {
478 + removesystrayicon(c);
479 + resizebarwin(selmon);
480 + updatesystray();
481 + }
482 }
483
484 void
485 updatebars(void) {
486 + unsigned int w;
487 Monitor *m;
488 +
489 XSetWindowAttributes wa = {
490 .override_redirect = True,
491 .background_pixmap = ParentRelative,
492 .event_mask = ButtonPressMask|ExposureMask
493 };
494 for(m = mons; m; m = m->next) {
495 - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->w…
496 + w = m->ww;
497 + if(showsystray && m == selmon)
498 + w -= getsystraywidth();
499 + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, b…
500 CopyFromParent, DefaultVisual…
501 CWOverrideRedirect|CWBackPixm…
502 XDefineCursor(dpy, m->barwin, cursor[CurNormal]);
503 @@ -2011,6 +2208,107 @@
504 }
505
506 void
507 +updatesystrayicongeom(Client *i, int w, int h) {
508 + if(i) {
509 + i->h = bh;
510 + if(w == h)
511 + i->w = bh;
512 + else if(h == bh)
513 + i->w = w;
514 + else
515 + i->w = (int) ((float)bh * ((float)w / (float)h)…
516 + applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), F…
517 + /* force icons into the systray dimenons if they don't …
518 + if(i->h > bh) {
519 + if(i->w == i->h)
520 + i->w = bh;
521 + else
522 + i->w = (int) ((float)bh * ((float)i->w …
523 + i->h = bh;
524 + }
525 + }
526 +}
527 +
528 +void
529 +updatesystrayiconstate(Client *i, XPropertyEvent *ev) {
530 + long flags;
531 + int code = 0;
532 +
533 + if(!showsystray || !i || ev->atom != xatom[XembedInfo] ||
534 + !(flags = getatomprop(i, xatom[XembedInfo])))
535 + return;
536 +
537 + if(flags & XEMBED_MAPPED && !i->tags) {
538 + i->tags = 1;
539 + code = XEMBED_WINDOW_ACTIVATE;
540 + XMapRaised(dpy, i->win);
541 + setclientstate(i, NormalState);
542 + }
543 + else if(!(flags & XEMBED_MAPPED) && i->tags) {
544 + i->tags = 0;
545 + code = XEMBED_WINDOW_DEACTIVATE;
546 + XUnmapWindow(dpy, i->win);
547 + setclientstate(i, WithdrawnState);
548 + }
549 + else
550 + return;
551 + sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTi…
552 + systray->win, XEMBED_EMBEDDED_VERSION);
553 +}
554 +
555 +void
556 +updatesystray(void) {
557 + XSetWindowAttributes wa;
558 + Client *i;
559 + unsigned int x = selmon->mx + selmon->mw;
560 + unsigned int w = 1;
561 +
562 + if(!showsystray)
563 + return;
564 + if(!systray) {
565 + /* init systray */
566 + if(!(systray = (Systray *)calloc(1, sizeof(Systray))))
567 + die("fatal: could not malloc() %u bytes\n", siz…
568 + systray->win = XCreateSimpleWindow(dpy, root, x, selmon…
569 + wa.event_mask = ButtonPressMask | ExposureMask;
570 + wa.override_redirect = True;
571 + wa.background_pixmap = ParentRelative;
572 + wa.background_pixel = dc.norm[ColBG];
573 + XSelectInput(dpy, systray->win, SubstructureNotifyMask);
574 + XChangeProperty(dpy, systray->win, netatom[NetSystemTra…
575 + PropModeReplace, (unsigned char *)&syst…
576 + XChangeWindowAttributes(dpy, systray->win, CWEventMask|…
577 + XMapRaised(dpy, systray->win);
578 + XSetSelectionOwner(dpy, netatom[NetSystemTray], systray…
579 + if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) == s…
580 + sendevent(root, xatom[Manager], StructureNotify…
581 + XSync(dpy, False);
582 + }
583 + else {
584 + fprintf(stderr, "dwm: unable to obtain system t…
585 + free(systray);
586 + systray = NULL;
587 + return;
588 + }
589 + }
590 + for(w = 0, i = systray->icons; i; i = i->next) {
591 + XMapRaised(dpy, i->win);
592 + w += systrayspacing;
593 + XMoveResizeWindow(dpy, i->win, (i->x = w), 0, i->w, i->…
594 + w += i->w;
595 + if(i->mon != selmon)
596 + i->mon = selmon;
597 + }
598 + w = w ? w + systrayspacing : 1;
599 + x -= w;
600 + XMoveResizeWindow(dpy, systray->win, x, selmon->by, w, bh);
601 + /* redraw background */
602 + XSetForeground(dpy, dc.gc, dc.norm[ColBG]);
603 + XFillRectangle(dpy, systray->win, dc.gc, 0, 0, w, bh);
604 + XSync(dpy, False);
605 +}
606 +
607 +void
608 updatewindowtype(Client *c) {
609 Atom state = getatomprop(c, netatom[NetWMState]);
610 Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
611 @@ -2080,6 +2372,16 @@
612 return selmon;
613 }
614
615 +Client *
616 +wintosystrayicon(Window w) {
617 + Client *i = NULL;
618 +
619 + if(!showsystray || !w)
620 + return i;
621 + for(i = systray->icons; i && i->win != w; i = i->next) ;
622 + return i;
623 +}
624 +
625 /* There's no way to check accesses to destroyed windows, thus those ca…
626 * ignored (especially on UnmapNotify's). Other types of errors call X…
627 * default error handler, which may call exit. */
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.