it* dwm + patches Err codevoid.de 70 i Err codevoid.de 70 hgit clone git://git.codevoid.de/dwm-sdk URL:git://git.codevoid.de/dwm-sdk codevoid.de 70 1Log /git/dwm-sdk/log.gph codevoid.de 70 1Files /git/dwm-sdk/files.gph codevoid.de 70 1Refs /git/dwm-sdk/refs.gph codevoid.de 70 1README /git/dwm-sdk/file/README.gph codevoid.de 70 1LICENSE /git/dwm-sdk/file/LICENSE.gph codevoid.de 70 i--- Err codevoid.de 70 1commit 2fc02334c971485d52e007a3c0a5de834e7c98c0 /git/dwm-sdk/commit/2fc02334c971485d52e007a3c0a5de834e7c98c0.gph codevoid.de 70 1parent 7ba08f0d3026fda7f3879542a15420f63e851728 /git/dwm-sdk/commit/7ba08f0d3026fda7f3879542a15420f63e851728.gph codevoid.de 70 hAuthor: Stefan Hagen URL:mailto:sh+git[at]codevoid[dot]de codevoid.de 70 iDate: Fri, 16 Nov 2018 09:45:11 +0100 Err codevoid.de 70 i Err codevoid.de 70 iAdd systray patch Err codevoid.de 70 i Err codevoid.de 70 iDiffstat: Err codevoid.de 70 i M config.def.h | 2 ++ Err codevoid.de 70 i M config.h | 2 ++ Err codevoid.de 70 i M dwm.c | 349 +++++++++++++++++++++++++++++-- Err codevoid.de 70 i Err codevoid.de 70 i3 files changed, 332 insertions(+), 21 deletions(-) Err codevoid.de 70 i--- Err codevoid.de 70 1diff --git a/config.def.h b/config.def.h /git/dwm-sdk/file/config.def.h.gph codevoid.de 70 it@@ -13,6 +13,8 @@ static const char floatselbordercolor[] = "#005577"; Err codevoid.de 70 i static const unsigned int borderpx = 1; /* border pixel of windows */ Err codevoid.de 70 i static const unsigned int gappx = 18; /* gap pixel between windows */ Err codevoid.de 70 i static const unsigned int snap = 32; /* snap pixel */ Err codevoid.de 70 i+static const unsigned int systrayspacing = 2; /* systray spacing */ Err codevoid.de 70 i+static const Bool showsystray = True; /* False means no systray */ Err codevoid.de 70 i static const Bool showbar = True; /* False means no bar */ Err codevoid.de 70 i static const Bool topbar = True; /* False means bottom bar */ Err codevoid.de 70 i static const Bool extrabar = True; /* False means no extra bar */ Err codevoid.de 70 1diff --git a/config.h b/config.h /git/dwm-sdk/file/config.h.gph codevoid.de 70 it@@ -13,6 +13,8 @@ static const char floatselbordercolor[] = "#FF0000"; // floating window border Err codevoid.de 70 i static const unsigned int borderpx = 1; // border pixel of windows Err codevoid.de 70 i static const unsigned int gappx = 8; // gap pixel between windows Err codevoid.de 70 i static const unsigned int snap = 8; // snap pixel Err codevoid.de 70 i+static const unsigned int systrayspacing = 2; // systray spacing Err codevoid.de 70 i+static const Bool showsystray = True; // False means no systray Err codevoid.de 70 i static const Bool showbar = True; // False means no bar Err codevoid.de 70 i static const Bool topbar = True; // False means bottom bar Err codevoid.de 70 i static const Bool extrabar = True; // False means no extra bar Err codevoid.de 70 1diff --git a/dwm.c b/dwm.c /git/dwm-sdk/file/dwm.c.gph codevoid.de 70 it@@ -55,12 +55,30 @@ Err codevoid.de 70 i #define TAGMASK ((1 << LENGTH(tags)) - 1) Err codevoid.de 70 i #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) Err codevoid.de 70 i Err codevoid.de 70 i+#define SYSTEM_TRAY_REQUEST_DOCK 0 Err codevoid.de 70 i+#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 Err codevoid.de 70 i+ Err codevoid.de 70 i+/* XEMBED messages */ Err codevoid.de 70 i+#define XEMBED_EMBEDDED_NOTIFY 0 Err codevoid.de 70 i+#define XEMBED_WINDOW_ACTIVATE 1 Err codevoid.de 70 i+#define XEMBED_FOCUS_IN 4 Err codevoid.de 70 i+#define XEMBED_MODALITY_ON 10 Err codevoid.de 70 i+ Err codevoid.de 70 i+#define XEMBED_MAPPED (1 << 0) Err codevoid.de 70 i+#define XEMBED_WINDOW_ACTIVATE 1 Err codevoid.de 70 i+#define XEMBED_WINDOW_DEACTIVATE 2 Err codevoid.de 70 i+ Err codevoid.de 70 i+#define VERSION_MAJOR 0 Err codevoid.de 70 i+#define VERSION_MINOR 0 Err codevoid.de 70 i+#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR Err codevoid.de 70 i+ Err codevoid.de 70 i /* enums */ Err codevoid.de 70 i enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ Err codevoid.de 70 i enum { ColBorder, ColFG, ColBG, ColBorderFloat, ColLast }; /* color */ Err codevoid.de 70 i-enum { NetSupported, NetWMName, NetWMState, Err codevoid.de 70 i- NetWMFullscreen, NetActiveWindow, NetWMWindowType, Err codevoid.de 70 i- NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ Err codevoid.de 70 i+enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, Err codevoid.de 70 i+ NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, NetWMWindowType, Err codevoid.de 70 i+ NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ Err codevoid.de 70 i+enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ Err codevoid.de 70 i enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ Err codevoid.de 70 i enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, Err codevoid.de 70 i ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ Err codevoid.de 70 it@@ -163,6 +181,12 @@ typedef struct { Err codevoid.de 70 i char text[256]; Err codevoid.de 70 i } Bar; Err codevoid.de 70 i Err codevoid.de 70 i+typedef struct Systray Systray; Err codevoid.de 70 i+struct Systray { Err codevoid.de 70 i+ Window win; Err codevoid.de 70 i+ Client *icons; Err codevoid.de 70 i+}; Err codevoid.de 70 i+ Err codevoid.de 70 i /* function declarations */ Err codevoid.de 70 i static void applyrules(Client *c); Err codevoid.de 70 i static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); Err codevoid.de 70 it@@ -195,9 +219,11 @@ static void focus(Client *c); Err codevoid.de 70 i static void focusin(XEvent *e); Err codevoid.de 70 i static void focusmon(const Arg *arg); Err codevoid.de 70 i static void focusstack(const Arg *arg); Err codevoid.de 70 i+static Atom getatomprop(Client *c, Atom prop); Err codevoid.de 70 i static unsigned long getcolor(const char *colstr); Err codevoid.de 70 i static Bool getrootptr(int *x, int *y); Err codevoid.de 70 i static long getstate(Window w); Err codevoid.de 70 i+static unsigned int getsystraywidth(); Err codevoid.de 70 i static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); Err codevoid.de 70 i static void grabbuttons(Client *c, Bool focused); Err codevoid.de 70 i static void grabkeys(void); Err codevoid.de 70 it@@ -216,13 +242,16 @@ static void pop(Client *); Err codevoid.de 70 i static void propertynotify(XEvent *e); Err codevoid.de 70 i static void quit(const Arg *arg); Err codevoid.de 70 i static Monitor *recttomon(int x, int y, int w, int h); Err codevoid.de 70 i+static void removesystrayicon(Client *i); Err codevoid.de 70 i static void resize(Client *c, int x, int y, int w, int h, Bool interact); Err codevoid.de 70 i+static void resizebarwin(Monitor *m); Err codevoid.de 70 i static void resizeclient(Client *c, int x, int y, int w, int h); Err codevoid.de 70 i static void resizemouse(const Arg *arg); Err codevoid.de 70 i+static void resizerequest(XEvent *e); Err codevoid.de 70 i static void restack(Monitor *m); Err codevoid.de 70 i static void run(void); Err codevoid.de 70 i static void scan(void); Err codevoid.de 70 i-static Bool sendevent(Client *c, Atom proto); Err codevoid.de 70 i+static Bool sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); Err codevoid.de 70 i static void sendmon(Client *c, Monitor *m); Err codevoid.de 70 i static void setclientstate(Client *c, long state); Err codevoid.de 70 i static void setfocus(Client *c); Err codevoid.de 70 it@@ -253,6 +282,9 @@ static void updatebars(void); Err codevoid.de 70 i static void updatenumlockmask(void); Err codevoid.de 70 i static void updatesizehints(Client *c); Err codevoid.de 70 i static void updatestatus(void); Err codevoid.de 70 i+static void updatesystray(void); Err codevoid.de 70 i+static void updatesystrayicongeom(Client *i, int w, int h); Err codevoid.de 70 i+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); Err codevoid.de 70 i static void updatewindowtype(Client *c); Err codevoid.de 70 i static void updatetitle(Client *c); Err codevoid.de 70 i static void updatewmhints(Client *c); Err codevoid.de 70 it@@ -261,12 +293,15 @@ static void viewtoleft(const Arg *arg); Err codevoid.de 70 i static void viewtoright(const Arg *arg); Err codevoid.de 70 i static Client *wintoclient(Window w); Err codevoid.de 70 i static Monitor *wintomon(Window w); Err codevoid.de 70 i+static Client *wintosystrayicon(Window w); Err codevoid.de 70 i static int xerror(Display *dpy, XErrorEvent *ee); Err codevoid.de 70 i static int xerrordummy(Display *dpy, XErrorEvent *ee); Err codevoid.de 70 i static int xerrorstart(Display *dpy, XErrorEvent *ee); Err codevoid.de 70 i static void zoom(const Arg *arg); Err codevoid.de 70 i Err codevoid.de 70 i /* variables */ Err codevoid.de 70 i+static Systray *systray = NULL; Err codevoid.de 70 i+static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; Err codevoid.de 70 i static Client *prevzoom = NULL; Err codevoid.de 70 i static const char broken[] = "broken"; Err codevoid.de 70 i static char stext[256]; Err codevoid.de 70 it@@ -289,9 +324,10 @@ static void (*handler[LASTEvent]) (XEvent *) = { Err codevoid.de 70 i [MapRequest] = maprequest, Err codevoid.de 70 i [MotionNotify] = motionnotify, Err codevoid.de 70 i [PropertyNotify] = propertynotify, Err codevoid.de 70 i+ [ResizeRequest] = resizerequest, Err codevoid.de 70 i [UnmapNotify] = unmapnotify Err codevoid.de 70 i }; Err codevoid.de 70 i-static Atom wmatom[WMLast], netatom[NetLast]; Err codevoid.de 70 i+static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; Err codevoid.de 70 i static Bool running = True; Err codevoid.de 70 i static Cursor cursor[CurLast]; Err codevoid.de 70 i static Display *dpy; Err codevoid.de 70 it@@ -524,6 +560,11 @@ cleanup(void) { Err codevoid.de 70 i XDestroyWindow(dpy, eb.win); Err codevoid.de 70 i while(mons) Err codevoid.de 70 i cleanupmon(mons); Err codevoid.de 70 i+ if(showsystray) { Err codevoid.de 70 i+ XUnmapWindow(dpy, systray->win); Err codevoid.de 70 i+ XDestroyWindow(dpy, systray->win); Err codevoid.de 70 i+ free(systray); Err codevoid.de 70 i+ } Err codevoid.de 70 i XSync(dpy, False); Err codevoid.de 70 i XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); Err codevoid.de 70 i } Err codevoid.de 70 it@@ -557,9 +598,49 @@ clearurgent(Client *c) { Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i clientmessage(XEvent *e) { Err codevoid.de 70 i+ XWindowAttributes wa; Err codevoid.de 70 i+ XSetWindowAttributes swa; Err codevoid.de 70 i XClientMessageEvent *cme = &e->xclient; Err codevoid.de 70 i Client *c = wintoclient(cme->window); Err codevoid.de 70 i Err codevoid.de 70 i+ if(showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { Err codevoid.de 70 i+ /* add systray icons */ Err codevoid.de 70 i+ if(cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { Err codevoid.de 70 i+ if(!(c = (Client *)calloc(1, sizeof(Client)))) Err codevoid.de 70 i+ die("fatal: could not malloc() %u bytes\n", sizeof(Client)); Err codevoid.de 70 i+ c->win = cme->data.l[2]; Err codevoid.de 70 i+ c->mon = selmon; Err codevoid.de 70 i+ c->next = systray->icons; Err codevoid.de 70 i+ systray->icons = c; Err codevoid.de 70 i+ XGetWindowAttributes(dpy, c->win, &wa); Err codevoid.de 70 i+ c->x = c->oldx = c->y = c->oldy = 0; Err codevoid.de 70 i+ c->w = c->oldw = wa.width; Err codevoid.de 70 i+ c->h = c->oldh = wa.height; Err codevoid.de 70 i+ c->oldbw = wa.border_width; Err codevoid.de 70 i+ c->bw = 0; Err codevoid.de 70 i+ c->isfloating = True; Err codevoid.de 70 i+ /* reuse tags field as mapped status */ Err codevoid.de 70 i+ c->tags = 1; Err codevoid.de 70 i+ updatesizehints(c); Err codevoid.de 70 i+ updatesystrayicongeom(c, wa.width, wa.height); Err codevoid.de 70 i+ XAddToSaveSet(dpy, c->win); Err codevoid.de 70 i+ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); Err codevoid.de 70 i+ XReparentWindow(dpy, c->win, systray->win, 0, 0); Err codevoid.de 70 i+ /* use parents background pixmap */ Err codevoid.de 70 i+ swa.background_pixmap = ParentRelative; Err codevoid.de 70 i+ swa.background_pixel = dc.norm[ColBG]; Err codevoid.de 70 i+ XChangeWindowAttributes(dpy, c->win, CWBackPixmap|CWBackPixel, &swa); Err codevoid.de 70 i+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); Err codevoid.de 70 i+ /* FIXME not sure if I have to send these events, too */ Err codevoid.de 70 i+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); Err codevoid.de 70 i+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); Err codevoid.de 70 i+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); Err codevoid.de 70 i+ resizebarwin(selmon); Err codevoid.de 70 i+ updatesystray(); Err codevoid.de 70 i+ setclientstate(c, NormalState); Err codevoid.de 70 i+ } Err codevoid.de 70 i+ return; Err codevoid.de 70 i+ } Err codevoid.de 70 i if(!c) Err codevoid.de 70 i return; Err codevoid.de 70 i if(cme->message_type == netatom[NetWMState]) { Err codevoid.de 70 it@@ -612,6 +693,7 @@ configurenotify(XEvent *e) { Err codevoid.de 70 i for(m = mons; m; m = m->next) Err codevoid.de 70 i XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); Err codevoid.de 70 i XMoveResizeWindow(dpy, eb.win, mons->wx, eb.y, mons->ww, bh); Err codevoid.de 70 i+ resizebarwin(m); Err codevoid.de 70 i focus(NULL); Err codevoid.de 70 i arrange(NULL); Err codevoid.de 70 i } Err codevoid.de 70 it@@ -714,6 +796,11 @@ destroynotify(XEvent *e) { Err codevoid.de 70 i Err codevoid.de 70 i if((c = wintoclient(ev->window))) Err codevoid.de 70 i unmanage(c, True); Err codevoid.de 70 i+ else if((c = wintosystrayicon(ev->window))) { Err codevoid.de 70 i+ removesystrayicon(c); Err codevoid.de 70 i+ resizebarwin(selmon); Err codevoid.de 70 i+ updatesystray(); Err codevoid.de 70 i+ } Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 it@@ -769,6 +856,7 @@ drawbar(Monitor *m) { Err codevoid.de 70 i unsigned long *col; Err codevoid.de 70 i Client *c; Err codevoid.de 70 i Err codevoid.de 70 i+ resizebarwin(m); Err codevoid.de 70 i for(c = m->clients; c; c = c->next) { Err codevoid.de 70 i occ |= c->tags; Err codevoid.de 70 i if(c->isurgent) Err codevoid.de 70 it@@ -790,6 +878,9 @@ drawbar(Monitor *m) { Err codevoid.de 70 i if(m == selmon) { /* status is only drawn on selected monitor */ Err codevoid.de 70 i dc.w = TEXTW(stext); Err codevoid.de 70 i dc.x = m->ww - dc.w; Err codevoid.de 70 i+ if(showsystray && m == selmon) { Err codevoid.de 70 i+ dc.x -= getsystraywidth(); Err codevoid.de 70 i+ } Err codevoid.de 70 i if(dc.x < x) { Err codevoid.de 70 i dc.x = x; Err codevoid.de 70 i dc.w = m->ww - x; Err codevoid.de 70 it@@ -822,6 +913,7 @@ drawbars(void) { Err codevoid.de 70 i Err codevoid.de 70 i for(m = mons; m; m = m->next) Err codevoid.de 70 i drawbar(m); Err codevoid.de 70 i+ updatesystray(); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 it@@ -971,10 +1063,17 @@ getatomprop(Client *c, Atom prop) { Err codevoid.de 70 i unsigned long dl; Err codevoid.de 70 i unsigned char *p = NULL; Err codevoid.de 70 i Atom da, atom = None; Err codevoid.de 70 i+ /* FIXME getatomprop should return the number of items and a pointer to Err codevoid.de 70 i+ * the stored data instead of this workaround */ Err codevoid.de 70 i+ Atom req = XA_ATOM; Err codevoid.de 70 i+ if(prop == xatom[XembedInfo]) Err codevoid.de 70 i+ req = xatom[XembedInfo]; Err codevoid.de 70 i Err codevoid.de 70 i- if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, Err codevoid.de 70 i+ if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, Err codevoid.de 70 i &da, &di, &dl, &dl, &p) == Success && p) { Err codevoid.de 70 i atom = *(Atom *)p; Err codevoid.de 70 i+ if(da == xatom[XembedInfo] && dl == 2) Err codevoid.de 70 i+ atom = ((Atom *)p)[1]; Err codevoid.de 70 i XFree(p); Err codevoid.de 70 i } Err codevoid.de 70 i return atom; Err codevoid.de 70 it@@ -1016,6 +1115,15 @@ getstate(Window w) { Err codevoid.de 70 i return result; Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i+unsigned int Err codevoid.de 70 i+getsystraywidth() { Err codevoid.de 70 i+ unsigned int w = 0; Err codevoid.de 70 i+ Client *i; Err codevoid.de 70 i+ if(showsystray) Err codevoid.de 70 i+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; Err codevoid.de 70 i+ return w ? w + systrayspacing : 1; Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i Bool Err codevoid.de 70 i gettextprop(Window w, Atom atom, char *text, unsigned int size) { Err codevoid.de 70 i char **list = NULL; Err codevoid.de 70 it@@ -1150,7 +1258,7 @@ void Err codevoid.de 70 i killclient(const Arg *arg) { Err codevoid.de 70 i if(!selmon->sel) Err codevoid.de 70 i return; Err codevoid.de 70 i- if(!sendevent(selmon->sel, wmatom[WMDelete])) { Err codevoid.de 70 i+ if(!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { Err codevoid.de 70 i XGrabServer(dpy); Err codevoid.de 70 i XSetErrorHandler(xerrordummy); Err codevoid.de 70 i XSetCloseDownMode(dpy, DestroyAll); Err codevoid.de 70 it@@ -1238,6 +1346,12 @@ void Err codevoid.de 70 i maprequest(XEvent *e) { Err codevoid.de 70 i static XWindowAttributes wa; Err codevoid.de 70 i XMapRequestEvent *ev = &e->xmaprequest; Err codevoid.de 70 i+ Client *i; Err codevoid.de 70 i+ if((i = wintosystrayicon(ev->window))) { Err codevoid.de 70 i+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); Err codevoid.de 70 i+ resizebarwin(selmon); Err codevoid.de 70 i+ updatesystray(); Err codevoid.de 70 i+ } Err codevoid.de 70 i Err codevoid.de 70 i if(!XGetWindowAttributes(dpy, ev->window, &wa)) Err codevoid.de 70 i return; Err codevoid.de 70 it@@ -1351,6 +1465,16 @@ propertynotify(XEvent *e) { Err codevoid.de 70 i Window trans; Err codevoid.de 70 i XPropertyEvent *ev = &e->xproperty; Err codevoid.de 70 i Err codevoid.de 70 i+ if((c = wintosystrayicon(ev->window))) { Err codevoid.de 70 i+ if(ev->atom == XA_WM_NORMAL_HINTS) { Err codevoid.de 70 i+ updatesizehints(c); Err codevoid.de 70 i+ updatesystrayicongeom(c, c->w, c->h); Err codevoid.de 70 i+ } Err codevoid.de 70 i+ else Err codevoid.de 70 i+ updatesystrayiconstate(c, ev); Err codevoid.de 70 i+ resizebarwin(selmon); Err codevoid.de 70 i+ updatesystray(); Err codevoid.de 70 i+ } Err codevoid.de 70 i if((ev->window == root) && (ev->atom == XA_WM_NAME)) Err codevoid.de 70 i updatestatus(); Err codevoid.de 70 i else if(ev->state == PropertyDelete) Err codevoid.de 70 it@@ -1400,12 +1524,33 @@ recttomon(int x, int y, int w, int h) { Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i+removesystrayicon(Client *i) { Err codevoid.de 70 i+ Client **ii; Err codevoid.de 70 i+ Err codevoid.de 70 i+ if(!showsystray || !i) Err codevoid.de 70 i+ return; Err codevoid.de 70 i+ for(ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); Err codevoid.de 70 i+ if(ii) Err codevoid.de 70 i+ *ii = i->next; Err codevoid.de 70 i+ free(i); Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i+ Err codevoid.de 70 i+void Err codevoid.de 70 i resize(Client *c, int x, int y, int w, int h, Bool interact) { Err codevoid.de 70 i if(applysizehints(c, &x, &y, &w, &h, interact)) Err codevoid.de 70 i resizeclient(c, x, y, w, h); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i+resizebarwin(Monitor *m) { Err codevoid.de 70 i+ unsigned int w = m->ww; Err codevoid.de 70 i+ if(showsystray && m == selmon) Err codevoid.de 70 i+ w -= getsystraywidth(); Err codevoid.de 70 i+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i+void Err codevoid.de 70 i resizeclient(Client *c, int x, int y, int w, int h) { Err codevoid.de 70 i XWindowChanges wc; Err codevoid.de 70 i Err codevoid.de 70 it@@ -1470,6 +1615,18 @@ resizemouse(const Arg *arg) { Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i+resizerequest(XEvent *e) { Err codevoid.de 70 i+ XResizeRequestEvent *ev = &e->xresizerequest; Err codevoid.de 70 i+ Client *i; Err codevoid.de 70 i+ Err codevoid.de 70 i+ if((i = wintosystrayicon(ev->window))) { Err codevoid.de 70 i+ updatesystrayicongeom(i, ev->width, ev->height); Err codevoid.de 70 i+ resizebarwin(selmon); Err codevoid.de 70 i+ updatesystray(); Err codevoid.de 70 i+ } Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i+void Err codevoid.de 70 i restack(Monitor *m) { Err codevoid.de 70 i Client *c; Err codevoid.de 70 i XEvent ev; Err codevoid.de 70 it@@ -1553,25 +1710,35 @@ setclientstate(Client *c, long state) { Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i Bool Err codevoid.de 70 i-sendevent(Client *c, Atom proto) { Err codevoid.de 70 i+sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) { Err codevoid.de 70 i int n; Err codevoid.de 70 i- Atom *protocols; Err codevoid.de 70 i+ Atom *protocols, mt; Err codevoid.de 70 i Bool exists = False; Err codevoid.de 70 i XEvent ev; Err codevoid.de 70 i Err codevoid.de 70 i- if(XGetWMProtocols(dpy, c->win, &protocols, &n)) { Err codevoid.de 70 i- while(!exists && n--) Err codevoid.de 70 i- exists = protocols[n] == proto; Err codevoid.de 70 i- XFree(protocols); Err codevoid.de 70 i+ if(proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { Err codevoid.de 70 i+ mt = wmatom[WMProtocols]; Err codevoid.de 70 i+ if(XGetWMProtocols(dpy, w, &protocols, &n)) { Err codevoid.de 70 i+ while(!exists && n--) Err codevoid.de 70 i+ exists = protocols[n] == proto; Err codevoid.de 70 i+ XFree(protocols); Err codevoid.de 70 i+ } Err codevoid.de 70 i+ } Err codevoid.de 70 i+ else { Err codevoid.de 70 i+ exists = True; Err codevoid.de 70 i+ mt = proto; Err codevoid.de 70 i } Err codevoid.de 70 i if(exists) { Err codevoid.de 70 i ev.type = ClientMessage; Err codevoid.de 70 i- ev.xclient.window = c->win; Err codevoid.de 70 i- ev.xclient.message_type = wmatom[WMProtocols]; Err codevoid.de 70 i+ ev.xclient.window = w; Err codevoid.de 70 i+ ev.xclient.message_type = mt; Err codevoid.de 70 i ev.xclient.format = 32; Err codevoid.de 70 i- ev.xclient.data.l[0] = proto; Err codevoid.de 70 i- ev.xclient.data.l[1] = CurrentTime; Err codevoid.de 70 i- XSendEvent(dpy, c->win, False, NoEventMask, &ev); Err codevoid.de 70 i+ ev.xclient.data.l[0] = d0; Err codevoid.de 70 i+ ev.xclient.data.l[1] = d1; Err codevoid.de 70 i+ ev.xclient.data.l[2] = d2; Err codevoid.de 70 i+ ev.xclient.data.l[3] = d3; Err codevoid.de 70 i+ ev.xclient.data.l[4] = d4; Err codevoid.de 70 i+ XSendEvent(dpy, w, False, mask, &ev); Err codevoid.de 70 i } Err codevoid.de 70 i return exists; Err codevoid.de 70 i } Err codevoid.de 70 it@@ -1580,7 +1747,7 @@ void Err codevoid.de 70 i setfocus(Client *c) { Err codevoid.de 70 i if(!c->neverfocus) Err codevoid.de 70 i XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); Err codevoid.de 70 i- sendevent(c, wmatom[WMTakeFocus]); Err codevoid.de 70 i+ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 it@@ -1664,11 +1831,17 @@ setup(void) { Err codevoid.de 70 i wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); Err codevoid.de 70 i netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); Err codevoid.de 70 i netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); Err codevoid.de 70 i+ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); Err codevoid.de 70 i+ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); Err codevoid.de 70 i+ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); Err codevoid.de 70 i netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); Err codevoid.de 70 i netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); Err codevoid.de 70 i netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); Err codevoid.de 70 i netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); Err codevoid.de 70 i netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); Err codevoid.de 70 i+ xatom[Manager] = XInternAtom(dpy, "MANAGER", False); Err codevoid.de 70 i+ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); Err codevoid.de 70 i+ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); Err codevoid.de 70 i /* init cursors */ Err codevoid.de 70 i cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); Err codevoid.de 70 i cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); Err codevoid.de 70 it@@ -1687,6 +1860,8 @@ setup(void) { Err codevoid.de 70 i XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); Err codevoid.de 70 i if(!dc.font.set) Err codevoid.de 70 i XSetFont(dpy, dc.gc, dc.font.xfont->fid); Err codevoid.de 70 i+ /* init system tray */ Err codevoid.de 70 i+ updatesystray(); Err codevoid.de 70 i /* init bars */ Err codevoid.de 70 i updatebars(); Err codevoid.de 70 i updatestatus(); Err codevoid.de 70 it@@ -1820,7 +1995,18 @@ void Err codevoid.de 70 i togglebar(const Arg *arg) { Err codevoid.de 70 i selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; Err codevoid.de 70 i updatebarpos(selmon); Err codevoid.de 70 i- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); Err codevoid.de 70 i+ resizebarwin(selmon); Err codevoid.de 70 i+ if(showsystray) { Err codevoid.de 70 i+ XWindowChanges wc; Err codevoid.de 70 i+ if(!selmon->showbar) Err codevoid.de 70 i+ wc.y = -bh; Err codevoid.de 70 i+ else if(selmon->showbar) { Err codevoid.de 70 i+ wc.y = 0; Err codevoid.de 70 i+ if(!selmon->topbar) Err codevoid.de 70 i+ wc.y = selmon->mh - bh; Err codevoid.de 70 i+ } Err codevoid.de 70 i+ XConfigureWindow(dpy, systray->win, CWY, &wc); Err codevoid.de 70 i+ } Err codevoid.de 70 i arrange(selmon); Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 it@@ -1942,18 +2128,28 @@ unmapnotify(XEvent *e) { Err codevoid.de 70 i else Err codevoid.de 70 i unmanage(c, False); Err codevoid.de 70 i } Err codevoid.de 70 i+ else if((c = wintosystrayicon(ev->window))) { Err codevoid.de 70 i+ removesystrayicon(c); Err codevoid.de 70 i+ resizebarwin(selmon); Err codevoid.de 70 i+ updatesystray(); Err codevoid.de 70 i+ } Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i updatebars(void) { Err codevoid.de 70 i+ unsigned int w; Err codevoid.de 70 i Monitor *m; Err codevoid.de 70 i+ Err codevoid.de 70 i XSetWindowAttributes wa = { Err codevoid.de 70 i .override_redirect = True, Err codevoid.de 70 i .background_pixmap = ParentRelative, Err codevoid.de 70 i .event_mask = ButtonPressMask|ExposureMask Err codevoid.de 70 i }; Err codevoid.de 70 i for(m = mons; m; m = m->next) { Err codevoid.de 70 i- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), Err codevoid.de 70 i+ w = m->ww; Err codevoid.de 70 i+ if(showsystray && m == selmon) Err codevoid.de 70 i+ w -= getsystraywidth(); Err codevoid.de 70 i+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), Err codevoid.de 70 i CopyFromParent, DefaultVisual(dpy, screen), Err codevoid.de 70 i CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); Err codevoid.de 70 i XDefineCursor(dpy, m->barwin, cursor[CurNormal]); Err codevoid.de 70 it@@ -2164,6 +2360,107 @@ updatestatus(void) { Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i void Err codevoid.de 70 i+updatesystrayicongeom(Client *i, int w, int h) { Err codevoid.de 70 i+ if(i) { Err codevoid.de 70 i+ i->h = bh; Err codevoid.de 70 i+ if(w == h) Err codevoid.de 70 i+ i->w = bh; Err codevoid.de 70 i+ else if(h == bh) Err codevoid.de 70 i+ i->w = w; Err codevoid.de 70 i+ else Err codevoid.de 70 i+ i->w = (int) ((float)bh * ((float)w / (float)h)); Err codevoid.de 70 i+ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); Err codevoid.de 70 i+ /* force icons into the systray dimenons if they don't want to */ Err codevoid.de 70 i+ if(i->h > bh) { Err codevoid.de 70 i+ if(i->w == i->h) Err codevoid.de 70 i+ i->w = bh; Err codevoid.de 70 i+ else Err codevoid.de 70 i+ i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); Err codevoid.de 70 i+ i->h = bh; Err codevoid.de 70 i+ } Err codevoid.de 70 i+ } Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i+void Err codevoid.de 70 i+updatesystrayiconstate(Client *i, XPropertyEvent *ev) { Err codevoid.de 70 i+ long flags; Err codevoid.de 70 i+ int code = 0; Err codevoid.de 70 i+ Err codevoid.de 70 i+ if(!showsystray || !i || ev->atom != xatom[XembedInfo] || Err codevoid.de 70 i+ !(flags = getatomprop(i, xatom[XembedInfo]))) Err codevoid.de 70 i+ return; Err codevoid.de 70 i+ Err codevoid.de 70 i+ if(flags & XEMBED_MAPPED && !i->tags) { Err codevoid.de 70 i+ i->tags = 1; Err codevoid.de 70 i+ code = XEMBED_WINDOW_ACTIVATE; Err codevoid.de 70 i+ XMapRaised(dpy, i->win); Err codevoid.de 70 i+ setclientstate(i, NormalState); Err codevoid.de 70 i+ } Err codevoid.de 70 i+ else if(!(flags & XEMBED_MAPPED) && i->tags) { Err codevoid.de 70 i+ i->tags = 0; Err codevoid.de 70 i+ code = XEMBED_WINDOW_DEACTIVATE; Err codevoid.de 70 i+ XUnmapWindow(dpy, i->win); Err codevoid.de 70 i+ setclientstate(i, WithdrawnState); Err codevoid.de 70 i+ } Err codevoid.de 70 i+ else Err codevoid.de 70 i+ return; Err codevoid.de 70 i+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, Err codevoid.de 70 i+ systray->win, XEMBED_EMBEDDED_VERSION); Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i+void Err codevoid.de 70 i+updatesystray(void) { Err codevoid.de 70 i+ XSetWindowAttributes wa; Err codevoid.de 70 i+ Client *i; Err codevoid.de 70 i+ unsigned int x = selmon->mx + selmon->mw; Err codevoid.de 70 i+ unsigned int w = 1; Err codevoid.de 70 i+ Err codevoid.de 70 i+ if(!showsystray) Err codevoid.de 70 i+ return; Err codevoid.de 70 i+ if(!systray) { Err codevoid.de 70 i+ /* init systray */ Err codevoid.de 70 i+ if(!(systray = (Systray *)calloc(1, sizeof(Systray)))) Err codevoid.de 70 i+ die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); Err codevoid.de 70 i+ systray->win = XCreateSimpleWindow(dpy, root, x, selmon->by, w, bh, 0, 0, dc.sel[ColBG]); Err codevoid.de 70 i+ wa.event_mask = ButtonPressMask | ExposureMask; Err codevoid.de 70 i+ wa.override_redirect = True; Err codevoid.de 70 i+ wa.background_pixmap = ParentRelative; Err codevoid.de 70 i+ wa.background_pixel = dc.norm[ColBG]; Err codevoid.de 70 i+ XSelectInput(dpy, systray->win, SubstructureNotifyMask); Err codevoid.de 70 i+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, Err codevoid.de 70 i+ PropModeReplace, (unsigned char *)&systrayorientation, 1); Err codevoid.de 70 i+ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel|CWBackPixmap, &wa); Err codevoid.de 70 i+ XMapRaised(dpy, systray->win); Err codevoid.de 70 i+ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); Err codevoid.de 70 i+ if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { Err codevoid.de 70 i+ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); Err codevoid.de 70 i+ XSync(dpy, False); Err codevoid.de 70 i+ } Err codevoid.de 70 i+ else { Err codevoid.de 70 i+ fprintf(stderr, "dwm: unable to obtain system tray.\n"); Err codevoid.de 70 i+ free(systray); Err codevoid.de 70 i+ systray = NULL; Err codevoid.de 70 i+ return; Err codevoid.de 70 i+ } Err codevoid.de 70 i+ } Err codevoid.de 70 i+ for(w = 0, i = systray->icons; i; i = i->next) { Err codevoid.de 70 i+ XMapRaised(dpy, i->win); Err codevoid.de 70 i+ w += systrayspacing; Err codevoid.de 70 i+ XMoveResizeWindow(dpy, i->win, (i->x = w), 0, i->w, i->h); Err codevoid.de 70 i+ w += i->w; Err codevoid.de 70 i+ if(i->mon != selmon) Err codevoid.de 70 i+ i->mon = selmon; Err codevoid.de 70 i+ } Err codevoid.de 70 i+ w = w ? w + systrayspacing : 1; Err codevoid.de 70 i+ x -= w; Err codevoid.de 70 i+ XMoveResizeWindow(dpy, systray->win, x, selmon->by, w, bh); Err codevoid.de 70 i+ /* redraw background */ Err codevoid.de 70 i+ XSetForeground(dpy, dc.gc, dc.norm[ColBG]); Err codevoid.de 70 i+ XFillRectangle(dpy, systray->win, dc.gc, 0, 0, w, bh); Err codevoid.de 70 i+ XSync(dpy, False); Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i+void Err codevoid.de 70 i updatewindowtype(Client *c) { Err codevoid.de 70 i Atom state = getatomprop(c, netatom[NetWMState]); Err codevoid.de 70 i Atom wtype = getatomprop(c, netatom[NetWMWindowType]); Err codevoid.de 70 it@@ -2277,6 +2574,16 @@ wintomon(Window w) { Err codevoid.de 70 i return selmon; Err codevoid.de 70 i } Err codevoid.de 70 i Err codevoid.de 70 i+Client * Err codevoid.de 70 i+wintosystrayicon(Window w) { Err codevoid.de 70 i+ Client *i = NULL; Err codevoid.de 70 i+ Err codevoid.de 70 i+ if(!showsystray || !w) Err codevoid.de 70 i+ return i; Err codevoid.de 70 i+ for(i = systray->icons; i && i->win != w; i = i->next) ; Err codevoid.de 70 i+ return i; Err codevoid.de 70 i+} Err codevoid.de 70 i+ Err codevoid.de 70 i /* There's no way to check accesses to destroyed windows, thus those cases are Err codevoid.de 70 i * ignored (especially on UnmapNotify's). Other types of errors call Xlibs Err codevoid.de 70 i * default error handler, which may call exit. */ Err codevoid.de 70 .