[wiki] [sites] update systray patch || Jan Christoph Ebersbach
changeset: 917:250be0a2d354
tag: tip
user: Jan Christoph Ebersbach <jceb_AT_e-jc.de>
date: Fri Mar 30 23:05:20 2012 +0200
files: dwm.suckless.org/patches/dwm-6.0-systray.diff dwm.suckless.org/patches/systray.md
description:
update systray patch
diff -r 7e9e1b16481c -r 250be0a2d354 dwm.suckless.org/patches/dwm-6.0-systray.diff
--- a/dwm.suckless.org/patches/dwm-6.0-systray.diff Mon Mar 26 19:29:51 2012 +0200
+++ b/dwm.suckless.org/patches/dwm-6.0-systray.diff Fri Mar 30 23:05:20 2012 +0200
_AT_@ -4,7 +4,7 @@
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
_AT_@ -10,6 +10,8 @@
static const char selfgcolor[] = "#eeeeee";
static const unsigned int borderpx = 1; /* border pixel of windows */
_AT_@ -16,47 +16,59 @@
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
-_AT_@ -55,12 +55,15 @@
++++ b/dwm.c Fri Mar 30 23:01:12 2012 +0200
+_AT_@ -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 */
-_AT_@ -154,6 +157,19 @@
+_AT_@ -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);
-_AT_@ -189,6 +205,7 @@
+_AT_@ -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);
_AT_@ -64,28 +76,38 @@
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, Bool focused);
static void grabkeys(void);
-_AT_@ -207,7 +224,9 @@
+_AT_@ -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);
-_AT_@ -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);
+_AT_@ -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);
_AT_@ -97,45 +119,74 @@
static const char broken[] = "broken";
static char stext[256];
static int screen;
-_AT_@ -530,9 +553,37 @@
+_AT_@ -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;
+_AT_@ -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);
+ }
+_AT_@ -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]) {
-_AT_@ -583,7 +634,7 @@
+_AT_@ -583,7 +657,7 @@
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
updatebars();
for(m = mons; m; m = m->next)
_AT_@ -144,23 +195,19 @@
focus(NULL);
arrange(NULL);
}
-_AT_@ -663,10 +714,15 @@
- void
- destroynotify(XEvent *e) {
- Client *c;
-+ SystrayIcon *i;
- XDestroyWindowEvent *ev = &e->xdestroywindow;
+_AT_@ -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
-_AT_@ -722,6 +778,7 @@
+_AT_@ -722,6 +801,7 @@
unsigned long *col;
Client *c;
_AT_@ -168,7 +215,7 @@
for(c = m->clients; c; c = c->next) {
occ |= c->tags;
if(c->isurgent)
-_AT_@ -743,6 +800,9 @@
+_AT_@ -743,6 +823,9 @@
if(m == selmon) { /* status is only drawn on selected monitor */
dc.w = TEXTW(stext);
dc.x = m->ww - dc.w;
_AT_@ -178,66 +225,68 @@
if(dc.x < x) {
dc.x = x;
dc.w = m->ww - x;
-_AT_@ -862,6 +922,7 @@
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- selmon->sel = c;
- drawbars();
-+ updatesystray();
- }
-
- void
-_AT_@ -962,6 +1023,14 @@
+_AT_@ -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;
-_AT_@ -1180,6 +1249,10 @@
+_AT_@ -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);
+_AT_@ -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;
-_AT_@ -1291,9 +1364,14 @@
- void
- propertynotify(XEvent *e) {
- Client *c;
-+ SystrayIcon *i;
+_AT_@ -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)
-_AT_@ -1343,12 +1421,32 @@
+_AT_@ -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);
+}
+
_AT_@ -260,7 +309,83 @@
resizeclient(Client *c, int x, int y, int w, int h) {
XWindowChanges wc;
-_AT_@ -1603,6 +1701,9 @@
+_AT_@ -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;
+_AT_@ -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;
+ }
+_AT_@ -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
+_AT_@ -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);
_AT_@ -270,7 +395,15 @@
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);
-_AT_@ -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);
+_AT_@ -1624,6 +1777,8 @@
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
if(!dc.font.set)
XSetFont(dpy, dc.gc, dc.font.xfont->fid);
_AT_@ -279,7 +412,7 @@
/* init bars */
updatebars();
updatestatus();
-_AT_@ -1732,8 +1835,18 @@
+_AT_@ -1732,8 +1887,18 @@
togglebar(const Arg *arg) {
selmon->showbar = !selmon->showbar;
updatebarpos(selmon);
_AT_@ -299,22 +432,15 @@
}
void
-_AT_@ -1809,6 +1922,7 @@
- void
- unmapnotify(XEvent *e) {
- Client *c;
-+ SystrayIcon *i;
- XUnmapEvent *ev = &e->xunmap;
-
- if((c = wintoclient(ev->window))) {
-_AT_@ -1816,12 +1930,17 @@
- setclientstate(c, WithdrawnState);
+_AT_@ -1817,11 +1982,18 @@
else
unmanage(c, False);
-+ } else if((i = wintosystrayicon(ev->window))) {
-+ removesystrayicon(i);
+ }
++ else if((c = wintosystrayicon(ev->window))) {
++ removesystrayicon(c);
++ resizebarwin(selmon);
+ updatesystray();
- }
++ }
}
void
_AT_@ -325,7 +451,7 @@
XSetWindowAttributes wa = {
.override_redirect = True,
.background_pixmap = ParentRelative,
-_AT_@ -1830,7 +1949,10 @@
+_AT_@ -1830,7 +2002,10 @@
for(m = mons; m; m = m->next) {
if (m->barwin)
continue;
_AT_@ -337,14 +463,50 @@
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]);
-_AT_@ -2014,6 +2136,59 @@
+_AT_@ -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;
+
_AT_@ -359,35 +521,28 @@
+ 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)
++ 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");
-+ 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);
-+ XSync(dpy, False);
++ 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);
_AT_@ -397,15 +552,15 @@
updatewindowtype(Client *c) {
Atom state = getatomprop(c, netatom[NetWMState]);
Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
-_AT_@ -2083,6 +2258,16 @@
+_AT_@ -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 -r 7e9e1b16481c -r 250be0a2d354 dwm.suckless.org/patches/systray.md
--- a/dwm.suckless.org/patches/systray.md Mon Mar 26 19:29:51 2012 +0200
+++ b/dwm.suckless.org/patches/systray.md Fri Mar 30 23:05:20 2012 +0200
_AT_@ -8,7 +8,7 @@
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
------
Received on Fri Mar 30 2012 - 23:05:22 CEST
This archive was generated by hypermail 2.3.0
: Thu Sep 13 2012 - 19:32:22 CEST