sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 9e82ccbdad77a6142b5c5ccfddc4070bee1a013b
parent 33754b0fe3da51279608807acb1866822d665b7c
Author: Jan Christoph Ebersbach <jceb@e-jc.de>
Date:   Sun,  9 Feb 2014 20:39:56 +0100

update systray patch

Diffstat:
Mdwm.suckless.org/patches/dwm-6.1-systray.diff | 211+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mdwm.suckless.org/patches/systray.md | 4++--
2 files changed, 129 insertions(+), 86 deletions(-)

diff --git a/dwm.suckless.org/patches/dwm-6.1-systray.diff b/dwm.suckless.org/patches/dwm-6.1-systray.diff @@ -1,28 +1,34 @@ -Author: Branislav Blaskovic <branislav@blaskovic.sk>, rewrited patch from Jan Christoph Ebersbach <jceb@e-jc.de> for DWM 6.1 +Author: Jan Christoph Ebersbach <jceb@e-jc.de>, inspired by http://code.google.com/p/dwm-plus URL: http://dwm.suckless.org/patches/systray Implements a system tray for dwm. -diff --git a/config.def.h b/../dwm-suckless/config.def.h -index d300687..9da950f 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -10,6 +10,8 @@ static const char selbgcolor[] = "#005577"; +Contributors: +- Carlos Pita, thanks for investigating multi monitor issues and sending in a + patch + +Index: dwm/config.def.h +=================================================================== +--- dwm/config.def.h.orig 2014-02-09 15:24:27.348117387 +0100 ++++ dwm/config.def.h 2014-02-09 15:24:27.340117386 +0100 +@@ -10,6 +10,10 @@ static const char selfgcolor[] = "#eeeeee"; static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ ++static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ +static const unsigned int systrayspacing = 2; /* systray spacing */ ++static const Bool systraypinningfailfirst = True; /* True: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ +static const Bool showsystray = True; /* False means no systray */ static const Bool showbar = True; /* False means no bar */ static const Bool topbar = True; /* False means bottom bar */ - -diff --git a/dwm.c b/../dwm-suckless/dwm.c -index 314adf4..24a0113 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -55,13 +55,30 @@ - #define HEIGHT(X) ((X)->h + 2 * (X)->bw) + +Index: dwm/dwm.c +=================================================================== +--- dwm/dwm.c.orig 2014-02-09 15:24:27.348117387 +0100 ++++ dwm/dwm.c 2014-02-09 15:24:27.340117386 +0100 +@@ -56,12 +56,30 @@ #define TAGMASK ((1 << LENGTH(tags)) - 1) #define TEXTW(X) (drw_font_getexts_width(drw->font, X, strlen(X)) + drw->font->h) + +#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 + @@ -39,19 +45,21 @@ index 314adf4..24a0113 100644 +#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 { SchemeNorm, SchemeSel, SchemeLast }; /* color schemes */ -enum { NetSupported, NetWMName, NetWMState, -+enum { NetSupported, NetWMName, NetWMState, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ +- NetWMFullscreen, NetActiveWindow, NetWMWindowType, +- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ ++enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, ++ NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, NetWMWindowType, ++ NetWMWindowTypeDialog, NetClientList, 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 */ -@@ -140,6 +157,12 @@ typedef struct { +@@ -140,6 +158,12 @@ int monitor; } Rule; @@ -64,7 +72,7 @@ index 314adf4..24a0113 100644 /* function declarations */ static void applyrules(Client *c); static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); -@@ -169,8 +192,10 @@ static void focus(Client *c); +@@ -169,8 +193,10 @@ static void focusin(XEvent *e); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); @@ -75,7 +83,7 @@ index 314adf4..24a0113 100644 static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); static void grabbuttons(Client *c, Bool focused); static void grabkeys(void); -@@ -188,13 +213,16 @@ static void pop(Client *); +@@ -188,13 +214,15 @@ static void propertynotify(XEvent *e); static void quit(const Arg *arg); static Monitor *recttomon(int x, int y, int w, int h); @@ -84,7 +92,6 @@ index 314adf4..24a0113 100644 +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); static void run(void); static void scan(void); @@ -93,7 +100,15 @@ index 314adf4..24a0113 100644 static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); static void setfocus(Client *c); -@@ -222,18 +250,24 @@ static void updateclientlist(void); +@@ -205,6 +233,7 @@ + static void showhide(Client *c); + static void sigchld(int unused); + static void spawn(const Arg *arg); ++static Monitor *systraytomon(Monitor *m); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); + static void tile(Monitor *); +@@ -222,18 +251,24 @@ static void updatenumlockmask(void); static void updatesizehints(Client *c); static void updatestatus(void); @@ -118,11 +133,8 @@ index 314adf4..24a0113 100644 static const char broken[] = "broken"; static char stext[256]; static int screen; -@@ -255,9 +289,10 @@ static void (*handler[LASTEvent]) (XEvent *) = { - [MapRequest] = maprequest, - [MotionNotify] = motionnotify, +@@ -257,7 +292,7 @@ [PropertyNotify] = propertynotify, -+ [ResizeRequest] = resizerequest, [UnmapNotify] = unmapnotify }; -static Atom wmatom[WMLast], netatom[NetLast]; @@ -130,7 +142,7 @@ index 314adf4..24a0113 100644 static Bool running = True; static Cur *cursor[CurLast]; static ClrScheme scheme[SchemeLast]; -@@ -471,6 +506,11 @@ cleanup(void) { +@@ -471,6 +506,11 @@ XUngrabKey(dpy, AnyKey, AnyModifier, root); while(mons) cleanupmon(mons); @@ -142,7 +154,7 @@ index 314adf4..24a0113 100644 drw_cur_free(drw, cursor[CurNormal]); drw_cur_free(drw, cursor[CurResize]); drw_cur_free(drw, cursor[CurMove]); -@@ -516,9 +556,49 @@ clearurgent(Client *c) { +@@ -516,9 +556,49 @@ void clientmessage(XEvent *e) { @@ -174,15 +186,15 @@ index 314adf4..24a0113 100644 + XAddToSaveSet(dpy, c->win); + XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); + XReparentWindow(dpy, c->win, systray->win, 0, 0); -+ /* use parents background pixmap */ -+ swa.background_pixmap = ParentRelative; ++ /* use parents background color */ + swa.background_pixel = scheme[SchemeNorm].bg->rgb; -+ XChangeWindowAttributes(dpy, c->win, CWBackPixmap|CWBackPixel, &swa); ++ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); + /* FIXME not sure if I have to send these events, too */ + 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); ++ XSync(dpy, False); + resizebarwin(selmon); + updatesystray(); + setclientstate(c, NormalState); @@ -192,7 +204,7 @@ index 314adf4..24a0113 100644 if(!c) return; if(cme->message_type == netatom[NetWMState]) { -@@ -568,7 +648,7 @@ configurenotify(XEvent *e) { +@@ -568,7 +648,7 @@ drw_resize(drw, sw, bh); updatebars(); for(m = mons; m; m = m->next) @@ -201,7 +213,7 @@ index 314adf4..24a0113 100644 focus(NULL); arrange(NULL); } -@@ -652,6 +732,11 @@ destroynotify(XEvent *e) { +@@ -652,6 +732,11 @@ if((c = wintoclient(ev->window))) unmanage(c, True); @@ -213,7 +225,7 @@ index 314adf4..24a0113 100644 } void -@@ -696,6 +781,7 @@ drawbar(Monitor *m) { +@@ -696,6 +781,7 @@ unsigned int i, occ = 0, urg = 0; Client *c; @@ -221,17 +233,17 @@ index 314adf4..24a0113 100644 for(c = m->clients; c; c = c->next) { occ |= c->tags; if(c->isurgent) -@@ -718,6 +804,9 @@ drawbar(Monitor *m) { +@@ -718,6 +804,9 @@ if(m == selmon) { /* status is only drawn on selected monitor */ w = TEXTW(stext); x = m->ww - w; -+ if(showsystray && m == selmon) { ++ if(showsystray && m == systraytomon(m)) { + x -= getsystraywidth(); + } if(x < xx) { x = xx; w = m->ww - xx; -@@ -747,6 +836,7 @@ drawbars(void) { +@@ -747,6 +836,7 @@ for(m = mons; m; m = m->next) drawbar(m); @@ -239,7 +251,20 @@ index 314adf4..24a0113 100644 } void -@@ -857,10 +947,17 @@ getatomprop(Client *c, Atom prop) { +@@ -773,8 +863,11 @@ + Monitor *m; + XExposeEvent *ev = &e->xexpose; + +- if(ev->count == 0 && (m = wintomon(ev->window))) ++ if(ev->count == 0 && (m = wintomon(ev->window))) { + drawbar(m); ++ if(m == selmon) ++ updatesystray(); ++ } + } + + void +@@ -857,10 +950,17 @@ unsigned long dl; unsigned char *p = NULL; Atom da, atom = None; @@ -258,7 +283,7 @@ index 314adf4..24a0113 100644 XFree(p); } return atom; -@@ -892,6 +989,15 @@ getstate(Window w) { +@@ -892,6 +992,15 @@ return result; } @@ -274,7 +299,7 @@ index 314adf4..24a0113 100644 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size) { char **list = NULL; -@@ -992,7 +1098,7 @@ void +@@ -992,7 +1101,7 @@ killclient(const Arg *arg) { if(!selmon->sel) return; @@ -283,7 +308,7 @@ index 314adf4..24a0113 100644 XGrabServer(dpy); XSetErrorHandler(xerrordummy); XSetCloseDownMode(dpy, DestroyAll); -@@ -1078,6 +1184,12 @@ void +@@ -1078,6 +1187,12 @@ maprequest(XEvent *e) { static XWindowAttributes wa; XMapRequestEvent *ev = &e->xmaprequest; @@ -296,7 +321,7 @@ index 314adf4..24a0113 100644 if(!XGetWindowAttributes(dpy, ev->window, &wa)) return; -@@ -1194,6 +1306,16 @@ propertynotify(XEvent *e) { +@@ -1194,6 +1309,16 @@ Window trans; XPropertyEvent *ev = &e->xproperty; @@ -313,7 +338,7 @@ index 314adf4..24a0113 100644 if((ev->window == root) && (ev->atom == XA_WM_NAME)) updatestatus(); else if(ev->state == PropertyDelete) -@@ -1243,12 +1365,33 @@ recttomon(int x, int y, int w, int h) { +@@ -1243,12 +1368,33 @@ } void @@ -338,7 +363,7 @@ index 314adf4..24a0113 100644 void +resizebarwin(Monitor *m) { + unsigned int w = m->ww; -+ if(showsystray && m == selmon) ++ if(showsystray && m == systraytomon(m)) + w -= getsystraywidth(); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); +} @@ -347,26 +372,7 @@ index 314adf4..24a0113 100644 resizeclient(Client *c, int x, int y, int w, int h) { XWindowChanges wc; -@@ -1315,6 +1458,18 @@ resizemouse(const Arg *arg) { - } - - void -+resizerequest(XEvent *e) { -+ XResizeRequestEvent *ev = &e->xresizerequest; -+ Client *i; -+ -+ if((i = wintosystrayicon(ev->window))) { -+ updatesystrayicongeom(i, ev->width, ev->height); -+ resizebarwin(selmon); -+ updatesystray(); -+ } -+} -+ -+void - restack(Monitor *m) { - Client *c; - XEvent ev; -@@ -1398,25 +1553,35 @@ setclientstate(Client *c, long state) { +@@ -1398,25 +1544,35 @@ } Bool @@ -413,7 +419,7 @@ index 314adf4..24a0113 100644 } return exists; } -@@ -1429,7 +1594,7 @@ setfocus(Client *c) { +@@ -1429,7 +1585,7 @@ XA_WINDOW, 32, PropModeReplace, (unsigned char *) &(c->win), 1); } @@ -422,7 +428,7 @@ index 314adf4..24a0113 100644 } void -@@ -1511,11 +1676,17 @@ setup(void) { +@@ -1511,12 +1667,18 @@ wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); @@ -434,13 +440,14 @@ index 314adf4..24a0113 100644 netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + xatom[Manager] = XInternAtom(dpy, "MANAGER", False); + xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); + xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); - netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); /* init cursors */ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); -@@ -1528,6 +1699,8 @@ setup(void) { + cursor[CurResize] = drw_cur_create(drw, XC_sizing); +@@ -1528,6 +1690,8 @@ scheme[SchemeSel].border = drw_clr_create(drw, selbordercolor); scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor); scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor); @@ -449,7 +456,30 @@ index 314adf4..24a0113 100644 /* init bars */ updatebars(); updatestatus(); -@@ -1626,7 +1799,18 @@ void +@@ -1583,6 +1747,22 @@ + } + } + ++Monitor * ++systraytomon(Monitor *m) { ++ Monitor *t; ++ int i, n; ++ if(!systraypinning) { ++ if(!m) ++ return selmon; ++ return m == selmon ? m : NULL; ++ } ++ for(n = 1, t = mons; t && t->next; n++, t = t->next) ; ++ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; ++ if(systraypinningfailfirst && n < systraypinning) ++ return mons; ++ return t; ++} ++ + void + tag(const Arg *arg) { + if(selmon->sel && arg->ui & TAGMASK) { +@@ -1629,7 +1809,18 @@ togglebar(const Arg *arg) { selmon->showbar = !selmon->showbar; updatebarpos(selmon); @@ -469,7 +499,7 @@ index 314adf4..24a0113 100644 arrange(selmon); } -@@ -1716,11 +1900,17 @@ unmapnotify(XEvent *e) { +@@ -1719,11 +1910,18 @@ else unmanage(c, False); } @@ -482,24 +512,30 @@ index 314adf4..24a0113 100644 void updatebars(void) { - Monitor *m; + unsigned int w; + Monitor *m; ++ XSetWindowAttributes wa = { .override_redirect = True, .background_pixmap = ParentRelative, -@@ -1729,7 +1919,10 @@ updatebars(void) { +@@ -1732,10 +1930,15 @@ for(m = mons; m; m = m->next) { if (m->barwin) continue; - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), + w = m->ww; -+ if(showsystray && m == selmon) ++ if(showsystray && m == systraytomon(m)) + w -= getsystraywidth(); + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); -@@ -1926,6 +2119,107 @@ updatestatus(void) { ++ if(showsystray && m == systraytomon(m)) ++ XMapRaised(dpy, systray->win); + XMapRaised(dpy, m->barwin); + } + } +@@ -1929,6 +2132,114 @@ } void @@ -554,8 +590,10 @@ index 314adf4..24a0113 100644 +void +updatesystray(void) { + XSetWindowAttributes wa; ++ XWindowChanges wc; + Client *i; -+ unsigned int x = selmon->mx + selmon->mw; ++ Monitor *m = systraytomon(NULL); ++ unsigned int x = m->mx + m->mw; + unsigned int w = 1; + + if(!showsystray) @@ -564,15 +602,14 @@ index 314adf4..24a0113 100644 + /* init systray */ + if(!(systray = (Systray *)calloc(1, sizeof(Systray)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); -+ systray->win = XCreateSimpleWindow(dpy, root, x, selmon->by, w, bh, 0, 0, scheme[SchemeSel].bg->rgb); ++ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel].bg->rgb); + wa.event_mask = ButtonPressMask | ExposureMask; + wa.override_redirect = True; -+ wa.background_pixmap = ParentRelative; + wa.background_pixel = scheme[SchemeNorm].bg->rgb; + 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|CWBackPixmap, &wa); ++ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa); + XMapRaised(dpy, systray->win); + XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); + if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { @@ -587,16 +624,22 @@ index 314adf4..24a0113 100644 + } + } + for(w = 0, i = systray->icons; i; i = i->next) { -+ XMapRaised(dpy, i->win); ++ /* make sure the background color stays the same */ ++ wa.background_pixel = scheme[SchemeNorm].bg->rgb; ++ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); + w += systrayspacing; + XMoveResizeWindow(dpy, i->win, (i->x = w), 0, i->w, i->h); + w += i->w; -+ if(i->mon != selmon) -+ i->mon = selmon; ++ if(i->mon != m) ++ i->mon = m; + } + w = w ? w + systrayspacing : 1; -+ x -= w; -+ XMoveResizeWindow(dpy, systray->win, x, selmon->by, w, bh); ++ x -= w; ++ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh; ++ wc.stack_mode = Above; wc.sibling = m->barwin; ++ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); ++ XMapWindow(dpy, systray->win); ++ XMapSubwindows(dpy, systray->win); + /* redraw background */ + XSetForeground(dpy, drw->gc, scheme[SchemeNorm].bg->rgb); + XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); @@ -607,7 +650,7 @@ index 314adf4..24a0113 100644 updatewindowtype(Client *c) { Atom state = getatomprop(c, netatom[NetWMState]); Atom wtype = getatomprop(c, netatom[NetWMWindowType]); -@@ -1994,6 +2288,16 @@ wintomon(Window w) { +@@ -1997,6 +2308,16 @@ return selmon; } diff --git a/dwm.suckless.org/patches/systray.md b/dwm.suckless.org/patches/systray.md @@ -9,11 +9,11 @@ is following the selected monitor. Download -------- Patches against different versions of dwm are available at -[dwm-clean-patches](https://bitbucket.org/jceb81/dwm-clean-patches/src). +[dwm-clean-patches](https://github.com/jceb/dwm-clean-patches). + * [dwm-6.1-systray.diff](dwm-6.1-systray.diff) (21630b) (20140209) * [dwm-c794a9f5ae5e-systray.diff](dwm-c794a9f5ae5e-systray.diff) (19946b) (20130119) * [dwm-6.0-systray.diff](dwm-6.0-systray.diff) (19788b) (20130119) - * [dwm-6.1-systray.diff](dwm-6.1-systray.diff) (20714b) (20130119) Author ------