sites

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 16628dfd244df10e8bd6d3c118a08d75c4f33bab
parent a75adf2ec6731c4675e08cd884096ff3034ed962
Author: Jan Christoph Ebersbach <jceb@e-jc.de>
Date:   Fri, 30 Mar 2012 23:05:20 +0200

update systray patch
Diffstat:
Mdwm.suckless.org/patches/dwm-6.0-systray.diff | 403+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mdwm.suckless.org/patches/systray.md | 2+-
2 files changed, 280 insertions(+), 125 deletions(-)

diff --git a/dwm.suckless.org/patches/dwm-6.0-systray.diff b/dwm.suckless.org/patches/dwm-6.0-systray.diff @@ -4,7 +4,7 @@ Implements a system tray for dwm. diff -r ad90e7fab364 config.def.h --- a/config.def.h Fri Feb 10 00:36:08 2012 +0000 -+++ b/config.def.h Sun Mar 25 11:43:07 2012 +0200 ++++ b/config.def.h Fri Mar 30 23:01:12 2012 +0200 @@ -10,6 +10,8 @@ static const char selfgcolor[] = "#eeeeee"; static const unsigned int borderpx = 1; /* border pixel of windows */ @@ -16,47 +16,59 @@ diff -r ad90e7fab364 config.def.h diff -r ad90e7fab364 dwm.c --- a/dwm.c Fri Feb 10 00:36:08 2012 +0000 -+++ b/dwm.c Sun Mar 25 11:43:07 2012 +0200 -@@ -55,12 +55,15 @@ ++++ b/dwm.c Fri Mar 30 23:01:12 2012 +0200 +@@ -55,12 +55,30 @@ #define TAGMASK ((1 << LENGTH(tags)) - 1) #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) +#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 + ++/* XEMBED messages */ ++#define XEMBED_EMBEDDED_NOTIFY 0 ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_FOCUS_IN 4 ++#define XEMBED_MODALITY_ON 10 ++ ++#define XEMBED_MAPPED (1 << 0) ++#define XEMBED_WINDOW_ACTIVATE 1 ++#define XEMBED_WINDOW_DEACTIVATE 2 ++ ++#define VERSION_MAJOR 0 ++#define VERSION_MINOR 0 ++#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR ++ /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ -enum { NetSupported, NetWMName, NetWMState, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ -+enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, -+ NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, -+ NetWMWindowType, NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ ++enum { NetSupported, NetSystemTray, NetSystemTrayOP, ++ NetSystemTrayOrientation, NetWMName, NetWMState, NetWMFullscreen, ++ NetActiveWindow, NetWMWindowType, NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */ ++enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ -@@ -154,6 +157,19 @@ +@@ -154,6 +172,12 @@ int monitor; } Rule; -+typedef struct SystrayIcon SystrayIcon; -+struct SystrayIcon { -+ Window win; -+ XRectangle geo; -+ SystrayIcon *next; -+}; -+ +typedef struct Systray Systray; +struct Systray { + Window win; -+ SystrayIcon *icons; ++ Client *icons; +}; + /* function declarations */ static void applyrules(Client *c); static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); -@@ -189,6 +205,7 @@ +@@ -186,9 +210,11 @@ + static void focusin(XEvent *e); + static void focusmon(const Arg *arg); + static void focusstack(const Arg *arg); ++static Atom getatomprop(Client *c, Atom prop); static unsigned long getcolor(const char *colstr); static Bool getrootptr(int *x, int *y); static long getstate(Window w); @@ -64,28 +76,38 @@ diff -r ad90e7fab364 dwm.c static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); static void grabbuttons(Client *c, Bool focused); static void grabkeys(void); -@@ -207,7 +224,9 @@ +@@ -207,13 +233,16 @@ static void propertynotify(XEvent *e); static void quit(const Arg *arg); static Monitor *recttomon(int x, int y, int w, int h); -+static void removesystrayicon(SystrayIcon *i); ++static void removesystrayicon(Client *i); static void resize(Client *c, int x, int y, int w, int h, Bool interact); +static void resizebarwin(Monitor *m); static void resizeclient(Client *c, int x, int y, int w, int h); static void resizemouse(const Arg *arg); ++static void resizerequest(XEvent *e); static void restack(Monitor *m); -@@ -241,18 +260,22 @@ + static void run(void); + static void scan(void); +-static Bool sendevent(Client *c, Atom proto); ++static Bool sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); + static void sendmon(Client *c, Monitor *m); + static void setclientstate(Client *c, long state); + static void setfocus(Client *c); +@@ -241,18 +270,24 @@ static void updatenumlockmask(void); static void updatesizehints(Client *c); static void updatestatus(void); -+static void updatesystray(); ++static void updatesystray(void); ++static void updatesystrayicongeom(Client *i, int w, int h); ++static void updatesystrayiconstate(Client *i); static void updatewindowtype(Client *c); static void updatetitle(Client *c); static void updatewmhints(Client *c); static void view(const Arg *arg); static Client *wintoclient(Window w); static Monitor *wintomon(Window w); -+static SystrayIcon *wintosystrayicon(Window w); ++static Client *wintosystrayicon(Window w); static int xerror(Display *dpy, XErrorEvent *ee); static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); @@ -97,45 +119,74 @@ diff -r ad90e7fab364 dwm.c static const char broken[] = "broken"; static char stext[256]; static int screen; -@@ -530,9 +553,37 @@ +@@ -274,9 +309,10 @@ + [MapRequest] = maprequest, + [MotionNotify] = motionnotify, + [PropertyNotify] = propertynotify, ++ [ResizeRequest] = resizerequest, + [UnmapNotify] = unmapnotify + }; +-static Atom wmatom[WMLast], netatom[NetLast]; ++static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; + static Bool running = True; + static Cursor cursor[CurLast]; + static Display *dpy; +@@ -497,6 +533,10 @@ + XFreeCursor(dpy, cursor[CurMove]); + while(mons) + cleanupmon(mons); ++ if(showsystray) { ++ XUnmapWindow(dpy, systray->win); ++ XDestroyWindow(dpy, systray->win); ++ } + XSync(dpy, False); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); + } +@@ -530,9 +570,43 @@ void clientmessage(XEvent *e) { -+ XWindowAttributes *wa; ++ XWindowAttributes wa; XClientMessageEvent *cme = &e->xclient; Client *c = wintoclient(cme->window); -+ SystrayIcon *i; -+ /* add systray icons */ -+ if(cme->message_type == netatom[NetSystemTrayOP]) { ++ if(showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { ++ /* add systray icons */ + if(cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { -+ if(!(i = (SystrayIcon *)calloc(1, sizeof(SystrayIcon)))) -+ die("fatal: could not malloc() %u bytes\n", sizeof(SystrayIcon)); -+ if(!(wa = (XWindowAttributes *)calloc(1, sizeof(XWindowAttributes)))) -+ die("fatal: could not malloc() %u bytes\n", sizeof(XWindowAttributes)); -+ i->win = cme->data.l[2]; -+ i->next = systray->icons; -+ systray->icons = i; -+ /* deal with tray icons that have rectangle proportions */ -+ XGetWindowAttributes(dpy, i->win, wa); -+ i->geo.height = bh; -+ if(wa->width == wa->height) -+ i->geo.width = bh; -+ else -+ i->geo.width = (int) (bh * (wa->width / wa->height)); -+ XAddToSaveSet(dpy, i->win); -+ XSelectInput(dpy, i->win, StructureNotifyMask | ResizeRedirectMask -+ | PointerMotionMask | PointerMotionHintMask -+ | PropertyChangeMask| EnterWindowMask | FocusChangeMask); -+ XReparentWindow(dpy, i->win, systray->win, 0, 0); -+ XMapRaised(dpy, i->win); ++ if(!(c = (Client *)calloc(1, sizeof(Client)))) ++ die("fatal: could not malloc() %u bytes\n", sizeof(Client)); ++ c->win = cme->data.l[2]; ++ c->mon = selmon; ++ c->next = systray->icons; ++ systray->icons = c; ++ XGetWindowAttributes(dpy, c->win, &wa); ++ c->x = c->oldx = wa.x; ++ c->y = c->oldy = wa.y; ++ c->w = c->oldw = wa.width; ++ c->h = c->oldh = wa.height; ++ c->oldbw = wa.border_width; ++ c->bw = 0; ++ c->isfloating = False; ++ updatesizehints(c); ++ updatesystrayicongeom(c, wa.width, wa.height); ++ applysizehints(c, &(c->x), &(c->y), &(c->w), &(c->h), False); ++ XAddToSaveSet(dpy, c->win); ++ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); ++ XReparentWindow(dpy, c->win, systray->win, 0, 0); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); ++ resizebarwin(selmon); + updatesystray(); ++ setclientstate(c, NormalState); + } ++ return; + } if(!c) return; if(cme->message_type == netatom[NetWMState]) { -@@ -583,7 +634,7 @@ +@@ -583,7 +657,7 @@ dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); updatebars(); for(m = mons; m; m = m->next) @@ -144,23 +195,19 @@ diff -r ad90e7fab364 dwm.c focus(NULL); arrange(NULL); } -@@ -663,10 +714,15 @@ - void - destroynotify(XEvent *e) { - Client *c; -+ SystrayIcon *i; - XDestroyWindowEvent *ev = &e->xdestroywindow; +@@ -667,6 +741,11 @@ if((c = wintoclient(ev->window))) unmanage(c, True); -+ else if((i = wintosystrayicon(ev->window))) { -+ removesystrayicon(i); ++ else if((c = wintosystrayicon(ev->window))) { ++ removesystrayicon(c); ++ resizebarwin(selmon); + updatesystray(); + } } void -@@ -722,6 +778,7 @@ +@@ -722,6 +801,7 @@ unsigned long *col; Client *c; @@ -168,7 +215,7 @@ diff -r ad90e7fab364 dwm.c for(c = m->clients; c; c = c->next) { occ |= c->tags; if(c->isurgent) -@@ -743,6 +800,9 @@ +@@ -743,6 +823,9 @@ if(m == selmon) { /* status is only drawn on selected monitor */ dc.w = TEXTW(stext); dc.x = m->ww - dc.w; @@ -178,66 +225,68 @@ diff -r ad90e7fab364 dwm.c if(dc.x < x) { dc.x = x; dc.w = m->ww - x; -@@ -862,6 +922,7 @@ - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - selmon->sel = c; - drawbars(); -+ updatesystray(); - } - - void -@@ -962,6 +1023,14 @@ +@@ -962,6 +1045,15 @@ return result; } +unsigned int +getsystraywidth() { + unsigned int w = 0; -+ SystrayIcon *i; -+ for(i = systray->icons; i; w += i->geo.width + systrayspacing, i = i->next) ; ++ Client *i; ++ if(showsystray) ++ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; + return w; +} + Bool gettextprop(Window w, Atom atom, char *text, unsigned int size) { char **list = NULL; -@@ -1180,6 +1249,10 @@ +@@ -1096,7 +1188,7 @@ + killclient(const Arg *arg) { + if(!selmon->sel) + return; +- if(!sendevent(selmon->sel, wmatom[WMDelete])) { ++ if(!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); +@@ -1180,6 +1272,12 @@ maprequest(XEvent *e) { static XWindowAttributes wa; XMapRequestEvent *ev = &e->xmaprequest; -+ SystrayIcon *i; ++ Client *i; + if((i = wintosystrayicon(ev->window))) { ++ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); ++ resizebarwin(selmon); + updatesystray(); + } if(!XGetWindowAttributes(dpy, ev->window, &wa)) return; -@@ -1291,9 +1364,14 @@ - void - propertynotify(XEvent *e) { - Client *c; -+ SystrayIcon *i; +@@ -1294,6 +1392,11 @@ Window trans; XPropertyEvent *ev = &e->xproperty; -+ if((i = wintosystrayicon(ev->window))) { -+ /* TODO include XEMBED functionality from systray_state */ ++ if((c = wintosystrayicon(ev->window))) { ++ updatesystrayiconstate(c); ++ resizebarwin(selmon); + updatesystray(); + } if((ev->window == root) && (ev->atom == XA_WM_NAME)) updatestatus(); else if(ev->state == PropertyDelete) -@@ -1343,12 +1421,32 @@ +@@ -1343,12 +1446,33 @@ } void -+removesystrayicon(SystrayIcon *i) { -+ SystrayIcon **ii; ++removesystrayicon(Client *i) { ++ Client **ii; + -+ if(!i || !showsystray) ++ if(!showsystray || !i) + return; + for(ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); -+ *ii = i->next; ++ if(ii) ++ *ii = i->next; + free(i); +} + @@ -260,7 +309,83 @@ diff -r ad90e7fab364 dwm.c resizeclient(Client *c, int x, int y, int w, int h) { XWindowChanges wc; -@@ -1603,6 +1701,9 @@ +@@ -1413,6 +1537,19 @@ + } + + void ++resizerequest(XEvent *e) { ++ XResizeRequestEvent *ev = &e->xresizerequest; ++ Client *i; ++ ++ if((i = wintosystrayicon(ev->window))) { ++ updatesystrayicongeom(i, ev->width, ev->height); ++ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); ++ resizebarwin(selmon); ++ updatesystray(); ++ } ++} ++ ++void + restack(Monitor *m) { + Client *c; + XEvent ev; +@@ -1496,25 +1633,35 @@ + } + + Bool +-sendevent(Client *c, Atom proto) { ++sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) { + int n; +- Atom *protocols; ++ Atom *protocols, mt; + Bool exists = False; + XEvent ev; + +- if(XGetWMProtocols(dpy, c->win, &protocols, &n)) { +- while(!exists && n--) +- exists = protocols[n] == proto; +- XFree(protocols); ++ if(proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { ++ mt = wmatom[WMProtocols]; ++ if(XGetWMProtocols(dpy, w, &protocols, &n)) { ++ while(!exists && n--) ++ exists = protocols[n] == proto; ++ XFree(protocols); ++ } ++ } ++ else { ++ exists = True; ++ mt = proto; + } + if(exists) { + ev.type = ClientMessage; +- ev.xclient.window = c->win; +- ev.xclient.message_type = wmatom[WMProtocols]; ++ ev.xclient.window = w; ++ ev.xclient.message_type = mt; + ev.xclient.format = 32; +- ev.xclient.data.l[0] = proto; +- ev.xclient.data.l[1] = CurrentTime; +- XSendEvent(dpy, c->win, False, NoEventMask, &ev); ++ ev.xclient.data.l[0] = d0; ++ ev.xclient.data.l[1] = d1; ++ ev.xclient.data.l[2] = d2; ++ ev.xclient.data.l[3] = d3; ++ ev.xclient.data.l[4] = d4; ++ XSendEvent(dpy, w, False, mask, &ev); + } + return exists; + } +@@ -1523,7 +1670,7 @@ + setfocus(Client *c) { + if(!c->neverfocus) + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); +- sendevent(c, wmatom[WMTakeFocus]); ++ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); + } + + void +@@ -1603,11 +1750,17 @@ wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); @@ -270,7 +395,15 @@ diff -r ad90e7fab364 dwm.c netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); -@@ -1624,6 +1725,8 @@ + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); ++ xatom[Manager] = XInternAtom(dpy, "MANAGER", False); ++ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); ++ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); + /* init cursors */ + cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); + cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); +@@ -1624,6 +1777,8 @@ XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); @@ -279,7 +412,7 @@ diff -r ad90e7fab364 dwm.c /* init bars */ updatebars(); updatestatus(); -@@ -1732,8 +1835,18 @@ +@@ -1732,8 +1887,18 @@ togglebar(const Arg *arg) { selmon->showbar = !selmon->showbar; updatebarpos(selmon); @@ -299,22 +432,15 @@ diff -r ad90e7fab364 dwm.c } void -@@ -1809,6 +1922,7 @@ - void - unmapnotify(XEvent *e) { - Client *c; -+ SystrayIcon *i; - XUnmapEvent *ev = &e->xunmap; - - if((c = wintoclient(ev->window))) { -@@ -1816,12 +1930,17 @@ - setclientstate(c, WithdrawnState); +@@ -1817,11 +1982,18 @@ else unmanage(c, False); -+ } else if((i = wintosystrayicon(ev->window))) { -+ removesystrayicon(i); -+ updatesystray(); } ++ else if((c = wintosystrayicon(ev->window))) { ++ removesystrayicon(c); ++ resizebarwin(selmon); ++ updatesystray(); ++ } } void @@ -325,7 +451,7 @@ diff -r ad90e7fab364 dwm.c XSetWindowAttributes wa = { .override_redirect = True, .background_pixmap = ParentRelative, -@@ -1830,7 +1949,10 @@ +@@ -1830,7 +2002,10 @@ for(m = mons; m; m = m->next) { if (m->barwin) continue; @@ -337,14 +463,50 @@ diff -r ad90e7fab364 dwm.c CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); XDefineCursor(dpy, m->barwin, cursor[CurNormal]); -@@ -2014,6 +2136,59 @@ +@@ -2014,6 +2189,88 @@ } void ++updatesystrayicongeom(Client *i, int w, int h) { ++ if(i) { ++ /* deal with tray icons that have rectangle proportions */ ++ i->h = bh; ++ if(w == h) ++ i->w = bh; ++ else if(h == bh) ++ i->w = w; ++ else ++ i->w = (int) ((float)bh * ((float)w / (float)h)); ++ } ++} ++ ++void ++updatesystrayiconstate(Client *i) { ++ long flags; ++ int code = 0; ++ ++ if(!showsystray || !i || !(flags = getatomprop(i, xatom[XembedInfo]))) ++ return; ++ /* somehow this doesn't work at all, the clients get unmapped */ ++ return; ++ ++ if(flags & XEMBED_MAPPED) { ++ code = XEMBED_WINDOW_ACTIVATE; ++ XMapRaised(dpy, i->win); ++ setclientstate(i, NormalState); ++ } ++ else { ++ code = XEMBED_WINDOW_DEACTIVATE; ++ XUnmapWindow(dpy, i->win); ++ setclientstate(i, WithdrawnState); ++ } ++ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, systray->win, XEMBED_EMBEDDED_VERSION); ++} ++ ++void +updatesystray(void) { + XSetWindowAttributes wa; -+ XEvent event; -+ SystrayIcon *i; ++ Client *i; + unsigned int x = selmon->mx + selmon->mw; + unsigned int w = 1; + @@ -359,35 +521,28 @@ diff -r ad90e7fab364 dwm.c + wa.override_redirect = True; + wa.background_pixmap = ParentRelative; + wa.background_pixel = dc.norm[ColBG]; -+ XSelectInput(dpy, systray->win, SubstructureNotifyMask | SubstructureRedirectMask -+ | PointerMotionMask | PointerMotionHintMask | KeyPressMask | ButtonPressMask); ++ XSelectInput(dpy, systray->win, SubstructureNotifyMask); + XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&systrayorientation, 1); + XChangeWindowAttributes(dpy, systray->win, CWEventMask | CWOverrideRedirect | CWBackPixel, &wa); + memset(&wa, 0, sizeof(XWindowAttributes)); + XMapRaised(dpy, systray->win); + XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); -+ if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) != systray->win) -+ fprintf(stderr, "dwm: unable to obtain system tray.\n"); -+ else { -+ memset(&event, 0, sizeof(event)); -+ event.xclient.type = ClientMessage; -+ event.xclient.window = root; -+ event.xclient.message_type = XInternAtom(dpy, "MANAGER", False); -+ event.xclient.format = 32; -+ event.xclient.data.l[0] = CurrentTime; -+ event.xclient.data.l[1] = netatom[NetSystemTray]; -+ event.xclient.data.l[2] = systray->win; -+ event.xclient.data.l[3] = 0; -+ event.xclient.data.l[4] = 0; -+ XSendEvent(dpy, root, False, StructureNotifyMask, &event); ++ if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { ++ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); + XSync(dpy, False); + } ++ else { ++ fprintf(stderr, "dwm: unable to obtain system tray.\n"); ++ free(systray); ++ systray = NULL; ++ return; ++ } + } + for(i = systray->icons; i; i = i->next) { + XMapWindow(dpy, i->win); -+ XMoveResizeWindow(dpy, i->win, (i->geo.x = w), 0, i->geo.width, i->geo.height); -+ w += i->geo.width + systrayspacing; ++ XMoveResizeWindow(dpy, i->win, (i->x = w), 0, i->w, i->h); ++ w += i->w + systrayspacing; + } + x -= w; + XMoveResizeWindow(dpy, systray->win, x, selmon->by, w, bh); @@ -397,15 +552,15 @@ diff -r ad90e7fab364 dwm.c updatewindowtype(Client *c) { Atom state = getatomprop(c, netatom[NetWMState]); Atom wtype = getatomprop(c, netatom[NetWMWindowType]); -@@ -2083,6 +2258,16 @@ +@@ -2083,6 +2340,16 @@ return selmon; } -+SystrayIcon * ++Client * +wintosystrayicon(Window w) { -+ SystrayIcon *i = NULL; ++ Client *i = NULL; + -+ if(!w) ++ if(!showsystray || !w) + return i; + for(i = systray->icons; i && i->win != w; i = i->next) ; + return i; diff --git a/dwm.suckless.org/patches/systray.md b/dwm.suckless.org/patches/systray.md @@ -8,7 +8,7 @@ is following the selected monitor. Download -------- -* [dwm-6.0-systray.diff](dwm-6.0-systray.diff) (14K) (20120325) +* [dwm-6.0-systray.diff](dwm-6.0-systray.diff) (18K) (20120330) Author ------