diff --git a/dwm.c b/dwm.c index ce232b4..aa0eb7e 100644 --- a/dwm.c +++ b/dwm.c @@ -52,6 +52,7 @@ #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) +#define ISTRAY(C) (systrayclient && systrayclient == (C)) #define LENGTH(X) (sizeof X / sizeof X[0]) #define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define WIDTH(X) ((X)->w + 2 * (X)->bw) @@ -246,6 +247,7 @@ static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh, blw = 0; /* bar geometry */ static int (*xerrorxlib)(Display *, XErrorEvent *); +static Client *systrayclient; static unsigned int numlockmask = 0; static void (*handler[LASTEvent]) (XEvent *) = { [ButtonPress] = buttonpress, @@ -835,6 +837,9 @@ drawbar(Monitor *m) { if(m == selmon) { /* status is only drawn on selected monitor */ w = TEXTW(stext); x = m->ww - w; + if (systrayclient) { + x -= WIDTH(systrayclient); + } if(x < xx) { x = xx; w = m->ww - xx; @@ -883,7 +888,7 @@ focus(Client *c) { if(!c || !ISVISIBLE(c)) { if (focusbyft) { for(i = 0, c = selmon->clients; c; c = c->next) { - if (!ISVISIBLE(c)) { + if (!ISVISIBLE(c) || ISTRAY(c)) { continue; } @@ -903,7 +908,7 @@ focus(Client *c) { c = o; focusbyft = False; } else { - for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); + for(c = selmon->stack; c && (!ISVISIBLE(c) || ISTRAY(c)); c = c->snext); } } /* was if(selmon->sel) */ @@ -1049,7 +1054,7 @@ grabbuttons(Client *c, Bool focused) { unsigned int i, j; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - if(!focused) + if(!focused && !ISTRAY(c)) XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK, GrabModeSync, GrabModeSync, None, None); for(i = 0; i < LENGTH(buttons); i++) @@ -1160,6 +1165,11 @@ manage(Window w, XWindowAttributes *wa) { c->mon = selmon; applyrules(c); } + if (!strcmp("stalonetray", c->name)) { + c->tags = 0; + systrayclient = c; + } + /* geometry */ c->x = c->oldx = wa->x; c->y = c->oldy = wa->y; @@ -1173,11 +1183,17 @@ manage(Window w, XWindowAttributes *wa) { c->y = c->mon->my + c->mon->mh - HEIGHT(c); c->x = MAX(c->x, c->mon->mx); /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) - && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + if (ISTRAY(c)) { + c->y = 0; + } else { + c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) + && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + } updatewindowtype(c); - if (c->isfloating) { + if (c == systrayclient) { + c->bw = 0; + } else if (c->isfloating) { c->bw = c->isfullscreen ? 0 : borderpx; } else { c->bw = 0; @@ -1410,7 +1426,7 @@ resizeclient(Client *c, int x, int y, int w, int h) { XWindowChanges wc; c->oldx = c->x; c->x = wc.x = x; - c->oldy = c->y; c->y = wc.y = y; + c->oldy = c->y; c->y = wc.y = ISTRAY(c) ? 0 : y; c->oldw = c->w; c->w = wc.width = w; c->oldh = c->h; c->h = wc.height = h; wc.border_width = c->bw; @@ -1719,7 +1735,7 @@ void showhide(Client *c) { if(!c) return; - if(ISVISIBLE(c)) { /* show clients top down */ + if(ISVISIBLE(c) || ISTRAY(c)) { /* show clients top down */ if (c->isurgent) { clearurgent(c); } @@ -1875,6 +1891,8 @@ unmanage(Client *c, Bool destroyed) { XSetErrorHandler(xerror); XUngrabServer(dpy); } + if (ISTRAY(c)) + systrayclient = NULL; free(c); focus(NULL); updateclientlist();