alpha-systray: more refactoring ref. #37

pull/74/head
bakkeby 3 years ago
parent e8db783d7e
commit e4d19e9c43

@ -1,4 +1,4 @@
From 47b8212ca25931d4d23b61b77f9a7d1c3d7f5f18 Mon Sep 17 00:00:00 2001 From 4e7ad00582ce172bc8d1506b971f3190591ec664 Mon Sep 17 00:00:00 2001
From: bakkeby <bakkeby@gmail.com> From: bakkeby <bakkeby@gmail.com>
Date: Tue, 7 Apr 2020 10:53:35 +0200 Date: Tue, 7 Apr 2020 10:53:35 +0200
Subject: [PATCH 2/2] Adding systray patch Subject: [PATCH 2/2] Adding systray patch
@ -6,8 +6,8 @@ Subject: [PATCH 2/2] Adding systray patch
Refer to https://dwm.suckless.org/patches/systray/ Refer to https://dwm.suckless.org/patches/systray/
--- ---
config.def.h | 4 + config.def.h | 4 +
dwm.c | 423 +++++++++++++++++++++++++++++++++++++++++++++++---- dwm.c | 415 ++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 400 insertions(+), 27 deletions(-) 2 files changed, 395 insertions(+), 24 deletions(-)
diff --git a/config.def.h b/config.def.h diff --git a/config.def.h b/config.def.h
index 4f68fe8..1952613 100644 index 4f68fe8..1952613 100644
@ -25,7 +25,7 @@ index 4f68fe8..1952613 100644
static const char dmenufont[] = "monospace:size=10"; static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222"; static const char col_gray1[] = "#222222";
diff --git a/dwm.c b/dwm.c diff --git a/dwm.c b/dwm.c
index 20f8309..c0643aa 100644 index 20f8309..0daa7c5 100644
--- a/dwm.c --- a/dwm.c
+++ b/dwm.c +++ b/dwm.c
@@ -59,12 +59,30 @@ @@ -59,12 +59,30 @@
@ -113,7 +113,7 @@ index 20f8309..c0643aa 100644
static void updatenumlockmask(void); static void updatenumlockmask(void);
static void updatesizehints(Client *c); static void updatesizehints(Client *c);
static void updatestatus(void); static void updatestatus(void);
+static void updatesystray(void); +static void updatesystray(int updatebar);
+static void updatesystrayicongeom(Client *i, int w, int h); +static void updatesystrayicongeom(Client *i, int w, int h);
+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); +static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
static void updatetitle(Client *c); static void updatetitle(Client *c);
@ -217,7 +217,7 @@ index 20f8309..c0643aa 100644
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ XSync(dpy, False); + XSync(dpy, False);
+ setclientstate(c, NormalState); + setclientstate(c, NormalState);
+ updatesystray(); + updatesystray(1);
+ } + }
+ return; + return;
+ } + }
@ -231,12 +231,12 @@ index 20f8309..c0643aa 100644
unmanage(c, 1); unmanage(c, 1);
+ else if (showsystray && (c = wintosystrayicon(ev->window))) { + else if (showsystray && (c = wintosystrayicon(ev->window))) {
+ removesystrayicon(c); + removesystrayicon(c);
+ updatesystray(); + updatesystray(1);
+ } + }
} }
void void
@@ -703,17 +795,20 @@ dirtomon(int dir) @@ -703,17 +795,23 @@ dirtomon(int dir)
void void
drawbar(Monitor *m) drawbar(Monitor *m)
{ {
@ -247,8 +247,11 @@ index 20f8309..c0643aa 100644
unsigned int i, occ = 0, urg = 0; unsigned int i, occ = 0, urg = 0;
Client *c; Client *c;
+ if (showsystray && m == systraytomon(m)) + if (showsystray && m == systraytomon(m)) {
+ stw = getsystraywidth(); + stw = getsystraywidth();
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, m->ww - stw, 0, stw, bh, 1, 1);
+ }
+ +
/* draw status first so it can be overdrawn by tags later */ /* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */ if (m == selmon) { /* status is only drawn on selected monitor */
@ -259,7 +262,7 @@ index 20f8309..c0643aa 100644
} }
for (c = m->clients; c; c = c->next) { for (c = m->clients; c; c = c->next) {
@@ -736,7 +831,7 @@ drawbar(Monitor *m) @@ -736,7 +834,7 @@ drawbar(Monitor *m)
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
@ -268,31 +271,31 @@ index 20f8309..c0643aa 100644
if (m->sel) { if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
@@ -747,7 +842,7 @@ drawbar(Monitor *m) @@ -757,6 +855,9 @@ drawbars(void)
drw_rect(drw, x, 0, w, bh, 1, 1);
} for (m = mons; m; m = m->next)
} drawbar(m);
- drw_map(drw, m->barwin, 0, 0, m->ww, bh); +
+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); + if (showsystray && !systraypinning)
+ updatesystray(0);
} }
void void
@@ -784,8 +879,12 @@ expose(XEvent *e) @@ -784,8 +885,12 @@ expose(XEvent *e)
Monitor *m; Monitor *m;
XExposeEvent *ev = &e->xexpose; XExposeEvent *ev = &e->xexpose;
- if (ev->count == 0 && (m = wintomon(ev->window))) - if (ev->count == 0 && (m = wintomon(ev->window)))
- drawbar(m);
+ if (ev->count == 0 && (m = wintomon(ev->window))) { + if (ev->count == 0 && (m = wintomon(ev->window))) {
+ if (showsystray && m == selmon) drawbar(m);
+ updatesystray(); +
+ else + if (showsystray && m == systraytomon(m))
+ drawbar(m); + updatesystray(0);
+ } + }
} }
void void
@@ -871,9 +970,17 @@ getatomprop(Client *c, Atom prop) @@ -871,9 +976,17 @@ getatomprop(Client *c, Atom prop)
unsigned char *p = NULL; unsigned char *p = NULL;
Atom da, atom = None; Atom da, atom = None;
@ -311,7 +314,7 @@ index 20f8309..c0643aa 100644
XFree(p); XFree(p);
} }
return atom; return atom;
@@ -907,6 +1014,16 @@ getstate(Window w) @@ -907,6 +1020,16 @@ getstate(Window w)
return result; return result;
} }
@ -328,7 +331,7 @@ index 20f8309..c0643aa 100644
int int
gettextprop(Window w, Atom atom, char *text, unsigned int size) gettextprop(Window w, Atom atom, char *text, unsigned int size)
{ {
@@ -1011,7 +1128,7 @@ killclient(const Arg *arg) @@ -1011,7 +1134,7 @@ killclient(const Arg *arg)
{ {
if (!selmon->sel) if (!selmon->sel)
return; return;
@ -337,20 +340,20 @@ index 20f8309..c0643aa 100644
XGrabServer(dpy); XGrabServer(dpy);
XSetErrorHandler(xerrordummy); XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll); XSetCloseDownMode(dpy, DestroyAll);
@@ -1100,6 +1217,12 @@ maprequest(XEvent *e) @@ -1100,6 +1223,12 @@ maprequest(XEvent *e)
static XWindowAttributes wa; static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest; XMapRequestEvent *ev = &e->xmaprequest;
+ Client *i; + Client *i;
+ if (showsystray && (i = wintosystrayicon(ev->window))) { + if (showsystray && (i = wintosystrayicon(ev->window))) {
+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); + sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
+ updatesystray(); + updatesystray(1);
+ } + }
+ +
if (!XGetWindowAttributes(dpy, ev->window, &wa)) if (!XGetWindowAttributes(dpy, ev->window, &wa))
return; return;
if (wa.override_redirect) if (wa.override_redirect)
@@ -1223,6 +1346,16 @@ propertynotify(XEvent *e) @@ -1223,6 +1352,16 @@ propertynotify(XEvent *e)
Window trans; Window trans;
XPropertyEvent *ev = &e->xproperty; XPropertyEvent *ev = &e->xproperty;
@ -361,13 +364,13 @@ index 20f8309..c0643aa 100644
+ } + }
+ else + else
+ updatesystrayiconstate(c, ev); + updatesystrayiconstate(c, ev);
+ updatesystray(); + updatesystray(1);
+ } + }
+ +
if ((ev->window == root) && (ev->atom == XA_WM_NAME)) if ((ev->window == root) && (ev->atom == XA_WM_NAME))
updatestatus(); updatestatus();
else if (ev->state == PropertyDelete) else if (ev->state == PropertyDelete)
@@ -1273,6 +1406,19 @@ recttomon(int x, int y, int w, int h) @@ -1273,6 +1412,19 @@ recttomon(int x, int y, int w, int h)
return r; return r;
} }
@ -387,7 +390,7 @@ index 20f8309..c0643aa 100644
void void
resize(Client *c, int x, int y, int w, int h, int interact) resize(Client *c, int x, int y, int w, int h, int interact)
{ {
@@ -1352,6 +1498,18 @@ resizemouse(const Arg *arg) @@ -1352,6 +1504,18 @@ resizemouse(const Arg *arg)
} }
} }
@ -399,14 +402,14 @@ index 20f8309..c0643aa 100644
+ +
+ if ((i = wintosystrayicon(ev->window))) { + if ((i = wintosystrayicon(ev->window))) {
+ updatesystrayicongeom(i, ev->width, ev->height); + updatesystrayicongeom(i, ev->width, ev->height);
+ updatesystray(); + updatesystray(1);
+ } + }
+} +}
+ +
void void
restack(Monitor *m) restack(Monitor *m)
{ {
@@ -1441,26 +1599,35 @@ setclientstate(Client *c, long state) @@ -1441,26 +1605,35 @@ setclientstate(Client *c, long state)
} }
int int
@ -453,7 +456,7 @@ index 20f8309..c0643aa 100644
} }
return exists; return exists;
} }
@@ -1474,7 +1641,7 @@ setfocus(Client *c) @@ -1474,7 +1647,7 @@ setfocus(Client *c)
XA_WINDOW, 32, PropModeReplace, XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &(c->win), 1); (unsigned char *) &(c->win), 1);
} }
@ -462,7 +465,7 @@ index 20f8309..c0643aa 100644
} }
void void
@@ -1564,13 +1731,22 @@ setup(void) @@ -1564,13 +1737,22 @@ setup(void)
wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
@ -485,32 +488,33 @@ index 20f8309..c0643aa 100644
/* init cursors */ /* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing); cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@@ -1579,6 +1755,9 @@ setup(void) @@ -1579,6 +1761,9 @@ setup(void)
scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
for (i = 0; i < LENGTH(colors); i++) for (i = 0; i < LENGTH(colors); i++)
scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3); scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3);
+ /* init system tray */ + /* init system tray */
+ if (showsystray) + if (showsystray)
+ updatesystray(); + updatesystray(0);
/* init bars */ /* init bars */
updatebars(); updatebars();
updatestatus(); updatestatus();
@@ -1661,6 +1840,22 @@ spawn(const Arg *arg) @@ -1661,6 +1846,23 @@ spawn(const Arg *arg)
} }
} }
+Monitor * +Monitor *
+systraytomon(Monitor *m) { +systraytomon(Monitor *m)
+{
+ Monitor *t; + Monitor *t;
+ int i, n; + int i, n;
+ if(!systraypinning) { + if (!systraypinning) {
+ if(!m) + if (!m)
+ return selmon; + return selmon;
+ return m == selmon ? m : NULL; + return m == selmon ? m : NULL;
+ } + }
+ for(n = 1, t = mons; t && t->next; n++, t = t->next) ; + for (n = 1, t = mons; t && t->next; n++, t = t->next);
+ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; + for (i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next);
+ if(systraypinningfailfirst && n < systraypinning) + if (systraypinningfailfirst && n < systraypinning)
+ return mons; + return mons;
+ return t; + return t;
+} +}
@ -518,7 +522,7 @@ index 20f8309..c0643aa 100644
void void
tag(const Arg *arg) tag(const Arg *arg)
{ {
@@ -1711,6 +1906,23 @@ togglebar(const Arg *arg) @@ -1711,6 +1913,23 @@ togglebar(const Arg *arg)
selmon->showbar = !selmon->showbar; selmon->showbar = !selmon->showbar;
updatebarpos(selmon); updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
@ -542,7 +546,7 @@ index 20f8309..c0643aa 100644
arrange(selmon); arrange(selmon);
} }
@@ -1804,12 +2016,18 @@ unmapnotify(XEvent *e) @@ -1804,6 +2023,11 @@ unmapnotify(XEvent *e)
setclientstate(c, WithdrawnState); setclientstate(c, WithdrawnState);
else else
unmanage(c, 0); unmanage(c, 0);
@ -550,26 +554,11 @@ index 20f8309..c0643aa 100644
+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do + /* KLUDGE! sometimes icons occasionally unmap their windows, but do
+ * _not_ destroy them. We map those windows back */ + * _not_ destroy them. We map those windows back */
+ XMapRaised(dpy, c->win); + XMapRaised(dpy, c->win);
+ updatesystray(); + updatesystray(1);
} }
} }
void @@ -1826,6 +2050,8 @@ updatebars(void)
updatebars(void)
{
+ unsigned int w;
Monitor *m;
XSetWindowAttributes wa = {
.override_redirect = True,
@@ -1822,10 +2040,15 @@ updatebars(void)
for (m = mons; m; m = m->next) {
if (m->barwin)
continue;
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth,
+ w = m->ww;
+ if (showsystray && m == systraytomon(m))
+ w -= getsystraywidth();
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, depth,
InputOutput, visual, InputOutput, visual,
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
@ -578,16 +567,12 @@ index 20f8309..c0643aa 100644
XMapRaised(dpy, m->barwin); XMapRaised(dpy, m->barwin);
XSetClassHint(dpy, m->barwin, &ch); XSetClassHint(dpy, m->barwin, &ch);
} }
@@ -2001,6 +2224,142 @@ updatestatus(void) @@ -2003,6 +2229,137 @@ updatestatus(void)
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION);
drawbar(selmon); drawbar(selmon);
+ if (showsystray) }
+ updatesystray();
+}
+
+void +void
+updatesystray(void) +updatesystray(int updatebar)
+{ +{
+ XSetWindowAttributes wa; + XSetWindowAttributes wa;
+ XWindowChanges wc; + XWindowChanges wc;
@ -636,11 +621,6 @@ index 20f8309..c0643aa 100644
+ } + }
+ } + }
+ +
+ /* Clear status bar to avoid artifacts beneath systray icons */
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, 0, 0, selmon->ww, bh, 1, 1);
+ drw_map(drw, selmon->barwin, 0, 0, selmon->ww, bh);
+
+ for (w = 0, i = systray->icons; i; i = i->next) { + for (w = 0, i = systray->icons; i; i = i->next) {
+ wa.background_pixel = 0; + wa.background_pixel = 0;
+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); + XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
@ -664,7 +644,9 @@ index 20f8309..c0643aa 100644
+ XMapWindow(dpy, systray->win); + XMapWindow(dpy, systray->win);
+ XMapSubwindows(dpy, systray->win); + XMapSubwindows(dpy, systray->win);
+ XSync(dpy, False); + XSync(dpy, False);
+ drawbar(m); +
+ if (updatebar)
+ drawbar(m);
+} +}
+ +
+void +void
@ -718,10 +700,12 @@ index 20f8309..c0643aa 100644
+ return; + return;
+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, + sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
+ systray->win, XEMBED_EMBEDDED_VERSION); + systray->win, XEMBED_EMBEDDED_VERSION);
} +}
+
void void
@@ -2085,6 +2444,16 @@ wintomon(Window w) updatetitle(Client *c)
{
@@ -2085,6 +2442,16 @@ wintomon(Window w)
return selmon; return selmon;
} }

