[wiki] [sites] update systray patch || Jan Christoph Ebersbach

From: <hg_AT_suckless.org>
Date: Fri, 30 Mar 2012 23:05:22 +0200 (CEST)

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