Introduction
Introduction Statistics Contact Development Disclaimer Help
01-dwm-systray-6.4.diff - dotfiles - These are my dotfiles. There are many like…
git clone git://jay.scot/dotfiles
Log
Files
Refs
README
---
01-dwm-systray-6.4.diff (24467B)
---
1 diff --git a/config.def.h b/config.def.h
2 index 9efa774..750529d 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -3,6 +3,11 @@
6 /* appearance */
7 static const unsigned int borderpx = 1; /* border pixel of wind…
8 static const unsigned int snap = 32; /* snap pixel */
9 +static const unsigned int systraypinning = 0; /* 0: sloppy systray fo…
10 +static const unsigned int systrayonleft = 0; /* 0: systray in the ri…
11 +static const unsigned int systrayspacing = 2; /* systray spacing */
12 +static const int systraypinningfailfirst = 1; /* 1: if pinning fails,…
13 +static const int showsystray = 1; /* 0 means no systray */
14 static const int showbar = 1; /* 0 means no bar */
15 static const int topbar = 1; /* 0 means bottom bar */
16 static const char *fonts[] = { "monospace:size=10" };
17 @@ -101,8 +106,8 @@ static const Key keys[] = {
18 /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, Clk…
19 static const Button buttons[] = {
20 /* click event mask button functio…
21 - { ClkLtSymbol, 0, Button1, setlayo…
22 - { ClkLtSymbol, 0, Button3, setlayo…
23 + { ClkTagBar, MODKEY, Button1, tag, …
24 + { ClkTagBar, MODKEY, Button3, togglet…
25 { ClkWinTitle, 0, Button2, zoom, …
26 { ClkStatusText, 0, Button2, spawn, …
27 { ClkClientWin, MODKEY, Button1, movemou…
28 diff --git a/dwm.c b/dwm.c
29 index 03baf42..4611a03 100644
30 --- a/dwm.c
31 +++ b/dwm.c
32 @@ -57,12 +57,27 @@
33 #define TAGMASK ((1 << LENGTH(tags)) - 1)
34 #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
35
36 +#define SYSTEM_TRAY_REQUEST_DOCK 0
37 +/* XEMBED messages */
38 +#define XEMBED_EMBEDDED_NOTIFY 0
39 +#define XEMBED_WINDOW_ACTIVATE 1
40 +#define XEMBED_FOCUS_IN 4
41 +#define XEMBED_MODALITY_ON 10
42 +#define XEMBED_MAPPED (1 << 0)
43 +#define XEMBED_WINDOW_ACTIVATE 1
44 +#define XEMBED_WINDOW_DEACTIVATE 2
45 +#define VERSION_MAJOR 0
46 +#define VERSION_MINOR 0
47 +#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
48 +
49 /* enums */
50 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
51 enum { SchemeNorm, SchemeSel }; /* color schemes */
52 enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
53 + NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSys…
54 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
55 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
56 +enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
57 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* defaul…
58 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
59 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
60 @@ -141,6 +156,12 @@ typedef struct {
61 int monitor;
62 } Rule;
63
64 +typedef struct Systray Systray;
65 +struct Systray {
66 + Window win;
67 + Client *icons;
68 +};
69 +
70 /* function declarations */
71 static void applyrules(Client *c);
72 static int applysizehints(Client *c, int *x, int *y, int *w, int *h, in…
73 @@ -172,6 +193,7 @@ static void focusstack(const Arg *arg);
74 static Atom getatomprop(Client *c, Atom prop);
75 static int getrootptr(int *x, int *y);
76 static long getstate(Window w);
77 +static unsigned int getsystraywidth();
78 static int gettextprop(Window w, Atom atom, char *text, unsigned int si…
79 static void grabbuttons(Client *c, int focused);
80 static void grabkeys(void);
81 @@ -189,13 +211,16 @@ static void pop(Client *c);
82 static void propertynotify(XEvent *e);
83 static void quit(const Arg *arg);
84 static Monitor *recttomon(int x, int y, int w, int h);
85 +static void removesystrayicon(Client *i);
86 static void resize(Client *c, int x, int y, int w, int h, int interact);
87 +static void resizebarwin(Monitor *m);
88 static void resizeclient(Client *c, int x, int y, int w, int h);
89 static void resizemouse(const Arg *arg);
90 +static void resizerequest(XEvent *e);
91 static void restack(Monitor *m);
92 static void run(void);
93 static void scan(void);
94 -static int sendevent(Client *c, Atom proto);
95 +static int sendevent(Window w, Atom proto, int m, long d0, long d1, lon…
96 static void sendmon(Client *c, Monitor *m);
97 static void setclientstate(Client *c, long state);
98 static void setfocus(Client *c);
99 @@ -207,6 +232,7 @@ static void seturgent(Client *c, int urg);
100 static void showhide(Client *c);
101 static void sigchld(int unused);
102 static void spawn(const Arg *arg);
103 +static Monitor *systraytomon(Monitor *m);
104 static void tag(const Arg *arg);
105 static void tagmon(const Arg *arg);
106 static void tile(Monitor *m);
107 @@ -224,18 +250,23 @@ static int updategeom(void);
108 static void updatenumlockmask(void);
109 static void updatesizehints(Client *c);
110 static void updatestatus(void);
111 +static void updatesystray(void);
112 +static void updatesystrayicongeom(Client *i, int w, int h);
113 +static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
114 static void updatetitle(Client *c);
115 static void updatewindowtype(Client *c);
116 static void updatewmhints(Client *c);
117 static void view(const Arg *arg);
118 static Client *wintoclient(Window w);
119 static Monitor *wintomon(Window w);
120 +static Client *wintosystrayicon(Window w);
121 static int xerror(Display *dpy, XErrorEvent *ee);
122 static int xerrordummy(Display *dpy, XErrorEvent *ee);
123 static int xerrorstart(Display *dpy, XErrorEvent *ee);
124 static void zoom(const Arg *arg);
125
126 /* variables */
127 +static Systray *systray = NULL;
128 static const char broken[] = "broken";
129 static char stext[256];
130 static int screen;
131 @@ -258,9 +289,10 @@ static void (*handler[LASTEvent]) (XEvent *) = {
132 [MapRequest] = maprequest,
133 [MotionNotify] = motionnotify,
134 [PropertyNotify] = propertynotify,
135 + [ResizeRequest] = resizerequest,
136 [UnmapNotify] = unmapnotify
137 };
138 -static Atom wmatom[WMLast], netatom[NetLast];
139 +static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
140 static int running = 1;
141 static Cur *cursor[CurLast];
142 static Clr **scheme;
143 @@ -442,7 +474,7 @@ buttonpress(XEvent *e)
144 arg.ui = 1 << i;
145 } else if (ev->x < x + TEXTW(selmon->ltsymbol))
146 click = ClkLtSymbol;
147 - else if (ev->x > selmon->ww - (int)TEXTW(stext))
148 + else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsy…
149 click = ClkStatusText;
150 else
151 click = ClkWinTitle;
152 @@ -485,6 +517,13 @@ cleanup(void)
153 XUngrabKey(dpy, AnyKey, AnyModifier, root);
154 while (mons)
155 cleanupmon(mons);
156 +
157 + if (showsystray) {
158 + XUnmapWindow(dpy, systray->win);
159 + XDestroyWindow(dpy, systray->win);
160 + free(systray);
161 + }
162 +
163 for (i = 0; i < CurLast; i++)
164 drw_cur_free(drw, cursor[i]);
165 for (i = 0; i < LENGTH(colors); i++)
166 @@ -516,9 +555,58 @@ cleanupmon(Monitor *mon)
167 void
168 clientmessage(XEvent *e)
169 {
170 + XWindowAttributes wa;
171 + XSetWindowAttributes swa;
172 XClientMessageEvent *cme = &e->xclient;
173 Client *c = wintoclient(cme->window);
174
175 + if (showsystray && cme->window == systray->win && cme->message_…
176 + /* add systray icons */
177 + if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
178 + if (!(c = (Client *)calloc(1, sizeof(Client))))
179 + die("fatal: could not malloc() %u bytes…
180 + if (!(c->win = cme->data.l[2])) {
181 + free(c);
182 + return;
183 + }
184 + c->mon = selmon;
185 + c->next = systray->icons;
186 + systray->icons = c;
187 + if (!XGetWindowAttributes(dpy, c->win, &wa)) {
188 + /* use sane defaults */
189 + wa.width = bh;
190 + wa.height = bh;
191 + wa.border_width = 0;
192 + }
193 + c->x = c->oldx = c->y = c->oldy = 0;
194 + c->w = c->oldw = wa.width;
195 + c->h = c->oldh = wa.height;
196 + c->oldbw = wa.border_width;
197 + c->bw = 0;
198 + c->isfloating = True;
199 + /* reuse tags field as mapped status */
200 + c->tags = 1;
201 + updatesizehints(c);
202 + updatesystrayicongeom(c, wa.width, wa.height);
203 + XAddToSaveSet(dpy, c->win);
204 + XSelectInput(dpy, c->win, StructureNotifyMask |…
205 + XReparentWindow(dpy, c->win, systray->win, 0, 0…
206 + /* use parents background color */
207 + swa.background_pixel = scheme[SchemeNorm][ColB…
208 + XChangeWindowAttributes(dpy, c->win, CWBackPixe…
209 + sendevent(c->win, netatom[Xembed], StructureNot…
210 + /* FIXME not sure if I have to send these event…
211 + sendevent(c->win, netatom[Xembed], StructureNot…
212 + sendevent(c->win, netatom[Xembed], StructureNot…
213 + sendevent(c->win, netatom[Xembed], StructureNot…
214 + XSync(dpy, False);
215 + resizebarwin(selmon);
216 + updatesystray();
217 + setclientstate(c, NormalState);
218 + }
219 + return;
220 + }
221 +
222 if (!c)
223 return;
224 if (cme->message_type == netatom[NetWMState]) {
225 @@ -571,7 +659,7 @@ configurenotify(XEvent *e)
226 for (c = m->clients; c; c = c->next)
227 if (c->isfullscreen)
228 resizeclient(c, m->mx, …
229 - XMoveResizeWindow(dpy, m->barwin, m->wx…
230 + resizebarwin(m);
231 }
232 focus(NULL);
233 arrange(NULL);
234 @@ -656,6 +744,11 @@ destroynotify(XEvent *e)
235
236 if ((c = wintoclient(ev->window)))
237 unmanage(c, 1);
238 + else if ((c = wintosystrayicon(ev->window))) {
239 + removesystrayicon(c);
240 + resizebarwin(selmon);
241 + updatesystray();
242 + }
243 }
244
245 void
246 @@ -699,7 +792,7 @@ dirtomon(int dir)
247 void
248 drawbar(Monitor *m)
249 {
250 - int x, w, tw = 0;
251 + int x, w, tw = 0, stw = 0;
252 int boxs = drw->fonts->h / 9;
253 int boxw = drw->fonts->h / 6 + 2;
254 unsigned int i, occ = 0, urg = 0;
255 @@ -708,13 +801,17 @@ drawbar(Monitor *m)
256 if (!m->showbar)
257 return;
258
259 + if(showsystray && m == systraytomon(m) && !systrayonleft)
260 + stw = getsystraywidth();
261 +
262 /* draw status first so it can be overdrawn by tags later */
263 if (m == selmon) { /* status is only drawn on selected monitor …
264 drw_setscheme(drw, scheme[SchemeNorm]);
265 - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
266 - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
267 + tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right p…
268 + drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - …
269 }
270
271 + resizebarwin(m);
272 for (c = m->clients; c; c = c->next) {
273 occ |= c->tags;
274 if (c->isurgent)
275 @@ -735,7 +832,7 @@ drawbar(Monitor *m)
276 drw_setscheme(drw, scheme[SchemeNorm]);
277 x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
278
279 - if ((w = m->ww - tw - x) > bh) {
280 + if ((w = m->ww - tw - stw - x) > bh) {
281 if (m->sel) {
282 drw_setscheme(drw, scheme[m == selmon ? SchemeS…
283 drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->n…
284 @@ -746,7 +843,7 @@ drawbar(Monitor *m)
285 drw_rect(drw, x, 0, w, bh, 1, 1);
286 }
287 }
288 - drw_map(drw, m->barwin, 0, 0, m->ww, bh);
289 + drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
290 }
291
292 void
293 @@ -783,8 +880,11 @@ expose(XEvent *e)
294 Monitor *m;
295 XExposeEvent *ev = &e->xexpose;
296
297 - if (ev->count == 0 && (m = wintomon(ev->window)))
298 + if (ev->count == 0 && (m = wintomon(ev->window))) {
299 drawbar(m);
300 + if (m == selmon)
301 + updatesystray();
302 + }
303 }
304
305 void
306 @@ -870,14 +970,32 @@ getatomprop(Client *c, Atom prop)
307 unsigned char *p = NULL;
308 Atom da, atom = None;
309
310 - if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, Fals…
311 + /* FIXME getatomprop should return the number of items and a po…
312 + * the stored data instead of this workaround */
313 + Atom req = XA_ATOM;
314 + if (prop == xatom[XembedInfo])
315 + req = xatom[XembedInfo];
316 +
317 + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, Fals…
318 &da, &di, &dl, &dl, &p) == Success && p) {
319 atom = *(Atom *)p;
320 + if (da == xatom[XembedInfo] && dl == 2)
321 + atom = ((Atom *)p)[1];
322 XFree(p);
323 }
324 return atom;
325 }
326
327 +unsigned int
328 +getsystraywidth()
329 +{
330 + unsigned int w = 0;
331 + Client *i;
332 + if(showsystray)
333 + for(i = systray->icons; i; w += i->w + systrayspacing, …
334 + return w ? w + systrayspacing : 1;
335 +}
336 +
337 int
338 getrootptr(int *x, int *y)
339 {
340 @@ -1018,7 +1136,8 @@ killclient(const Arg *arg)
341 {
342 if (!selmon->sel)
343 return;
344 - if (!sendevent(selmon->sel, wmatom[WMDelete])) {
345 +
346 + if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask,…
347 XGrabServer(dpy);
348 XSetErrorHandler(xerrordummy);
349 XSetCloseDownMode(dpy, DestroyAll);
350 @@ -1105,6 +1224,13 @@ maprequest(XEvent *e)
351 static XWindowAttributes wa;
352 XMapRequestEvent *ev = &e->xmaprequest;
353
354 + Client *i;
355 + if ((i = wintosystrayicon(ev->window))) {
356 + sendevent(i->win, netatom[Xembed], StructureNotifyMask,…
357 + resizebarwin(selmon);
358 + updatesystray();
359 + }
360 +
361 if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_…
362 return;
363 if (!wintoclient(ev->window))
364 @@ -1226,6 +1352,17 @@ propertynotify(XEvent *e)
365 Window trans;
366 XPropertyEvent *ev = &e->xproperty;
367
368 + if ((c = wintosystrayicon(ev->window))) {
369 + if (ev->atom == XA_WM_NORMAL_HINTS) {
370 + updatesizehints(c);
371 + updatesystrayicongeom(c, c->w, c->h);
372 + }
373 + else
374 + updatesystrayiconstate(c, ev);
375 + resizebarwin(selmon);
376 + updatesystray();
377 + }
378 +
379 if ((ev->window == root) && (ev->atom == XA_WM_NAME))
380 updatestatus();
381 else if (ev->state == PropertyDelete)
382 @@ -1276,6 +1413,19 @@ recttomon(int x, int y, int w, int h)
383 return r;
384 }
385
386 +void
387 +removesystrayicon(Client *i)
388 +{
389 + Client **ii;
390 +
391 + if (!showsystray || !i)
392 + return;
393 + for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
394 + if (ii)
395 + *ii = i->next;
396 + free(i);
397 +}
398 +
399 void
400 resize(Client *c, int x, int y, int w, int h, int interact)
401 {
402 @@ -1283,6 +1433,14 @@ resize(Client *c, int x, int y, int w, int h, int…
403 resizeclient(c, x, y, w, h);
404 }
405
406 +void
407 +resizebarwin(Monitor *m) {
408 + unsigned int w = m->ww;
409 + if (showsystray && m == systraytomon(m) && !systrayonleft)
410 + w -= getsystraywidth();
411 + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
412 +}
413 +
414 void
415 resizeclient(Client *c, int x, int y, int w, int h)
416 {
417 @@ -1298,6 +1456,19 @@ resizeclient(Client *c, int x, int y, int w, int …
418 XSync(dpy, False);
419 }
420
421 +void
422 +resizerequest(XEvent *e)
423 +{
424 + XResizeRequestEvent *ev = &e->xresizerequest;
425 + Client *i;
426 +
427 + if ((i = wintosystrayicon(ev->window))) {
428 + updatesystrayicongeom(i, ev->width, ev->height);
429 + resizebarwin(selmon);
430 + updatesystray();
431 + }
432 +}
433 +
434 void
435 resizemouse(const Arg *arg)
436 {
437 @@ -1444,26 +1615,37 @@ setclientstate(Client *c, long state)
438 }
439
440 int
441 -sendevent(Client *c, Atom proto)
442 +sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, lo…
443 {
444 int n;
445 - Atom *protocols;
446 + Atom *protocols, mt;
447 int exists = 0;
448 XEvent ev;
449
450 - if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
451 - while (!exists && n--)
452 - exists = protocols[n] == proto;
453 - XFree(protocols);
454 + if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
455 + mt = wmatom[WMProtocols];
456 + if (XGetWMProtocols(dpy, w, &protocols, &n)) {
457 + while (!exists && n--)
458 + exists = protocols[n] == proto;
459 + XFree(protocols);
460 + }
461 + }
462 + else {
463 + exists = True;
464 + mt = proto;
465 }
466 +
467 if (exists) {
468 ev.type = ClientMessage;
469 - ev.xclient.window = c->win;
470 - ev.xclient.message_type = wmatom[WMProtocols];
471 + ev.xclient.window = w;
472 + ev.xclient.message_type = mt;
473 ev.xclient.format = 32;
474 - ev.xclient.data.l[0] = proto;
475 - ev.xclient.data.l[1] = CurrentTime;
476 - XSendEvent(dpy, c->win, False, NoEventMask, &ev);
477 + ev.xclient.data.l[0] = d0;
478 + ev.xclient.data.l[1] = d1;
479 + ev.xclient.data.l[2] = d2;
480 + ev.xclient.data.l[3] = d3;
481 + ev.xclient.data.l[4] = d4;
482 + XSendEvent(dpy, w, False, mask, &ev);
483 }
484 return exists;
485 }
486 @@ -1477,7 +1659,7 @@ setfocus(Client *c)
487 XA_WINDOW, 32, PropModeReplace,
488 (unsigned char *) &(c->win), 1);
489 }
490 - sendevent(c, wmatom[WMTakeFocus]);
491 + sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTa…
492 }
493
494 void
495 @@ -1566,6 +1748,10 @@ setup(void)
496 wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
497 netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW…
498 netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", Fals…
499 + netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0"…
500 + netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_O…
501 + netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYST…
502 + netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_…
503 netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
504 netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
505 netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHEC…
506 @@ -1573,6 +1759,9 @@ setup(void)
507 netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYP…
508 netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WIND…
509 netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", F…
510 + xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
511 + xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
512 + xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
513 /* init cursors */
514 cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
515 cursor[CurResize] = drw_cur_create(drw, XC_sizing);
516 @@ -1581,6 +1770,8 @@ setup(void)
517 scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
518 for (i = 0; i < LENGTH(colors); i++)
519 scheme[i] = drw_scm_create(drw, colors[i], 3);
520 + /* init system tray */
521 + updatesystray();
522 /* init bars */
523 updatebars();
524 updatestatus();
525 @@ -1711,7 +1902,18 @@ togglebar(const Arg *arg)
526 {
527 selmon->showbar = !selmon->showbar;
528 updatebarpos(selmon);
529 - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, …
530 + resizebarwin(selmon);
531 + if (showsystray) {
532 + XWindowChanges wc;
533 + if (!selmon->showbar)
534 + wc.y = -bh;
535 + else if (selmon->showbar) {
536 + wc.y = 0;
537 + if (!selmon->topbar)
538 + wc.y = selmon->mh - bh;
539 + }
540 + XConfigureWindow(dpy, systray->win, CWY, &wc);
541 + }
542 arrange(selmon);
543 }
544
545 @@ -1807,11 +2009,18 @@ unmapnotify(XEvent *e)
546 else
547 unmanage(c, 0);
548 }
549 + else if ((c = wintosystrayicon(ev->window))) {
550 + /* KLUDGE! sometimes icons occasionally unmap their win…
551 + * _not_ destroy them. We map those windows back */
552 + XMapRaised(dpy, c->win);
553 + updatesystray();
554 + }
555 }
556
557 void
558 updatebars(void)
559 {
560 + unsigned int w;
561 Monitor *m;
562 XSetWindowAttributes wa = {
563 .override_redirect = True,
564 @@ -1822,10 +2031,15 @@ updatebars(void)
565 for (m = mons; m; m = m->next) {
566 if (m->barwin)
567 continue;
568 - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->w…
569 + w = m->ww;
570 + if (showsystray && m == systraytomon(m))
571 + w -= getsystraywidth();
572 + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, b…
573 CopyFromParent, DefaultVisual(dpy, scre…
574 CWOverrideRedirect|CWBackPixmap|CWEvent…
575 XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor…
576 + if (showsystray && m == systraytomon(m))
577 + XMapRaised(dpy, systray->win);
578 XMapRaised(dpy, m->barwin);
579 XSetClassHint(dpy, m->barwin, &ch);
580 }
581 @@ -2002,6 +2216,125 @@ updatestatus(void)
582 if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
583 strcpy(stext, "dwm-"VERSION);
584 drawbar(selmon);
585 + updatesystray();
586 +}
587 +
588 +
589 +void
590 +updatesystrayicongeom(Client *i, int w, int h)
591 +{
592 + if (i) {
593 + i->h = bh;
594 + if (w == h)
595 + i->w = bh;
596 + else if (h == bh)
597 + i->w = w;
598 + else
599 + i->w = (int) ((float)bh * ((float)w / (float)h)…
600 + applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), F…
601 + /* force icons into the systray dimensions if they don'…
602 + if (i->h > bh) {
603 + if (i->w == i->h)
604 + i->w = bh;
605 + else
606 + i->w = (int) ((float)bh * ((float)i->w …
607 + i->h = bh;
608 + }
609 + }
610 +}
611 +
612 +void
613 +updatesystrayiconstate(Client *i, XPropertyEvent *ev)
614 +{
615 + long flags;
616 + int code = 0;
617 +
618 + if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
619 + !(flags = getatomprop(i, xatom[XembedInfo])))
620 + return;
621 +
622 + if (flags & XEMBED_MAPPED && !i->tags) {
623 + i->tags = 1;
624 + code = XEMBED_WINDOW_ACTIVATE;
625 + XMapRaised(dpy, i->win);
626 + setclientstate(i, NormalState);
627 + }
628 + else if (!(flags & XEMBED_MAPPED) && i->tags) {
629 + i->tags = 0;
630 + code = XEMBED_WINDOW_DEACTIVATE;
631 + XUnmapWindow(dpy, i->win);
632 + setclientstate(i, WithdrawnState);
633 + }
634 + else
635 + return;
636 + sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTi…
637 + systray->win, XEMBED_EMBEDDED_VERSION);
638 +}
639 +
640 +void
641 +updatesystray(void)
642 +{
643 + XSetWindowAttributes wa;
644 + XWindowChanges wc;
645 + Client *i;
646 + Monitor *m = systraytomon(NULL);
647 + unsigned int x = m->mx + m->mw;
648 + unsigned int sw = TEXTW(stext) - lrpad + systrayspacing;
649 + unsigned int w = 1;
650 +
651 + if (!showsystray)
652 + return;
653 + if (systrayonleft)
654 + x -= sw + lrpad / 2;
655 + if (!systray) {
656 + /* init systray */
657 + if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
658 + die("fatal: could not malloc() %u bytes\n", siz…
659 + systray->win = XCreateSimpleWindow(dpy, root, x, m->by,…
660 + wa.event_mask = ButtonPressMask | ExposureMask;
661 + wa.override_redirect = True;
662 + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
663 + XSelectInput(dpy, systray->win, SubstructureNotifyMask);
664 + XChangeProperty(dpy, systray->win, netatom[NetSystemTra…
665 + PropModeReplace, (unsigned char *)&neta…
666 + XChangeWindowAttributes(dpy, systray->win, CWEventMask|…
667 + XMapRaised(dpy, systray->win);
668 + XSetSelectionOwner(dpy, netatom[NetSystemTray], systray…
669 + if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == …
670 + sendevent(root, xatom[Manager], StructureNotify…
671 + XSync(dpy, False);
672 + }
673 + else {
674 + fprintf(stderr, "dwm: unable to obtain system t…
675 + free(systray);
676 + systray = NULL;
677 + return;
678 + }
679 + }
680 + for (w = 0, i = systray->icons; i; i = i->next) {
681 + /* make sure the background color stays the same */
682 + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
683 + XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
684 + XMapRaised(dpy, i->win);
685 + w += systrayspacing;
686 + i->x = w;
687 + XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
688 + w += i->w;
689 + if (i->mon != m)
690 + i->mon = m;
691 + }
692 + w = w ? w + systrayspacing : 1;
693 + x -= w;
694 + XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
695 + wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
696 + wc.stack_mode = Above; wc.sibling = m->barwin;
697 + XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CW…
698 + XMapWindow(dpy, systray->win);
699 + XMapSubwindows(dpy, systray->win);
700 + /* redraw background */
701 + XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
702 + XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
703 + XSync(dpy, False);
704 }
705
706 void
707 @@ -2069,6 +2402,16 @@ wintoclient(Window w)
708 return NULL;
709 }
710
711 +Client *
712 +wintosystrayicon(Window w) {
713 + Client *i = NULL;
714 +
715 + if (!showsystray || !w)
716 + return i;
717 + for (i = systray->icons; i && i->win != w; i = i->next) ;
718 + return i;
719 +}
720 +
721 Monitor *
722 wintomon(Window w)
723 {
724 @@ -2122,6 +2465,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
725 return -1;
726 }
727
728 +Monitor *
729 +systraytomon(Monitor *m) {
730 + Monitor *t;
731 + int i, n;
732 + if(!systraypinning) {
733 + if(!m)
734 + return selmon;
735 + return m == selmon ? m : NULL;
736 + }
737 + for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
738 + for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t…
739 + if(systraypinningfailfirst && n < systraypinning)
740 + return mons;
741 + return t;
742 +}
743 +
744 void
745 zoom(const Arg *arg)
746 {
You are viewing proxied material from jay.scot. 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.