@ -296,7 +296,7 @@ index 4465af1..20f8309 100644
2.19.1 2.19.1
From 47b8212ca25931d4d23b61b77f9a7d1c3d7f5f18 Mon Sep 17 00:00:00 2001 From 4e7ad00582ce172bc8d1506b971f3190591ec664 Mon Sep 17 00:00:00 2001
From: bakkeby <bakkeby@gmail.com> From: bakkeby <bakkeby@gmail.com>
Date: Tue, 7 Apr 2020 10:53:35 +0200 Date: Tue, 7 Apr 2020 10:53:35 +0200
Subject: [PATCH 2/2] Adding systray patch Subject: [PATCH 2/2] Adding systray patch
@ -304,8 +304,8 @@ Subject: [PATCH 2/2] Adding systray patch
Refer to https://dwm.suckless.org/patches/systray/ Refer to https://dwm.suckless.org/patches/systray/
--- ---
config.def.h | 4 + config.def.h | 4 +
dwm.c | 423 +++++++++++++++++++++++++++++++++++++++++++++++---- dwm.c | 415 ++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 400 insertions(+), 27 deletions(-) 2 files changed, 395 insertions(+), 24 deletions(-)
diff --git a/config.def.h b/config.def.h diff --git a/config.def.h b/config.def.h
index 4f68fe8..1952613 100644 index 4f68fe8..1952613 100644
@ -323,7 +323,7 @@ index 4f68fe8..1952613 100644
static const char dmenufont[] = "monospace:size=10"; static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222"; static const char col_gray1[] = "#222222";
diff --git a/dwm.c b/dwm.c diff --git a/dwm.c b/dwm.c
index 20f8309..c0643aa 100644 index 20f8309..0daa7c5 100644
--- a/dwm.c --- a/dwm.c
+++ b/dwm.c +++ b/dwm.c
@@ -59,12 +59,30 @@ @@ -59,12 +59,30 @@
@ -411,7 +411,7 @@ index 20f8309..c0643aa 100644
static void updatenumlockmask(void); static void updatenumlockmask(void);
static void updatesizehints(Client *c); static void updatesizehints(Client *c);
static void updatestatus(void); static void updatestatus(void);
+static void updatesystray(void); +static void updatesystray(int updatebar);
+static void updatesystrayicongeom(Client *i, int w, int h); +static void updatesystrayicongeom(Client *i, int w, int h);
+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); +static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
static void updatetitle(Client *c); static void updatetitle(Client *c);
@ -515,7 +515,7 @@ index 20f8309..c0643aa 100644
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ XSync(dpy, False); + XSync(dpy, False);
+ setclientstate(c, NormalState); + setclientstate(c, NormalState);
+ updatesystray(); + updatesystray(1);
+ } + }
+ return; + return;
+ } + }
@ -529,12 +529,12 @@ index 20f8309..c0643aa 100644
unmanage(c, 1); unmanage(c, 1);
+ else if (showsystray && (c = wintosystrayicon(ev->window))) { + else if (showsystray && (c = wintosystrayicon(ev->window))) {
+ removesystrayicon(c); + removesystrayicon(c);
+ updatesystray(); + updatesystray(1);
+ } + }
} }
void void
@@ -703,17 +795,20 @@ dirtomon(int dir) @@ -703,17 +795,23 @@ dirtomon(int dir)
void void
drawbar(Monitor *m) drawbar(Monitor *m)
{ {
@ -545,8 +545,11 @@ index 20f8309..c0643aa 100644
unsigned int i, occ = 0, urg = 0; unsigned int i, occ = 0, urg = 0;
Client *c; Client *c;
+ if (showsystray && m == systraytomon(m)) + if (showsystray && m == systraytomon(m)) {
+ stw = getsystraywidth(); + stw = getsystraywidth();
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, m->ww - stw, 0, stw, bh, 1, 1);
+ }
+ +
/* draw status first so it can be overdrawn by tags later */ /* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */ if (m == selmon) { /* status is only drawn on selected monitor */
@ -557,7 +560,7 @@ index 20f8309..c0643aa 100644
} }
for (c = m->clients; c; c = c->next) { for (c = m->clients; c; c = c->next) {
@@ -736,7 +831,7 @@ drawbar(Monitor *m) @@ -736,7 +834,7 @@ drawbar(Monitor *m)
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
@ -566,31 +569,31 @@ index 20f8309..c0643aa 100644
if (m->sel) { if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
@@ -747,7 +842,7 @@ drawbar(Monitor *m) @@ -757,6 +855,9 @@ drawbars(void)
drw_rect(drw, x, 0, w, bh, 1, 1);
} for (m = mons; m; m = m->next)
} drawbar(m);
- drw_map(drw, m->barwin, 0, 0, m->ww, bh); +
+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); + if (showsystray && !systraypinning)
+ updatesystray(0);
} }
void void
@@ -784,8 +879,12 @@ expose(XEvent *e) @@ -784,8 +885,12 @@ expose(XEvent *e)
Monitor *m; Monitor *m;
XExposeEvent *ev = &e->xexpose; XExposeEvent *ev = &e->xexpose;
- if (ev->count == 0 && (m = wintomon(ev->window))) - if (ev->count == 0 && (m = wintomon(ev->window)))
- drawbar(m);
+ if (ev->count == 0 && (m = wintomon(ev->window))) { + if (ev->count == 0 && (m = wintomon(ev->window))) {
+ if (showsystray && m == selmon) drawbar(m);
+ updatesystray(); +
+ else + if (showsystray && m == systraytomon(m))
+ drawbar(m); + updatesystray(0);
+ } + }
} }
void void
@@ -871,9 +970,17 @@ getatomprop(Client *c, Atom prop) @@ -871,9 +976,17 @@ getatomprop(Client *c, Atom prop)
unsigned char *p = NULL; unsigned char *p = NULL;
Atom da, atom = None; Atom da, atom = None;
@ -609,7 +612,7 @@ index 20f8309..c0643aa 100644
XFree(p); XFree(p);
} }
return atom; return atom;
@@ -907,6 +1014,16 @@ getstate(Window w) @@ -907,6 +1020,16 @@ getstate(Window w)
return result; return result;
} }
@ -626,7 +629,7 @@ index 20f8309..c0643aa 100644
int int
gettextprop(Window w, Atom atom, char *text, unsigned int size) gettextprop(Window w, Atom atom, char *text, unsigned int size)
{ {
@@ -1011,7 +1128,7 @@ killclient(const Arg *arg) @@ -1011,7 +1134,7 @@ killclient(const Arg *arg)
{ {
if (!selmon->sel) if (!selmon->sel)
return; return;
@ -635,20 +638,20 @@ index 20f8309..c0643aa 100644
XGrabServer(dpy); XGrabServer(dpy);
XSetErrorHandler(xerrordummy); XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll); XSetCloseDownMode(dpy, DestroyAll);
@@ -1100,6 +1217,12 @@ maprequest(XEvent *e) @@ -1100,6 +1223,12 @@ maprequest(XEvent *e)
static XWindowAttributes wa; static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest; XMapRequestEvent *ev = &e->xmaprequest;
+ Client *i; + Client *i;
+ if (showsystray && (i = wintosystrayicon(ev->window))) { + if (showsystray && (i = wintosystrayicon(ev->window))) {
+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); + sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
+ updatesystray(); + updatesystray(1);
+ } + }
+ +
if (!XGetWindowAttributes(dpy, ev->window, &wa)) if (!XGetWindowAttributes(dpy, ev->window, &wa))
return; return;
if (wa.override_redirect) if (wa.override_redirect)
@@ -1223,6 +1346,16 @@ propertynotify(XEvent *e) @@ -1223,6 +1352,16 @@ propertynotify(XEvent *e)
Window trans; Window trans;
XPropertyEvent *ev = &e->xproperty; XPropertyEvent *ev = &e->xproperty;
@ -659,13 +662,13 @@ index 20f8309..c0643aa 100644
+ } + }
+ else + else
+ updatesystrayiconstate(c, ev); + updatesystrayiconstate(c, ev);
+ updatesystray(); + updatesystray(1);
+ } + }
+ +
if ((ev->window == root) && (ev->atom == XA_WM_NAME)) if ((ev->window == root) && (ev->atom == XA_WM_NAME))
updatestatus(); updatestatus();
else if (ev->state == PropertyDelete) else if (ev->state == PropertyDelete)
@@ -1273,6 +1406,19 @@ recttomon(int x, int y, int w, int h) @@ -1273,6 +1412,19 @@ recttomon(int x, int y, int w, int h)
return r; return r;
} }
@ -685,7 +688,7 @@ index 20f8309..c0643aa 100644
void void
resize(Client *c, int x, int y, int w, int h, int interact) resize(Client *c, int x, int y, int w, int h, int interact)
{ {
@@ -1352,6 +1498,18 @@ resizemouse(const Arg *arg) @@ -1352,6 +1504,18 @@ resizemouse(const Arg *arg)
} }
} }
@ -697,14 +700,14 @@ index 20f8309..c0643aa 100644
+ +
+ if ((i = wintosystrayicon(ev->window))) { + if ((i = wintosystrayicon(ev->window))) {
+ updatesystrayicongeom(i, ev->width, ev->height); + updatesystrayicongeom(i, ev->width, ev->height);
+ updatesystray(); + updatesystray(1);
+ } + }
+} +}
+ +
void void
restack(Monitor *m) restack(Monitor *m)
{ {
@@ -1441,26 +1599,35 @@ setclientstate(Client *c, long state) @@ -1441,26 +1605,35 @@ setclientstate(Client *c, long state)
} }
int int
@ -751,7 +754,7 @@ index 20f8309..c0643aa 100644
} }
return exists; return exists;
} }
@@ -1474,7 +1641,7 @@ setfocus(Client *c) @@ -1474,7 +1647,7 @@ setfocus(Client *c)
XA_WINDOW, 32, PropModeReplace, XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &(c->win), 1); (unsigned char *) &(c->win), 1);
} }
@ -760,7 +763,7 @@ index 20f8309..c0643aa 100644
} }
void void
@@ -1564,13 +1731,22 @@ setup(void) @@ -1564,13 +1737,22 @@ setup(void)
wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
@ -783,32 +786,33 @@ index 20f8309..c0643aa 100644
/* init cursors */ /* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing); cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@@ -1579,6 +1755,9 @@ setup(void) @@ -1579,6 +1761,9 @@ setup(void)
scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
for (i = 0; i < LENGTH(colors); i++) for (i = 0; i < LENGTH(colors); i++)
scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3); scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3);
+ /* init system tray */ + /* init system tray */
+ if (showsystray) + if (showsystray)
+ updatesystray(); + updatesystray(0);
/* init bars */ /* init bars */
updatebars(); updatebars();
updatestatus(); updatestatus();
@@ -1661,6 +1840,22 @@ spawn(const Arg *arg) @@ -1661,6 +1846,23 @@ spawn(const Arg *arg)
} }
} }
+Monitor * +Monitor *
+systraytomon(Monitor *m) { +systraytomon(Monitor *m)
+{
+ Monitor *t; + Monitor *t;
+ int i, n; + int i, n;
+ if(!systraypinning) { + if (!systraypinning) {
+ if(!m) + if (!m)
+ return selmon; + return selmon;
+ return m == selmon ? m : NULL; + return m == selmon ? m : NULL;
+ } + }
+ for(n = 1, t = mons; t && t->next; n++, t = t->next) ; + for (n = 1, t = mons; t && t->next; n++, t = t->next);
+ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; + for (i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next);
+ if(systraypinningfailfirst && n < systraypinning) + if (systraypinningfailfirst && n < systraypinning)
+ return mons; + return mons;
+ return t; + return t;
+} +}
@ -816,7 +820,7 @@ index 20f8309..c0643aa 100644
void void
tag(const Arg *arg) tag(const Arg *arg)
{ {
@@ -1711,6 +1906,23 @@ togglebar(const Arg *arg) @@ -1711,6 +1913,23 @@ togglebar(const Arg *arg)
selmon->showbar = !selmon->showbar; selmon->showbar = !selmon->showbar;
updatebarpos(selmon); updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
@ -840,7 +844,7 @@ index 20f8309..c0643aa 100644
arrange(selmon); arrange(selmon);
} }
@@ -1804,12 +2016,18 @@ unmapnotify(XEvent *e) @@ -1804,6 +2023,11 @@ unmapnotify(XEvent *e)
setclientstate(c, WithdrawnState); setclientstate(c, WithdrawnState);
else else
unmanage(c, 0); unmanage(c, 0);
@ -848,26 +852,11 @@ index 20f8309..c0643aa 100644
+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do + /* KLUDGE! sometimes icons occasionally unmap their windows, but do
+ * _not_ destroy them. We map those windows back */ + * _not_ destroy them. We map those windows back */
+ XMapRaised(dpy, c->win); + XMapRaised(dpy, c->win);
+ updatesystray(); + updatesystray(1);
} }
} }
void @@ -1826,6 +2050,8 @@ updatebars(void)
updatebars(void)
{
+ unsigned int w;
Monitor *m;
XSetWindowAttributes wa = {
.override_redirect = True,
@@ -1822,10 +2040,15 @@ updatebars(void)
for (m = mons; m; m = m->next) {
if (m->barwin)
continue;
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth,
+ w = m->ww;
+ if (showsystray && m == systraytomon(m))
+ w -= getsystraywidth();
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, depth,
InputOutput, visual, InputOutput, visual,
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
@ -876,16 +865,12 @@ index 20f8309..c0643aa 100644
XMapRaised(dpy, m->barwin); XMapRaised(dpy, m->barwin);
XSetClassHint(dpy, m->barwin, &ch); XSetClassHint(dpy, m->barwin, &ch);
} }
@@ -2001,6 +2224,142 @@ updatestatus(void) @@ -2003,6 +2229,137 @@ updatestatus(void)
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION);
drawbar(selmon); drawbar(selmon);
+ if (showsystray) }
+ updatesystray();
+}
+
+void +void
+updatesystray(void) +updatesystray(int updatebar)
+{ +{
+ XSetWindowAttributes wa; + XSetWindowAttributes wa;
+ XWindowChanges wc; + XWindowChanges wc;
@ -934,11 +919,6 @@ index 20f8309..c0643aa 100644
+ } + }
+ } + }
+ +
+ /* Clear status bar to avoid artifacts beneath systray icons */
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, 0, 0, selmon->ww, bh, 1, 1);
+ drw_map(drw, selmon->barwin, 0, 0, selmon->ww, bh);
+
+ for (w = 0, i = systray->icons; i; i = i->next) { + for (w = 0, i = systray->icons; i; i = i->next) {
+ wa.background_pixel = 0; + wa.background_pixel = 0;
+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); + XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
@ -962,7 +942,9 @@ index 20f8309..c0643aa 100644
+ XMapWindow(dpy, systray->win); + XMapWindow(dpy, systray->win);
+ XMapSubwindows(dpy, systray->win); + XMapSubwindows(dpy, systray->win);
+ XSync(dpy, False); + XSync(dpy, False);
+ drawbar(m); +
+ if (updatebar)
+ drawbar(m);
+} +}
+ +
+void +void
@ -1016,10 +998,12 @@ index 20f8309..c0643aa 100644
+ return; + return;
+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, + sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
+ systray->win, XEMBED_EMBEDDED_VERSION); + systray->win, XEMBED_EMBEDDED_VERSION);
} +}
+
void void
@@ -2085,6 +2444,16 @@ wintomon(Window w) updatetitle(Client *c)
{
@@ -2085,6 +2442,16 @@ wintomon(Window w)
return selmon; return selmon;
} }

Loading…
Cancel
Save