From 52a39819a570ebfaad3fa90384aed9d23c1d7d08 Mon Sep 17 00:00:00 2001 From: Marcin Wozniak Date: Sat, 25 May 2019 13:53:13 +0200 Subject: [PATCH] Added files --- .gitignore | 5 + config.def.h.orig | 132 -- config.h | 2 +- config.mk.orig | 38 - drw.o | Bin 10224 -> 0 bytes dwm | Bin 64184 -> 0 bytes dwm-autostart-20161205-bb3bd6f.diff | 39 - dwm-fullgaps-6.2.diff | 95 - dwm-pango-6.0.diff | 294 ---- dwm-systray-20180314-3bd8466.diff | 716 -------- dwm.c.orig | 2505 --------------------------- dwm.o | Bin 72072 -> 0 bytes dwm.png | Bin 373 -> 0 bytes dwmgit.diff | 747 -------- util.o | Bin 2224 -> 0 bytes 15 files changed, 6 insertions(+), 4567 deletions(-) create mode 100644 .gitignore delete mode 100644 config.def.h.orig delete mode 100644 config.mk.orig delete mode 100644 drw.o delete mode 100755 dwm delete mode 100644 dwm-autostart-20161205-bb3bd6f.diff delete mode 100644 dwm-fullgaps-6.2.diff delete mode 100644 dwm-pango-6.0.diff delete mode 100644 dwm-systray-20180314-3bd8466.diff delete mode 100644 dwm.c.orig delete mode 100644 dwm.o delete mode 100644 dwm.png delete mode 100644 dwmgit.diff delete mode 100644 util.o diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61d0d01 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.diff +*.orig +*.rej +*.o +dwm diff --git a/config.def.h.orig b/config.def.h.orig deleted file mode 100644 index bfa9a12..0000000 --- a/config.def.h.orig +++ /dev/null @@ -1,132 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -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 int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -static const int showsystray = 1; /* 0 means no systray */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = { "monospace:size=10" }; -static const char dmenufont[] = "monospace:size=10"; -static const char col_gray1[] = "#222222"; -static const char col_gray2[] = "#444444"; -static const char col_gray3[] = "#bbbbbb"; -static const char col_gray4[] = "#eeeeee"; -static const char col_cyan[] = "#005577"; -static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, -}; - -/* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ - /* class instance title tags mask isfloating monitor */ - { "Chromium", NULL, NULL, 1 << 1, False, -1 }, - { "Opera", NULL, NULL, 1 << 1, False, -1 }, - { NULL, NULL, "Audacious", 1 << 4, False, -1 }, - { "Thunar", NULL, NULL, 1 << 5, False, -1 }, - { "Thunderbird", NULL, NULL, 1 << 3, False, -1 }, - { "Pidgin", NULL, NULL, 1 << 2, False, -1 }, - { "qbittorent", NULL, NULL, 1 << 5, False, -1 }, -}; - -/* layout(s) */ -static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ - -static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -}; - -/* key definitions */ -#define MODKEY Mod1Mask -#define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, - -/* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - -/* commands */ -static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; -static const char *termcmd[] = { "xterm", NULL }; -static const char *print_screen_cmd[] = { "scrot", "%Y-%m-%d-%H%M%S.png", "-e", "mv $f ~/images/screenshots", NULL }; -static const char *cmdlock[] = { "slock", NULL }; - -static Key keys[] = { - /* modifier key function argument */ - {0 , 0x1008ff02 , spawn, SHCMD ("xbacklight -inc 10")}, - {0 , 0x1008ff03 , spawn, SHCMD ("xbacklight -dec 10")}, - {0 , 0x1008ff11 , spawn, SHCMD ("pactl set-sink-volume 0 -5%")}, - {0 , 0x1008ff12 , spawn, SHCMD ("pactl set-sink-mute 0 toggle")}, - {0 , 0x1008ff13 , spawn, SHCMD ("pactl set-sink-volume 0 +5%")}, - { MODKEY|ShiftMask, XK_l, spawn, {.v = cmdlock } }, - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -}; - -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -}; - diff --git a/config.h b/config.h index 37152ba..df1249f 100644 --- a/config.h +++ b/config.h @@ -88,7 +88,7 @@ static Key keys[] = { {0, 0x1008ff13, spawn, SHCMD ("ponymix increase 5")}, { MODKEY, XK_F2, spawn, SHCMD ("ponymix decrease 5")}, { MODKEY, XK_F1, spawn, SHCMD ("ponymix toggle")}, - { MODKEY, XK_F1, spawn, SHCMD ("ponymix increase 5")}, + { MODKEY, XK_F3, spawn, SHCMD ("ponymix increase 5")}, { MODKEY, XK_F10, spawn, {.v = screenswitcher} }, {0, XK_Print, spawn, {.v = print_screen_cmd } }, { MODKEY, XK_l, spawn, {.v = cmdlock } }, diff --git a/config.mk.orig b/config.mk.orig deleted file mode 100644 index b672a0b..0000000 --- a/config.mk.orig +++ /dev/null @@ -1,38 +0,0 @@ -# dwm version -VERSION = 6.1 - -# Customize below to fit your system - -# paths -PREFIX = /usr/local -MANPREFIX = ${PREFIX}/share/man - -X11INC = /usr/include/X11 -X11LIB = /usr/lib/X11 - -# Xinerama, comment if you don't want it -XINERAMALIBS = -lXinerama -XINERAMAFLAGS = -DXINERAMA - -# freetype -FREETYPELIBS = -lfontconfig -lXft -FREETYPEINC = /usr/include/freetype2 -# OpenBSD (uncomment) -#FREETYPEINC = ${X11INC}/freetype2 - -# includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = -s ${LIBS} - -# Solaris -#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/drw.o b/drw.o deleted file mode 100644 index 6cccdde9b23f3c9b787a2fd458a55cf33bb2c086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10224 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 dbWH3+E;;E^aH9CO8T -Date: Thu Dec 22 17:31:07 2016 +0100 - - Applied and fixed autostart patch for previous version; - -diff --git a/dwm.c b/dwm.c -index d27cb67..066ed71 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -194,6 +194,7 @@ static void resizeclient(Client *c, int x, int y, int w, int h); - static void resizemouse(const Arg *arg); - static void restack(Monitor *m); - static void run(void); -+static void runAutostart(void); - static void scan(void); - static int sendevent(Client *c, Atom proto); - static void sendmon(Client *c, Monitor *m); -@@ -1386,6 +1387,12 @@ run(void) - } - - void -+runAutostart(void) { -+ system("cd ~/.dwm; ./autostart_blocking.sh"); -+ system("cd ~/.dwm; ./autostart.sh &"); -+} -+ -+void - scan(void) - { - unsigned int i, num; -@@ -2145,6 +2152,7 @@ main(int argc, char *argv[]) - checkotherwm(); - setup(); - scan(); -+ runAutostart(); - run(); - cleanup(); - XCloseDisplay(dpy); diff --git a/dwm-fullgaps-6.2.diff b/dwm-fullgaps-6.2.diff deleted file mode 100644 index 7206aec..0000000 --- a/dwm-fullgaps-6.2.diff +++ /dev/null @@ -1,95 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 1c0b587..38d2f6c 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -2,6 +2,7 @@ - - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ -+static const unsigned int gappx = 5; /* gaps between windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ -@@ -84,6 +85,9 @@ static Key keys[] = { - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -+ { MODKEY, XK_minus, setgaps, {.i = -1 } }, -+ { MODKEY, XK_equal, setgaps, {.i = +1 } }, -+ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) -diff --git a/dwm.c b/dwm.c -index 4465af1..4363627 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -119,6 +119,7 @@ struct Monitor { - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ -+ int gappx; /* gaps between windows */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; -@@ -199,6 +200,7 @@ static void sendmon(Client *c, Monitor *m); - static void setclientstate(Client *c, long state); - static void setfocus(Client *c); - static void setfullscreen(Client *c, int fullscreen); -+static void setgaps(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -638,6 +640,7 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->gappx = gappx; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -1497,6 +1500,16 @@ setfullscreen(Client *c, int fullscreen) - } - } - -+void -+setgaps(const Arg *arg) -+{ -+ if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) -+ selmon->gappx = 0; -+ else -+ selmon->gappx += arg->i; -+ arrange(selmon); -+} -+ - void - setlayout(const Arg *arg) - { -@@ -1683,16 +1696,16 @@ tile(Monitor *m) - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else -- mw = m->ww; -- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ mw = m->ww - m->gappx; -+ for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { -- h = (m->wh - my) / (MIN(n, m->nmaster) - i); -- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); -- my += HEIGHT(c); -+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; -+ resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); -+ my += HEIGHT(c) + m->gappx; - } else { -- h = (m->wh - ty) / (n - i); -- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); -- ty += HEIGHT(c); -+ h = (m->wh - ty) / (n - i) - m->gappx; -+ resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); -+ ty += HEIGHT(c) + m->gappx; - } - } - --- -2.20.1 - diff --git a/dwm-pango-6.0.diff b/dwm-pango-6.0.diff deleted file mode 100644 index e463f7b..0000000 --- a/dwm-pango-6.0.diff +++ /dev/null @@ -1,294 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 77ff358..3bee2e7 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -1,7 +1,7 @@ - /* See LICENSE file for copyright and license details. */ - - /* appearance */ --static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; -+static const char font[] = "Sans 8"; - static const char normbordercolor[] = "#444444"; - static const char normbgcolor[] = "#222222"; - static const char normfgcolor[] = "#bbbbbb"; -@@ -12,6 +12,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const Bool showbar = True; /* False means no bar */ - static const Bool topbar = True; /* False means bottom bar */ -+static const Bool statusmarkup = True; /* True means use pango markup in status message */ - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -diff --git a/config.mk b/config.mk -index 484554a..cdfb642 100644 ---- a/config.mk -+++ b/config.mk -@@ -15,8 +15,8 @@ XINERAMALIBS = -L${X11LIB} -lXinerama - XINERAMAFLAGS = -DXINERAMA - - # includes and libs --INCS = -I. -I/usr/include -I${X11INC} --LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I. -I/usr/include -I${X11INC} `pkg-config --cflags xft pango pangoxft` -+LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} `pkg-config --libs xft pango pangoxft` - - # flags - CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff --git a/dwm.c b/dwm.c -index 1d78655..8fae3ba 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -36,6 +36,9 @@ - #include - #include - #include -+#include -+#include -+#include - #ifdef XINERAMA - #include - #endif /* XINERAMA */ -@@ -47,8 +50,12 @@ - * 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 LENGTH(X) (sizeof X / sizeof X[0]) -+#ifndef MAX - #define MAX(A, B) ((A) > (B) ? (A) : (B)) -+#endif -+#ifndef MIN - #define MIN(A, B) ((A) < (B) ? (A) : (B)) -+#endif - #define MOUSEMASK (BUTTONMASK|PointerMotionMask) - #define WIDTH(X) ((X)->w + 2 * (X)->bw) - #define HEIGHT(X) ((X)->h + 2 * (X)->bw) -@@ -104,11 +111,15 @@ typedef struct { - Drawable drawable; - GC gc; - struct { -+ XftColor norm[ColLast]; -+ XftColor sel[ColLast]; -+ XftDraw *drawable; -+ } xft; -+ struct { - int ascent; - int descent; - int height; -- XFontSet set; -- XFontStruct *xfont; -+ PangoLayout *layout; - } font; - } DC; /* draw context */ - -@@ -186,7 +197,7 @@ static void focus(Client *c); - static void focusin(XEvent *e); - static void focusmon(const Arg *arg); - static void focusstack(const Arg *arg); --static unsigned long getcolor(const char *colstr); -+static unsigned long getcolor(const char *colstr, XftColor *color); - static Bool getrootptr(int *x, int *y); - static long getstate(Window w); - static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -254,7 +265,7 @@ static void zoom(const Arg *arg); - - /* variables */ - static const char broken[] = "broken"; --static char stext[256]; -+static char stext[512]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -@@ -479,18 +490,21 @@ cleanup(void) { - Arg a = {.ui = ~0}; - Layout foo = { "", NULL }; - Monitor *m; -+ int i; - - view(&a); - selmon->lt[selmon->sellt] = &foo; - for(m = mons; m; m = m->next) - while(m->stack) - unmanage(m->stack, False); -- if(dc.font.set) -- XFreeFontSet(dpy, dc.font.set); -- else -- XFreeFont(dpy, dc.font.xfont); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XFreePixmap(dpy, dc.drawable); -+ for(i = ColBorder; i < ColLast; i++) { -+ XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), dc.xft.norm + i); -+ XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), dc.xft.sel + i); -+ } -+ XftDrawDestroy(dc.xft.drawable); -+ g_object_unref(dc.font.layout); - XFreeGC(dpy, dc.gc); - XFreeCursor(dpy, cursor[CurNormal]); - XFreeCursor(dpy, cursor[CurResize]); -@@ -581,6 +595,7 @@ configurenotify(XEvent *e) { - if(dc.drawable != 0) - XFreePixmap(dpy, dc.drawable); - dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); -+ XftDrawChange(dc.xft.drawable, dc.drawable); - updatebars(); - for(m = mons; m; m = m->next) - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -@@ -787,7 +802,7 @@ drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { - - void - drawtext(const char *text, unsigned long col[ColLast], Bool invert) { -- char buf[256]; -+ char buf[512]; - int i, x, y, h, len, olen; - - XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); -@@ -796,20 +811,25 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { - return; - olen = strlen(text); - h = dc.font.ascent + dc.font.descent; -- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; -+ y = dc.y + (dc.h / 2) - (h / 2); - x = dc.x + (h / 2); -- /* shorten text if necessary */ -+ /* shorten text if necessary (this could wreak havoc with pango markup but fortunately -+ dc.w is adjusted to the width of the status text and not the other way around) */ - for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); - if(!len) - return; - memcpy(buf, text, len); - if(len < olen) - for(i = len; i && i > len - 3; buf[--i] = '.'); -- XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); -- if(dc.font.set) -- XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); -+ if(text == stext && statusmarkup) -+ pango_layout_set_markup(dc.font.layout, buf, len); - else -- XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); -+ pango_layout_set_text(dc.font.layout, buf, len); -+ pango_xft_render_layout(dc.xft.drawable, -+ (col == dc.norm ? dc.xft.norm : dc.xft.sel) + (invert ? ColBG : ColFG), -+ dc.font.layout, x * PANGO_SCALE, y * PANGO_SCALE); -+ if(text == stext && statusmarkup) /* clear markup attributes */ -+ pango_layout_set_attributes(dc.font.layout, NULL); - } - - void -@@ -927,13 +947,13 @@ getatomprop(Client *c, Atom prop) { - } - - unsigned long --getcolor(const char *colstr) { -+getcolor(const char *colstr, XftColor *color) { - Colormap cmap = DefaultColormap(dpy, screen); -- XColor color; -+ Visual *vis = DefaultVisual(dpy, screen); - -- if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) -+ if(!XftColorAllocName(dpy, vis, cmap, colstr, color)) - die("error, cannot allocate color '%s'\n", colstr); -- return color.pixel; -+ return color->pixel; - } - - Bool -@@ -1034,36 +1054,24 @@ incnmaster(const Arg *arg) { - - void - initfont(const char *fontstr) { -- char *def, **missing; -- int n; -- -- dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); -- if(missing) { -- while(n--) -- fprintf(stderr, "dwm: missing fontset: %s\n", missing[n]); -- XFreeStringList(missing); -- } -- if(dc.font.set) { -- XFontStruct **xfonts; -- char **font_names; -- -- dc.font.ascent = dc.font.descent = 0; -- XExtentsOfFontSet(dc.font.set); -- n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); -- while(n--) { -- dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); -- dc.font.descent = MAX(dc.font.descent,(*xfonts)->descent); -- xfonts++; -- } -- } -- else { -- if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) -- && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) -- die("error, cannot load font: '%s'\n", fontstr); -- dc.font.ascent = dc.font.xfont->ascent; -- dc.font.descent = dc.font.xfont->descent; -- } -+ PangoFontMap *fontmap; -+ PangoContext *context; -+ PangoFontDescription *desc; -+ PangoFontMetrics *metrics; -+ -+ fontmap = pango_xft_get_font_map(dpy, screen); -+ context = pango_font_map_create_context(fontmap); -+ desc = pango_font_description_from_string(fontstr); -+ dc.font.layout = pango_layout_new(context); -+ pango_layout_set_font_description(dc.font.layout, desc); -+ -+ metrics = pango_context_get_metrics(context, desc, NULL); -+ dc.font.ascent = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE; -+ dc.font.descent = pango_font_metrics_get_descent(metrics) / PANGO_SCALE; - dc.font.height = dc.font.ascent + dc.font.descent; -+ -+ pango_font_metrics_unref(metrics); -+ g_object_unref(context); - } - - #ifdef XINERAMA -@@ -1612,17 +1620,16 @@ setup(void) { - cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); - cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); - /* init appearance */ -- dc.norm[ColBorder] = getcolor(normbordercolor); -- dc.norm[ColBG] = getcolor(normbgcolor); -- dc.norm[ColFG] = getcolor(normfgcolor); -- dc.sel[ColBorder] = getcolor(selbordercolor); -- dc.sel[ColBG] = getcolor(selbgcolor); -- dc.sel[ColFG] = getcolor(selfgcolor); -+ dc.norm[ColBorder] = getcolor(normbordercolor, dc.xft.norm + ColBorder); -+ dc.norm[ColBG] = getcolor(normbgcolor, dc.xft.norm + ColBG); -+ dc.norm[ColFG] = getcolor(normfgcolor, dc.xft.norm + ColFG); -+ dc.sel[ColBorder] = getcolor(selbordercolor, dc.xft.sel + ColBorder); -+ dc.sel[ColBG] = getcolor(selbgcolor, dc.xft.sel + ColBG); -+ dc.sel[ColFG] = getcolor(selfgcolor, dc.xft.sel + ColFG); - dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); -+ dc.xft.drawable = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, NULL); - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); -- if(!dc.font.set) -- XSetFont(dpy, dc.gc, dc.font.xfont->fid); - /* init bars */ - updatebars(); - updatestatus(); -@@ -1692,13 +1699,15 @@ tagmon(const Arg *arg) { - - int - textnw(const char *text, unsigned int len) { -- XRectangle r; -- -- if(dc.font.set) { -- XmbTextExtents(dc.font.set, text, len, NULL, &r); -- return r.width; -- } -- return XTextWidth(dc.font.xfont, text, len); -+ PangoRectangle r; -+ if(text == stext && statusmarkup) -+ pango_layout_set_markup(dc.font.layout, text, len); -+ else -+ pango_layout_set_text(dc.font.layout, text, len); -+ pango_layout_get_extents(dc.font.layout, 0, &r); -+ if(text == stext && statusmarkup) /* clear markup attributes */ -+ pango_layout_set_attributes(dc.font.layout, NULL); -+ return r.width / PANGO_SCALE; - } - - void diff --git a/dwm-systray-20180314-3bd8466.diff b/dwm-systray-20180314-3bd8466.diff deleted file mode 100644 index 31fcb16..0000000 --- a/dwm-systray-20180314-3bd8466.diff +++ /dev/null @@ -1,716 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index a9ac303..bb623f0 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -3,6 +3,10 @@ - /* appearance */ - 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 int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -+static const int showsystray = 1; /* 0 means no systray */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ - static const char *fonts[] = { "monospace:size=10" }; -diff --git a/dwm.c b/dwm.c -index c98678d..5f74da0 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -57,12 +57,30 @@ - #define TAGMASK ((1 << LENGTH(tags)) - 1) - #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - -+#define SYSTEM_TRAY_REQUEST_DOCK 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 { SchemeNorm, SchemeSel }; /* color schemes */ - enum { NetSupported, NetWMName, NetWMState, NetWMCheck, -+ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, - 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 */ -@@ -141,6 +159,12 @@ typedef struct { - int monitor; - } Rule; - -+typedef struct Systray Systray; -+struct Systray { -+ Window win; -+ Client *icons; -+}; -+ - /* function declarations */ - static void applyrules(Client *c); - static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -@@ -169,8 +193,10 @@ static void focus(Client *c); - 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 int getrootptr(int *x, int *y); - static long getstate(Window w); -+static unsigned int getsystraywidth(); - static int gettextprop(Window w, Atom atom, char *text, unsigned int size); - static void grabbuttons(Client *c, int focused); - static void grabkeys(void); -@@ -188,13 +214,16 @@ static void pop(Client *); - 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(Client *i); - static void resize(Client *c, int x, int y, int w, int h, int 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); - static void run(void); - static void scan(void); --static int sendevent(Client *c, Atom proto); -+static int 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); -@@ -206,6 +235,7 @@ static void seturgent(Client *c, int urg); - 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 *); -@@ -223,18 +253,23 @@ static void updateclientlist(void); - static void updatenumlockmask(void); - static void updatesizehints(Client *c); - static void updatestatus(void); -+static void updatesystray(void); -+static void updatesystrayicongeom(Client *i, int w, int h); -+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); - static void updatetitle(Client *c); - static void updatewindowtype(Client *c); - static void updatewmhints(Client *c); - static void view(const Arg *arg); - static Client *wintoclient(Window w); - static Monitor *wintomon(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); - static void zoom(const Arg *arg); - - /* variables */ -+static Systray *systray = NULL; - static const char broken[] = "broken"; - static char stext[256]; - static int screen; -@@ -257,9 +292,10 @@ static void (*handler[LASTEvent]) (XEvent *) = { - [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 int running = 1; - static Cur *cursor[CurLast]; - static Clr **scheme; -@@ -482,6 +518,11 @@ cleanup(void) - XUngrabKey(dpy, AnyKey, AnyModifier, root); - while (mons) - cleanupmon(mons); -+ if (showsystray) { -+ XUnmapWindow(dpy, systray->win); -+ XDestroyWindow(dpy, systray->win); -+ free(systray); -+ } - for (i = 0; i < CurLast; i++) - drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) -@@ -512,9 +553,52 @@ cleanupmon(Monitor *mon) - void - clientmessage(XEvent *e) - { -+ XWindowAttributes wa; -+ XSetWindowAttributes swa; - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); - -+ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { -+ /* add systray icons */ -+ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { -+ if (!(c = (Client *)calloc(1, sizeof(Client)))) -+ die("fatal: could not malloc() %u bytes\n", sizeof(Client)); -+ if (!(c->win = cme->data.l[2])) { -+ free(c); -+ return; -+ } -+ c->mon = selmon; -+ c->next = systray->icons; -+ systray->icons = c; -+ XGetWindowAttributes(dpy, c->win, &wa); -+ c->x = c->oldx = c->y = c->oldy = 0; -+ c->w = c->oldw = wa.width; -+ c->h = c->oldh = wa.height; -+ c->oldbw = wa.border_width; -+ c->bw = 0; -+ c->isfloating = True; -+ /* reuse tags field as mapped status */ -+ c->tags = 1; -+ updatesizehints(c); -+ updatesystrayicongeom(c, wa.width, wa.height); -+ XAddToSaveSet(dpy, c->win); -+ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); -+ XReparentWindow(dpy, c->win, systray->win, 0, 0); -+ /* use parents background color */ -+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; -+ 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); -+ } -+ return; -+ } - if (!c) - return; - if (cme->message_type == netatom[NetWMState]) { -@@ -567,7 +651,7 @@ configurenotify(XEvent *e) - for (c = m->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); -- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ resizebarwin(m); - } - focus(NULL); - arrange(NULL); -@@ -652,6 +736,11 @@ destroynotify(XEvent *e) - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); -+ else if ((c = wintosystrayicon(ev->window))) { -+ removesystrayicon(c); -+ resizebarwin(selmon); -+ updatesystray(); -+ } - } - - void -@@ -695,19 +784,23 @@ dirtomon(int dir) - void - drawbar(Monitor *m) - { -- int x, w, sw = 0; -+ int x, w, sw = 0, stw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; - -+ if(showsystray && m == systraytomon(m)) -+ stw = getsystraywidth(); -+ - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); -- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ -- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); -+ sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */ -+ drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0); - } - -+ resizebarwin(m); - for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) -@@ -728,7 +821,7 @@ drawbar(Monitor *m) - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - -- if ((w = m->ww - sw - x) > bh) { -+ if ((w = m->ww - sw - stw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); -@@ -739,7 +832,7 @@ drawbar(Monitor *m) - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } -- drw_map(drw, m->barwin, 0, 0, m->ww, bh); -+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); - } - - void -@@ -776,8 +869,11 @@ expose(XEvent *e) - 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 -@@ -862,10 +958,17 @@ getatomprop(Client *c, Atom prop) - unsigned long dl; - unsigned char *p = NULL; - Atom da, atom = None; -+ /* FIXME getatomprop should return the number of items and a pointer to -+ * the stored data instead of this workaround */ -+ Atom req = XA_ATOM; -+ if (prop == xatom[XembedInfo]) -+ req = xatom[XembedInfo]; - -- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, -+ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, - &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; -+ if (da == xatom[XembedInfo] && dl == 2) -+ atom = ((Atom *)p)[1]; - XFree(p); - } - return atom; -@@ -899,6 +1002,16 @@ getstate(Window w) - return result; - } - -+unsigned int -+getsystraywidth() -+{ -+ unsigned int w = 0; -+ Client *i; -+ if(showsystray) -+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; -+ return w ? w + systrayspacing : 1; -+} -+ - int - gettextprop(Window w, Atom atom, char *text, unsigned int size) - { -@@ -1003,7 +1116,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); -@@ -1091,6 +1204,12 @@ maprequest(XEvent *e) - { - static XWindowAttributes wa; - XMapRequestEvent *ev = &e->xmaprequest; -+ 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; -@@ -1215,6 +1334,16 @@ propertynotify(XEvent *e) - Window trans; - XPropertyEvent *ev = &e->xproperty; - -+ if ((c = wintosystrayicon(ev->window))) { -+ if (ev->atom == XA_WM_NORMAL_HINTS) { -+ updatesizehints(c); -+ updatesystrayicongeom(c, c->w, c->h); -+ } -+ else -+ updatesystrayiconstate(c, ev); -+ resizebarwin(selmon); -+ updatesystray(); -+ } - if ((ev->window == root) && (ev->atom == XA_WM_NAME)) - updatestatus(); - else if (ev->state == PropertyDelete) -@@ -1265,6 +1394,20 @@ recttomon(int x, int y, int w, int h) - return r; - } - -+void -+removesystrayicon(Client *i) -+{ -+ Client **ii; -+ -+ if (!showsystray || !i) -+ return; -+ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); -+ if (ii) -+ *ii = i->next; -+ free(i); -+} -+ -+ - void - resize(Client *c, int x, int y, int w, int h, int interact) - { -@@ -1272,6 +1415,14 @@ resize(Client *c, int x, int y, int w, int h, int interact) - resizeclient(c, x, y, w, h); - } - -+void -+resizebarwin(Monitor *m) { -+ unsigned int w = m->ww; -+ if (showsystray && m == systraytomon(m)) -+ w -= getsystraywidth(); -+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); -+} -+ - void - resizeclient(Client *c, int x, int y, int w, int h) - { -@@ -1344,6 +1495,19 @@ 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) - { -@@ -1433,26 +1597,36 @@ setclientstate(Client *c, long state) - } - - int --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; - int exists = 0; - 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; - } -@@ -1466,7 +1640,7 @@ setfocus(Client *c) - XA_WINDOW, 32, PropModeReplace, - (unsigned char *) &(c->win), 1); - } -- sendevent(c, wmatom[WMTakeFocus]); -+ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); - } - - void -@@ -1555,6 +1729,10 @@ setup(void) - wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); - netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); -+ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); -+ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); -+ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); -+ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); - netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); - netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); - netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); -@@ -1562,6 +1740,9 @@ setup(void) - 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); - /* init cursors */ - cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); - cursor[CurResize] = drw_cur_create(drw, XC_sizing); -@@ -1570,6 +1751,8 @@ setup(void) - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); -+ /* init system tray */ -+ updatesystray(); - /* init bars */ - updatebars(); - updatestatus(); -@@ -1701,7 +1884,18 @@ togglebar(const Arg *arg) - { - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); -- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); -+ resizebarwin(selmon); -+ if (showsystray) { -+ XWindowChanges wc; -+ if (!selmon->showbar) -+ wc.y = -bh; -+ else if (selmon->showbar) { -+ wc.y = 0; -+ if (!selmon->topbar) -+ wc.y = selmon->mh - bh; -+ } -+ XConfigureWindow(dpy, systray->win, CWY, &wc); -+ } - arrange(selmon); - } - -@@ -1796,11 +1990,18 @@ unmapnotify(XEvent *e) - else - unmanage(c, 0); - } -+ else if ((c = wintosystrayicon(ev->window))) { -+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do -+ * _not_ destroy them. We map those windows back */ -+ XMapRaised(dpy, c->win); -+ updatesystray(); -+ } - } - - void - updatebars(void) - { -+ unsigned int w; - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, -@@ -1811,10 +2012,15 @@ updatebars(void) - 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 == 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); -+ if (showsystray && m == systraytomon(m)) -+ XMapRaised(dpy, systray->win); - XMapRaised(dpy, m->barwin); - XSetClassHint(dpy, m->barwin, &ch); - } -@@ -1990,6 +2196,121 @@ updatestatus(void) - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) - strcpy(stext, "dwm-"VERSION); - drawbar(selmon); -+ updatesystray(); -+} -+ -+void -+updatesystrayicongeom(Client *i, int w, int h) -+{ -+ if (i) { -+ 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)); -+ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); -+ /* force icons into the systray dimenons if they don't want to */ -+ if (i->h > bh) { -+ if (i->w == i->h) -+ i->w = bh; -+ else -+ i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); -+ i->h = bh; -+ } -+ } -+} -+ -+void -+updatesystrayiconstate(Client *i, XPropertyEvent *ev) -+{ -+ long flags; -+ int code = 0; -+ -+ if (!showsystray || !i || ev->atom != xatom[XembedInfo] || -+ !(flags = getatomprop(i, xatom[XembedInfo]))) -+ return; -+ -+ if (flags & XEMBED_MAPPED && !i->tags) { -+ i->tags = 1; -+ code = XEMBED_WINDOW_ACTIVATE; -+ XMapRaised(dpy, i->win); -+ setclientstate(i, NormalState); -+ } -+ else if (!(flags & XEMBED_MAPPED) && i->tags) { -+ i->tags = 0; -+ code = XEMBED_WINDOW_DEACTIVATE; -+ XUnmapWindow(dpy, i->win); -+ setclientstate(i, WithdrawnState); -+ } -+ else -+ return; -+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, -+ systray->win, XEMBED_EMBEDDED_VERSION); -+} -+ -+void -+updatesystray(void) -+{ -+ XSetWindowAttributes wa; -+ XWindowChanges wc; -+ Client *i; -+ Monitor *m = systraytomon(NULL); -+ unsigned int x = m->mx + m->mw; -+ unsigned int w = 1; -+ -+ if (!showsystray) -+ return; -+ if (!systray) { -+ /* 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, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); -+ wa.event_mask = ButtonPressMask | ExposureMask; -+ wa.override_redirect = True; -+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; -+ XSelectInput(dpy, systray->win, SubstructureNotifyMask); -+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, -+ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); -+ 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) { -+ 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 (w = 0, i = systray->icons; i; i = i->next) { -+ /* make sure the background color stays the same */ -+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; -+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); -+ XMapRaised(dpy, i->win); -+ w += systrayspacing; -+ i->x = w; -+ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); -+ w += i->w; -+ if (i->mon != m) -+ i->mon = m; -+ } -+ w = w ? w + systrayspacing : 1; -+ x -= w; -+ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); -+ 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][ColBg].pixel); -+ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); -+ XSync(dpy, False); - } - - void -@@ -2057,6 +2378,16 @@ wintoclient(Window w) - return NULL; - } - -+Client * -+wintosystrayicon(Window w) { -+ Client *i = NULL; -+ -+ if (!showsystray || !w) -+ return i; -+ for (i = systray->icons; i && i->win != w; i = i->next) ; -+ return i; -+} -+ - Monitor * - wintomon(Window w) - { -@@ -2110,6 +2441,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee) - return -1; - } - -+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 - zoom(const Arg *arg) - { diff --git a/dwm.c.orig b/dwm.c.orig deleted file mode 100644 index 6688340..0000000 --- a/dwm.c.orig +++ /dev/null @@ -1,2505 +0,0 @@ -/* See LICENSE file for copyright and license details. - * - * dynamic window manager is designed like any other X client as well. It is - * driven through handling X events. In contrast to other X clients, a window - * manager selects for SubstructureRedirectMask on the root window, to receive - * events about window (dis-)appearance. Only one X connection at a time is - * allowed to select for this event mask. - * - * The event handlers of dwm are organized in an array which is accessed - * whenever a new event has been fetched. This allows event dispatching - * in O(1) time. - * - * Each child of the root window is called a client, except windows which have - * set the override_redirect flag. Clients are organized in a linked client - * list on each monitor, the focus history is remembered through a stack list - * on each monitor. Each client contains a bit array to indicate the tags of a - * client. - * - * Keys and tagging rules are organized as arrays and defined in config.h. - * - * To understand everything else, start reading main(). - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef XINERAMA -#include -#endif /* XINERAMA */ -#include - -#include "drw.h" -#include "util.h" - -/* macros */ -#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) -#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) -#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 LENGTH(X) (sizeof X / sizeof X[0]) -#define MOUSEMASK (BUTTONMASK|PointerMotionMask) -#define WIDTH(X) ((X)->w + 2 * (X)->bw) -#define HEIGHT(X) ((X)->h + 2 * (X)->bw) -#define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - -#define SYSTEM_TRAY_REQUEST_DOCK 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 { SchemeNorm, SchemeSel }; /* color schemes */ -enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, - 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 */ - -typedef union { - int i; - unsigned int ui; - float f; - const void *v; -} Arg; - -typedef struct { - unsigned int click; - unsigned int mask; - unsigned int button; - void (*func)(const Arg *arg); - const Arg arg; -} Button; - -typedef struct Monitor Monitor; -typedef struct Client Client; -struct Client { - char name[256]; - float mina, maxa; - int x, y, w, h; - int oldx, oldy, oldw, oldh; - int basew, baseh, incw, inch, maxw, maxh, minw, minh; - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - Client *next; - Client *snext; - Monitor *mon; - Window win; -}; - -typedef struct { - unsigned int mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Key; - -typedef struct { - const char *symbol; - void (*arrange)(Monitor *); -} Layout; - -struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; - int topbar; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; - const Layout *lt[2]; -}; - -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; -} Rule; - -typedef struct Systray Systray; -struct Systray { - Window win; - Client *icons; -}; - -/* function declarations */ -static void applyrules(Client *c); -static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -static void arrange(Monitor *m); -static void arrangemon(Monitor *m); -static void attach(Client *c); -static void attachstack(Client *c); -static void buttonpress(XEvent *e); -static void checkotherwm(void); -static void cleanup(void); -static void cleanupmon(Monitor *mon); -static void clientmessage(XEvent *e); -static void configure(Client *c); -static void configurenotify(XEvent *e); -static void configurerequest(XEvent *e); -static Monitor *createmon(void); -static void destroynotify(XEvent *e); -static void detach(Client *c); -static void detachstack(Client *c); -static Monitor *dirtomon(int dir); -static void drawbar(Monitor *m); -static void drawbars(void); -static void enternotify(XEvent *e); -static void expose(XEvent *e); -static void focus(Client *c); -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 int getrootptr(int *x, int *y); -static long getstate(Window w); -static unsigned int getsystraywidth(); -static int gettextprop(Window w, Atom atom, char *text, unsigned int size); -static void grabbuttons(Client *c, int focused); -static void grabkeys(void); -static void incnmaster(const Arg *arg); -static void keypress(XEvent *e); -static void killclient(const Arg *arg); -static void manage(Window w, XWindowAttributes *wa); -static void mappingnotify(XEvent *e); -static void maprequest(XEvent *e); -static void monocle(Monitor *m); -static void motionnotify(XEvent *e); -static void movemouse(const Arg *arg); -static Client *nexttiled(Client *c); -static void pop(Client *); -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(Client *i); -static void resize(Client *c, int x, int y, int w, int h, int 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); -static void run(void); -static void runAutostart(void); -static void scan(void); -static int 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); -static void setfullscreen(Client *c, int fullscreen); -static void setlayout(const Arg *arg); -static void setmfact(const Arg *arg); -static void setup(void); -static void seturgent(Client *c, int urg); -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 *); -static void togglebar(const Arg *arg); -static void togglefloating(const Arg *arg); -static void toggletag(const Arg *arg); -static void toggleview(const Arg *arg); -static void unfocus(Client *c, int setfocus); -static void unmanage(Client *c, int destroyed); -static void unmapnotify(XEvent *e); -static void updatebarpos(Monitor *m); -static void updatebars(void); -static void updateclientlist(void); -static int updategeom(void); -static void updatenumlockmask(void); -static void updatesizehints(Client *c); -static void updatestatus(void); -static void updatesystray(void); -static void updatesystrayicongeom(Client *i, int w, int h); -static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); -static void updatetitle(Client *c); -static void updatewindowtype(Client *c); -static void updatewmhints(Client *c); -static void view(const Arg *arg); -static Client *wintoclient(Window w); -static Monitor *wintomon(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); -static void zoom(const Arg *arg); - -/* variables */ -static Systray *systray = NULL; -static const char broken[] = "broken"; -static char stext[512]; -static int screen; -static int sw, sh; /* X display screen geometry width, height */ -static int bh, blw = 0; /* bar geometry */ -static int lrpad; /* sum of left and right padding for text */ -static int (*xerrorxlib)(Display *, XErrorEvent *); -static unsigned int numlockmask = 0; -static void (*handler[LASTEvent]) (XEvent *) = { - [ButtonPress] = buttonpress, - [ClientMessage] = clientmessage, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [Expose] = expose, - [FocusIn] = focusin, - [KeyPress] = keypress, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [MotionNotify] = motionnotify, - [PropertyNotify] = propertynotify, - [ResizeRequest] = resizerequest, - [UnmapNotify] = unmapnotify -}; -static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; -static int running = 1; -static Cur *cursor[CurLast]; -static Clr **scheme; -static Display *dpy; -static Drw *drw; -static Monitor *mons, *selmon; -static Window root, wmcheckwin; - -/* configuration, allows nested code to access above variables */ -#include "config.h" - -/* compile-time check if all tags fit into an unsigned int bit array. */ -struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -/* function implementations */ -void -applyrules(Client *c) -{ - const char *class, *instance; - unsigned int i; - const Rule *r; - Monitor *m; - XClassHint ch = { NULL, NULL }; - - /* rule matching */ - c->isfloating = 0; - c->tags = 0; - XGetClassHint(dpy, c->win, &ch); - class = ch.res_class ? ch.res_class : broken; - instance = ch.res_name ? ch.res_name : broken; - - for (i = 0; i < LENGTH(rules); i++) { - r = &rules[i]; - if ((!r->title || strstr(c->name, r->title)) - && (!r->class || strstr(class, r->class)) - && (!r->instance || strstr(instance, r->instance))) - { - c->isfloating = r->isfloating; - c->tags |= r->tags; - for (m = mons; m && m->num != r->monitor; m = m->next); - if (m) - c->mon = m; - } - } - if (ch.res_class) - XFree(ch.res_class); - if (ch.res_name) - XFree(ch.res_name); - c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; -} - -int -applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) -{ - int baseismin; - Monitor *m = c->mon; - - /* set minimum possible */ - *w = MAX(1, *w); - *h = MAX(1, *h); - if (interact) { - if (*x > sw) - *x = sw - WIDTH(c); - if (*y > sh) - *y = sh - HEIGHT(c); - if (*x + *w + 2 * c->bw < 0) - *x = 0; - if (*y + *h + 2 * c->bw < 0) - *y = 0; - } else { - if (*x >= m->wx + m->ww) - *x = m->wx + m->ww - WIDTH(c); - if (*y >= m->wy + m->wh) - *y = m->wy + m->wh - HEIGHT(c); - if (*x + *w + 2 * c->bw <= m->wx) - *x = m->wx; - if (*y + *h + 2 * c->bw <= m->wy) - *y = m->wy; - } - if (*h < bh) - *h = bh; - if (*w < bh) - *w = bh; - if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { - /* see last two sentences in ICCCM 4.1.2.3 */ - baseismin = c->basew == c->minw && c->baseh == c->minh; - if (!baseismin) { /* temporarily remove base dimensions */ - *w -= c->basew; - *h -= c->baseh; - } - /* adjust for aspect limits */ - if (c->mina > 0 && c->maxa > 0) { - if (c->maxa < (float)*w / *h) - *w = *h * c->maxa + 0.5; - else if (c->mina < (float)*h / *w) - *h = *w * c->mina + 0.5; - } - if (baseismin) { /* increment calculation requires this */ - *w -= c->basew; - *h -= c->baseh; - } - /* adjust for increment value */ - if (c->incw) - *w -= *w % c->incw; - if (c->inch) - *h -= *h % c->inch; - /* restore base dimensions */ - *w = MAX(*w + c->basew, c->minw); - *h = MAX(*h + c->baseh, c->minh); - if (c->maxw) - *w = MIN(*w, c->maxw); - if (c->maxh) - *h = MIN(*h, c->maxh); - } - return *x != c->x || *y != c->y || *w != c->w || *h != c->h; -} - -void -arrange(Monitor *m) -{ - if (m) - showhide(m->stack); - else for (m = mons; m; m = m->next) - showhide(m->stack); - if (m) { - arrangemon(m); - restack(m); - } else for (m = mons; m; m = m->next) - arrangemon(m); -} - -void -arrangemon(Monitor *m) -{ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if (m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -} - -void -attach(Client *c) -{ - c->next = c->mon->clients; - c->mon->clients = c; -} - -void -attachstack(Client *c) -{ - c->snext = c->mon->stack; - c->mon->stack = c; -} - -void -buttonpress(XEvent *e) -{ - unsigned int i, x, click; - Arg arg = {0}; - Client *c; - Monitor *m; - XButtonPressedEvent *ev = &e->xbutton; - - click = ClkRootWin; - /* focus monitor if necessary */ - if ((m = wintomon(ev->window)) && m != selmon) { - unfocus(selmon->sel, 1); - selmon = m; - focus(NULL); - } - if (ev->window == selmon->barwin) { - i = x = 0; - do - x += TEXTW(tags[i]); - while (ev->x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { - click = ClkTagBar; - arg.ui = 1 << i; - } else if (ev->x < x + blw) - click = ClkLtSymbol; - else if (ev->x > selmon->ww - TEXTW(stext)) - click = ClkStatusText; - else - click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -} - -void -checkotherwm(void) -{ - xerrorxlib = XSetErrorHandler(xerrorstart); - /* this causes an error if some other window manager is running */ - XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); - XSync(dpy, False); - XSetErrorHandler(xerror); - XSync(dpy, False); -} - -void -cleanup(void) -{ - Arg a = {.ui = ~0}; - Layout foo = { "", NULL }; - Monitor *m; - size_t i; - - view(&a); - selmon->lt[selmon->sellt] = &foo; - for (m = mons; m; m = m->next) - while (m->stack) - unmanage(m->stack, 0); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - while (mons) - cleanupmon(mons); - if (showsystray) { - XUnmapWindow(dpy, systray->win); - XDestroyWindow(dpy, systray->win); - free(systray); - } - for (i = 0; i < CurLast; i++) - drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) - free(scheme[i]); - XDestroyWindow(dpy, wmcheckwin); - drw_free(drw); - XSync(dpy, False); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); -} - -void -cleanupmon(Monitor *mon) -{ - Monitor *m; - - if (mon == mons) - mons = mons->next; - else { - for (m = mons; m && m->next != mon; m = m->next); - m->next = mon->next; - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - free(mon); -} - -void -clientmessage(XEvent *e) -{ - XWindowAttributes wa; - XSetWindowAttributes swa; - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); - - if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { - /* add systray icons */ - if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { - if (!(c = (Client *)calloc(1, sizeof(Client)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Client)); - if (!(c->win = cme->data.l[2])) { - free(c); - return; - } - c->mon = selmon; - c->next = systray->icons; - systray->icons = c; - XGetWindowAttributes(dpy, c->win, &wa); - c->x = c->oldx = c->y = c->oldy = 0; - c->w = c->oldw = wa.width; - c->h = c->oldh = wa.height; - c->oldbw = wa.border_width; - c->bw = 0; - c->isfloating = True; - /* reuse tags field as mapped status */ - c->tags = 1; - updatesizehints(c); - updatesystrayicongeom(c, wa.width, wa.height); - XAddToSaveSet(dpy, c->win); - XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); - XReparentWindow(dpy, c->win, systray->win, 0, 0); - /* use parents background color */ - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - 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); - } - return; - } - if (!c) - return; - if (cme->message_type == netatom[NetWMState]) { - if (cme->data.l[1] == netatom[NetWMFullscreen] - || cme->data.l[2] == netatom[NetWMFullscreen]) - setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ - || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } else if (cme->message_type == netatom[NetActiveWindow]) { - if (c != selmon->sel && !c->isurgent) - seturgent(c, 1); - } -} - -void -configure(Client *c) -{ - XConfigureEvent ce; - - ce.type = ConfigureNotify; - ce.display = dpy; - ce.event = c->win; - ce.window = c->win; - ce.x = c->x; - ce.y = c->y; - ce.width = c->w; - ce.height = c->h; - ce.border_width = c->bw; - ce.above = None; - ce.override_redirect = False; - XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); -} - -void -configurenotify(XEvent *e) -{ - Monitor *m; - Client *c; - XConfigureEvent *ev = &e->xconfigure; - int dirty; - - /* TODO: updategeom handling sucks, needs to be simplified */ - if (ev->window == root) { - dirty = (sw != ev->width || sh != ev->height); - sw = ev->width; - sh = ev->height; - if (updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); - for (m = mons; m; m = m->next) { - for (c = m->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); - resizebarwin(m); - } - focus(NULL); - arrange(NULL); - } - } -} - -void -configurerequest(XEvent *e) -{ - Client *c; - Monitor *m; - XConfigureRequestEvent *ev = &e->xconfigurerequest; - XWindowChanges wc; - - if ((c = wintoclient(ev->window))) { - if (ev->value_mask & CWBorderWidth) - c->bw = ev->border_width; - else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { - m = c->mon; - if (ev->value_mask & CWX) { - c->oldx = c->x; - c->x = m->mx + ev->x; - } - if (ev->value_mask & CWY) { - c->oldy = c->y; - c->y = m->my + ev->y; - } - if (ev->value_mask & CWWidth) { - c->oldw = c->w; - c->w = ev->width; - } - if (ev->value_mask & CWHeight) { - c->oldh = c->h; - c->h = ev->height; - } - if ((c->x + c->w) > m->mx + m->mw && c->isfloating) - c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ - if ((c->y + c->h) > m->my + m->mh && c->isfloating) - c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ - if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) - configure(c); - if (ISVISIBLE(c)) - XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); - } else - configure(c); - } else { - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); - } - XSync(dpy, False); -} - -Monitor * -createmon(void) -{ - Monitor *m; - - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); - return m; -} - -void -destroynotify(XEvent *e) -{ - Client *c; - XDestroyWindowEvent *ev = &e->xdestroywindow; - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); - else if ((c = wintosystrayicon(ev->window))) { - removesystrayicon(c); - resizebarwin(selmon); - updatesystray(); - } -} - -void -detach(Client *c) -{ - Client **tc; - - for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); - *tc = c->next; -} - -void -detachstack(Client *c) -{ - Client **tc, *t; - - for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); - *tc = c->snext; - - if (c == c->mon->sel) { - for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); - c->mon->sel = t; - } -} - -Monitor * -dirtomon(int dir) -{ - Monitor *m = NULL; - - if (dir > 0) { - if (!(m = selmon->next)) - m = mons; - } else if (selmon == mons) - for (m = mons; m->next; m = m->next); - else - for (m = mons; m->next != selmon; m = m->next); - return m; -} - -void -drawbar(Monitor *m) -{ - int x, w, sw = 0, stw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; - - if(showsystray && m == systraytomon(m)) - stw = getsystraywidth(); - - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */ - drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0); - } - - resizebarwin(m); - for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); - if (occ & 1 << i) - drw_rect(drw, x + boxs, boxs, boxw, boxw, - m == selmon && selmon->sel && selmon->sel->tags & 1 << i, - urg & 1 << i); - x += w; - } - w = blw = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - sw - stw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); - if (m->sel->isfloating) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); - } else { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } - drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); -} - -void -drawbars(void) -{ - Monitor *m; - - for (m = mons; m; m = m->next) - drawbar(m); -} - -void -enternotify(XEvent *e) -{ - Client *c; - Monitor *m; - XCrossingEvent *ev = &e->xcrossing; - - if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) - return; - c = wintoclient(ev->window); - m = c ? c->mon : wintomon(ev->window); - if (m != selmon) { - unfocus(selmon->sel, 1); - selmon = m; - } else if (!c || c == selmon->sel) - return; - focus(c); -} - -void -expose(XEvent *e) -{ - Monitor *m; - XExposeEvent *ev = &e->xexpose; - - if (ev->count == 0 && (m = wintomon(ev->window))) { - drawbar(m); - if (m == selmon) - updatesystray(); - } -} - -void -focus(Client *c) -{ - if (!c || !ISVISIBLE(c)) - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); - if (selmon->sel && selmon->sel != c) - unfocus(selmon->sel, 0); - if (c) { - if (c->mon != selmon) - selmon = c->mon; - if (c->isurgent) - seturgent(c, 0); - detachstack(c); - attachstack(c); - grabbuttons(c, 1); - XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); - setfocus(c); - } else { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); - } - selmon->sel = c; - drawbars(); -} - -/* there are some broken focus acquiring clients needing extra handling */ -void -focusin(XEvent *e) -{ - XFocusChangeEvent *ev = &e->xfocus; - - if (selmon->sel && ev->window != selmon->sel->win) - setfocus(selmon->sel); -} - -void -focusmon(const Arg *arg) -{ - Monitor *m; - - if (!mons->next) - return; - if ((m = dirtomon(arg->i)) == selmon) - return; - unfocus(selmon->sel, 0); - selmon = m; - focus(NULL); -} - -void -focusstack(const Arg *arg) -{ - Client *c = NULL, *i; - - if (!selmon->sel) - return; - if (arg->i > 0) { - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); - if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); - } else { - for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) - c = i; - if (!c) - for (; i; i = i->next) - if (ISVISIBLE(i)) - c = i; - } - if (c) { - focus(c); - restack(selmon); - } -} - -Atom -getatomprop(Client *c, Atom prop) -{ - int di; - unsigned long dl; - unsigned char *p = NULL; - Atom da, atom = None; - /* FIXME getatomprop should return the number of items and a pointer to - * the stored data instead of this workaround */ - Atom req = XA_ATOM; - if (prop == xatom[XembedInfo]) - req = xatom[XembedInfo]; - - if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, - &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; - if (da == xatom[XembedInfo] && dl == 2) - atom = ((Atom *)p)[1]; - XFree(p); - } - return atom; -} - -int -getrootptr(int *x, int *y) -{ - int di; - unsigned int dui; - Window dummy; - - return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); -} - -long -getstate(Window w) -{ - int format; - long result = -1; - unsigned char *p = NULL; - unsigned long n, extra; - Atom real; - - if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], - &real, &format, &n, &extra, (unsigned char **)&p) != Success) - return -1; - if (n != 0) - result = *p; - XFree(p); - return result; -} - -unsigned int -getsystraywidth() -{ - unsigned int w = 0; - Client *i; - if(showsystray) - for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; - return w ? w + systrayspacing : 1; -} - -int -gettextprop(Window w, Atom atom, char *text, unsigned int size) -{ - char **list = NULL; - int n; - XTextProperty name; - - if (!text || size == 0) - return 0; - text[0] = '\0'; - if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) - return 0; - if (name.encoding == XA_STRING) - strncpy(text, (char *)name.value, size - 1); - else { - if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { - strncpy(text, *list, size - 1); - XFreeStringList(list); - } - } - text[size - 1] = '\0'; - XFree(name.value); - return 1; -} - -void -grabbuttons(Client *c, int focused) -{ - updatenumlockmask(); - { - unsigned int i, j; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - if (!focused) - XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, - BUTTONMASK, GrabModeSync, GrabModeSync, None, None); - for (i = 0; i < LENGTH(buttons); i++) - if (buttons[i].click == ClkClientWin) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabButton(dpy, buttons[i].button, - buttons[i].mask | modifiers[j], - c->win, False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - } -} - -void -grabkeys(void) -{ - updatenumlockmask(); - { - unsigned int i, j; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - KeyCode code; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < LENGTH(keys); i++) - if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, - True, GrabModeAsync, GrabModeAsync); - } -} - -void -incnmaster(const Arg *arg) -{ - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); - arrange(selmon); -} - -#ifdef XINERAMA -static int -isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) -{ - while (n--) - if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org - && unique[n].width == info->width && unique[n].height == info->height) - return 0; - return 1; -} -#endif /* XINERAMA */ - -void -keypress(XEvent *e) -{ - unsigned int i; - KeySym keysym; - XKeyEvent *ev; - - ev = &e->xkey; - keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for (i = 0; i < LENGTH(keys); i++) - if (keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); -} - -void -killclient(const Arg *arg) -{ - if (!selmon->sel) - return; - if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { - XGrabServer(dpy); - XSetErrorHandler(xerrordummy); - XSetCloseDownMode(dpy, DestroyAll); - XKillClient(dpy, selmon->sel->win); - XSync(dpy, False); - XSetErrorHandler(xerror); - XUngrabServer(dpy); - } -} - -void -manage(Window w, XWindowAttributes *wa) -{ - Client *c, *t = NULL; - Window trans = None; - XWindowChanges wc; - - c = ecalloc(1, sizeof(Client)); - c->win = w; - /* geometry */ - 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; - - updatetitle(c); - if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { - c->mon = t->mon; - c->tags = t->tags; - } else { - c->mon = selmon; - applyrules(c); - } - - if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) - c->x = c->mon->mx + c->mon->mw - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) - 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); - c->bw = borderpx; - - wc.border_width = c->bw; - XConfigureWindow(dpy, w, CWBorderWidth, &wc); - XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); - configure(c); /* propagates border_width, if size doesn't change */ - updatewindowtype(c); - updatesizehints(c); - updatewmhints(c); - XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - grabbuttons(c, 0); - if (!c->isfloating) - c->isfloating = c->oldstate = trans != None || c->isfixed; - if (c->isfloating) - XRaiseWindow(dpy, c->win); - attach(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - setclientstate(c, NormalState); - if (c->mon == selmon) - unfocus(selmon->sel, 0); - c->mon->sel = c; - arrange(c->mon); - XMapWindow(dpy, c->win); - focus(NULL); -} - -void -mappingnotify(XEvent *e) -{ - XMappingEvent *ev = &e->xmapping; - - XRefreshKeyboardMapping(ev); - if (ev->request == MappingKeyboard) - grabkeys(); -} - -void -maprequest(XEvent *e) -{ - static XWindowAttributes wa; - XMapRequestEvent *ev = &e->xmaprequest; - 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; - if (wa.override_redirect) - return; - if (!wintoclient(ev->window)) - manage(ev->window, &wa); -} - -void -monocle(Monitor *m) -{ - unsigned int n = 0; - Client *c; - - for (c = m->clients; c; c = c->next) - if (ISVISIBLE(c)) - n++; - if (n > 0) /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); - for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -} - -void -motionnotify(XEvent *e) -{ - static Monitor *mon = NULL; - Monitor *m; - XMotionEvent *ev = &e->xmotion; - - if (ev->window != root) - return; - if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { - unfocus(selmon->sel, 1); - selmon = m; - focus(NULL); - } - mon = m; -} - -void -movemouse(const Arg *arg) -{ - int x, y, ocx, ocy, nx, ny; - Client *c; - Monitor *m; - XEvent ev; - Time lasttime = 0; - - if (!(c = selmon->sel)) - return; - if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ - return; - restack(selmon); - ocx = c->x; - ocy = c->y; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, - None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) - return; - if (!getrootptr(&x, &y)) - return; - do { - XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); - switch(ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); - break; - case MotionNotify: - if ((ev.xmotion.time - lasttime) <= (1000 / 60)) - continue; - lasttime = ev.xmotion.time; - - nx = ocx + (ev.xmotion.x - x); - ny = ocy + (ev.xmotion.y - y); - if (abs(selmon->wx - nx) < snap) - nx = selmon->wx; - else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) - nx = selmon->wx + selmon->ww - WIDTH(c); - if (abs(selmon->wy - ny) < snap) - ny = selmon->wy; - else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) - ny = selmon->wy + selmon->wh - HEIGHT(c); - if (!c->isfloating && selmon->lt[selmon->sellt]->arrange - && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) - togglefloating(NULL); - if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) - resize(c, nx, ny, c->w, c->h, 1); - break; - } - } while (ev.type != ButtonRelease); - XUngrabPointer(dpy, CurrentTime); - if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { - sendmon(c, m); - selmon = m; - focus(NULL); - } -} - -Client * -nexttiled(Client *c) -{ - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); - return c; -} - -void -pop(Client *c) -{ - detach(c); - attach(c); - focus(c); - arrange(c->mon); -} - -void -propertynotify(XEvent *e) -{ - Client *c; - Window trans; - XPropertyEvent *ev = &e->xproperty; - - if ((c = wintosystrayicon(ev->window))) { - if (ev->atom == XA_WM_NORMAL_HINTS) { - updatesizehints(c); - updatesystrayicongeom(c, c->w, c->h); - } - else - updatesystrayiconstate(c, ev); - resizebarwin(selmon); - updatesystray(); - } - if ((ev->window == root) && (ev->atom == XA_WM_NAME)) - updatestatus(); - else if (ev->state == PropertyDelete) - return; /* ignore */ - else if ((c = wintoclient(ev->window))) { - switch(ev->atom) { - default: break; - case XA_WM_TRANSIENT_FOR: - if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && - (c->isfloating = (wintoclient(trans)) != NULL)) - arrange(c->mon); - break; - case XA_WM_NORMAL_HINTS: - updatesizehints(c); - break; - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if (c == c->mon->sel) - drawbar(c->mon); - } - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); - } -} - -void -quit(const Arg *arg) -{ - running = 0; -} - -Monitor * -recttomon(int x, int y, int w, int h) -{ - Monitor *m, *r = selmon; - int a, area = 0; - - for (m = mons; m; m = m->next) - if ((a = INTERSECT(x, y, w, h, m)) > area) { - area = a; - r = m; - } - return r; -} - -void -removesystrayicon(Client *i) -{ - Client **ii; - - if (!showsystray || !i) - return; - for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); - if (ii) - *ii = i->next; - free(i); -} - - -void -resize(Client *c, int x, int y, int w, int h, int interact) -{ - if (applysizehints(c, &x, &y, &w, &h, interact)) - resizeclient(c, x, y, w, h); -} - -void -resizebarwin(Monitor *m) { - unsigned int w = m->ww; - if (showsystray && m == systraytomon(m)) - w -= getsystraywidth(); - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); -} - -void -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->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; c->h = wc.height = h; - wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); -} - -void -resizemouse(const Arg *arg) -{ - int ocx, ocy, nw, nh; - Client *c; - Monitor *m; - XEvent ev; - Time lasttime = 0; - - if (!(c = selmon->sel)) - return; - if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ - return; - restack(selmon); - ocx = c->x; - ocy = c->y; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, - None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) - return; - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); - do { - XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); - switch(ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); - break; - case MotionNotify: - if ((ev.xmotion.time - lasttime) <= (1000 / 60)) - continue; - lasttime = ev.xmotion.time; - - nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); - nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); - if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww - && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) - { - if (!c->isfloating && selmon->lt[selmon->sellt]->arrange - && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) - togglefloating(NULL); - } - if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) - resize(c, c->x, c->y, nw, nh, 1); - break; - } - } while (ev.type != ButtonRelease); - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); - XUngrabPointer(dpy, CurrentTime); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); - if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { - sendmon(c, m); - selmon = m; - focus(NULL); - } -} - -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; - XWindowChanges wc; - - drawbar(m); - if (!m->sel) - return; - if (m->sel->isfloating || !m->lt[m->sellt]->arrange) - XRaiseWindow(dpy, m->sel->win); - if (m->lt[m->sellt]->arrange) { - wc.stack_mode = Below; - wc.sibling = m->barwin; - for (c = m->stack; c; c = c->snext) - if (!c->isfloating && ISVISIBLE(c)) { - XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); - wc.sibling = c->win; - } - } - XSync(dpy, False); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); -} - -void -run(void) -{ - XEvent ev; - /* main event loop */ - XSync(dpy, False); - while (running && !XNextEvent(dpy, &ev)) - if (handler[ev.type]) - handler[ev.type](&ev); /* call handler */ -} - -void -runAutostart(void) { - system("cd ~/.dwm; ./autostart_blocking.sh"); - system("cd ~/.dwm; ./autostart.sh &"); -} - -void -scan(void) -{ - unsigned int i, num; - Window d1, d2, *wins = NULL; - XWindowAttributes wa; - - if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { - for (i = 0; i < num; i++) { - if (!XGetWindowAttributes(dpy, wins[i], &wa) - || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) - continue; - if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) - manage(wins[i], &wa); - } - for (i = 0; i < num; i++) { /* now the transients */ - if (!XGetWindowAttributes(dpy, wins[i], &wa)) - continue; - if (XGetTransientForHint(dpy, wins[i], &d1) - && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) - manage(wins[i], &wa); - } - if (wins) - XFree(wins); - } -} - -void -sendmon(Client *c, Monitor *m) -{ - if (c->mon == m) - return; - unfocus(c, 1); - detach(c); - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ - attach(c); - attachstack(c); - focus(NULL); - arrange(NULL); -} - -void -setclientstate(Client *c, long state) -{ - long data[] = { state, None }; - - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, - PropModeReplace, (unsigned char *)data, 2); -} - -int -sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) -{ - int n; - Atom *protocols, mt; - int exists = 0; - XEvent ev; - - 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 = w; - ev.xclient.message_type = mt; - ev.xclient.format = 32; - 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; -} - -void -setfocus(Client *c) -{ - if (!c->neverfocus) { - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - XChangeProperty(dpy, root, netatom[NetActiveWindow], - XA_WINDOW, 32, PropModeReplace, - (unsigned char *) &(c->win), 1); - } - sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); -} - -void -setfullscreen(Client *c, int fullscreen) -{ - if (fullscreen && !c->isfullscreen) { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); - c->isfullscreen = 1; - c->oldstate = c->isfloating; - c->oldbw = c->bw; - c->bw = 0; - c->isfloating = 1; - resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); - XRaiseWindow(dpy, c->win); - } else if (!fullscreen && c->isfullscreen){ - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = 0; - c->isfloating = c->oldstate; - c->bw = c->oldbw; - c->x = c->oldx; - c->y = c->oldy; - c->w = c->oldw; - c->h = c->oldh; - resizeclient(c, c->x, c->y, c->w, c->h); - arrange(c->mon); - } -} - -void -setlayout(const Arg *arg) -{ - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if (selmon->sel) - arrange(selmon); - else - drawbar(selmon); -} - -/* arg > 1.0 will set mfact absolutely */ -void -setmfact(const Arg *arg) -{ - float f; - - if (!arg || !selmon->lt[selmon->sellt]->arrange) - return; - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if (f < 0.1 || f > 0.9) - return; - selmon->mfact = f; - arrange(selmon); -} - -void -setup(void) -{ - int i; - XSetWindowAttributes wa; - Atom utf8string; - - /* clean up any zombies immediately */ - sigchld(0); - - /* init screen */ - screen = DefaultScreen(dpy); - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - root = RootWindow(dpy, screen); - drw = drw_create(dpy, screen, root, sw, sh); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - bh = drw->fonts->h + 2; - updategeom(); - /* init atoms */ - utf8string = XInternAtom(dpy, "UTF8_STRING", False); - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); - wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); - wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); - netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); - netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); - netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); - netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); - netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); - netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); - netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); - netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); - 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); - /* init cursors */ - cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); - cursor[CurResize] = drw_cur_create(drw, XC_sizing); - cursor[CurMove] = drw_cur_create(drw, XC_fleur); - /* init appearance */ - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); - /* init system tray */ - updatesystray(); - /* init bars */ - updatebars(); - updatestatus(); - /* supporting window for NetWMCheck */ - wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wmcheckwin, 1); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, - PropModeReplace, (unsigned char *) "dwm", 3); - XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wmcheckwin, 1); - /* EWMH support per view */ - XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, - PropModeReplace, (unsigned char *) netatom, NetLast); - XDeleteProperty(dpy, root, netatom[NetClientList]); - /* select events */ - wa.cursor = cursor[CurNormal]->cursor; - wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask - |ButtonPressMask|PointerMotionMask|EnterWindowMask - |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; - XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); - focus(NULL); -} - - -void -seturgent(Client *c, int urg) -{ - XWMHints *wmh; - - c->isurgent = urg; - if (!(wmh = XGetWMHints(dpy, c->win))) - return; - wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); - XSetWMHints(dpy, c->win, wmh); - XFree(wmh); -} - -void -showhide(Client *c) -{ - if (!c) - return; - if (ISVISIBLE(c)) { - /* show clients top down */ - XMoveWindow(dpy, c->win, c->x, c->y); - if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) - resize(c, c->x, c->y, c->w, c->h, 0); - showhide(c->snext); - } else { - /* hide clients bottom up */ - showhide(c->snext); - XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); - } -} - -void -sigchld(int unused) -{ - if (signal(SIGCHLD, sigchld) == SIG_ERR) - die("can't install SIGCHLD handler:"); - while (0 < waitpid(-1, NULL, WNOHANG)); -} - -void -spawn(const Arg *arg) -{ - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - execvp(((char **)arg->v)[0], (char **)arg->v); - fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); - perror(" failed"); - exit(EXIT_SUCCESS); - } -} - -void -tag(const Arg *arg) -{ - if (selmon->sel && arg->ui & TAGMASK) { - selmon->sel->tags = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); - } -} - -void -tagmon(const Arg *arg) -{ - if (!selmon->sel || !mons->next) - return; - sendmon(selmon->sel, dirtomon(arg->i)); -} - -void -tile(Monitor *m) -{ - unsigned int i, n, h, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); - my += HEIGHT(c); - } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); - ty += HEIGHT(c); - } -} - -void -togglebar(const Arg *arg) -{ - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - resizebarwin(selmon); - if (showsystray) { - XWindowChanges wc; - if (!selmon->showbar) - wc.y = -bh; - else if (selmon->showbar) { - wc.y = 0; - if (!selmon->topbar) - wc.y = selmon->mh - bh; - } - XConfigureWindow(dpy, systray->win, CWY, &wc); - } - arrange(selmon); -} - -void -togglefloating(const Arg *arg) -{ - if (!selmon->sel) - return; - if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; - if (selmon->sel->isfloating) - resize(selmon->sel, selmon->sel->x, selmon->sel->y, - selmon->sel->w, selmon->sel->h, 0); - arrange(selmon); -} - -void -toggletag(const Arg *arg) -{ - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - focus(NULL); - arrange(selmon); - } -} - -void -toggleview(const Arg *arg) -{ - unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); - - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } -} - -void -unfocus(Client *c, int setfocus) -{ - if (!c) - return; - grabbuttons(c, 0); - XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); - if (setfocus) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); - } -} - -void -unmanage(Client *c, int destroyed) -{ - Monitor *m = c->mon; - XWindowChanges wc; - - detach(c); - detachstack(c); - if (!destroyed) { - wc.border_width = c->oldbw; - XGrabServer(dpy); /* avoid race conditions */ - XSetErrorHandler(xerrordummy); - XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ - XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - setclientstate(c, WithdrawnState); - XSync(dpy, False); - XSetErrorHandler(xerror); - XUngrabServer(dpy); - } - free(c); - focus(NULL); - updateclientlist(); - arrange(m); -} - -void -unmapnotify(XEvent *e) -{ - Client *c; - XUnmapEvent *ev = &e->xunmap; - - if ((c = wintoclient(ev->window))) { - if (ev->send_event) - setclientstate(c, WithdrawnState); - else - unmanage(c, 0); - } - else if ((c = wintosystrayicon(ev->window))) { - /* KLUDGE! sometimes icons occasionally unmap their windows, but do - * _not_ destroy them. We map those windows back */ - XMapRaised(dpy, c->win); - updatesystray(); - } -} - -void -updatebars(void) -{ - unsigned int w; - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, - .background_pixmap = ParentRelative, - .event_mask = ButtonPressMask|ExposureMask - }; - XClassHint ch = {"dwm", "dwm"}; - for (m = mons; m; m = m->next) { - if (m->barwin) - continue; - w = m->ww; - 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); - if (showsystray && m == systraytomon(m)) - XMapRaised(dpy, systray->win); - XMapRaised(dpy, m->barwin); - XSetClassHint(dpy, m->barwin, &ch); - } -} - -void -updatebarpos(Monitor *m) -{ - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + bh : m->wy; - } else - m->by = -bh; -} - -void -updateclientlist() -{ - Client *c; - Monitor *m; - - XDeleteProperty(dpy, root, netatom[NetClientList]); - for (m = mons; m; m = m->next) - for (c = m->clients; c; c = c->next) - XChangeProperty(dpy, root, netatom[NetClientList], - XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); -} - -int -updategeom(void) -{ - int dirty = 0; - -#ifdef XINERAMA - if (XineramaIsActive(dpy)) { - int i, j, n, nn; - Client *c; - Monitor *m; - XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); - XineramaScreenInfo *unique = NULL; - - for (n = 0, m = mons; m; m = m->next, n++); - /* only consider unique geometries as separate screens */ - unique = ecalloc(nn, sizeof(XineramaScreenInfo)); - for (i = 0, j = 0; i < nn; i++) - if (isuniquegeom(unique, j, &info[i])) - memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); - XFree(info); - nn = j; - if (n <= nn) { /* new monitors available */ - for (i = 0; i < (nn - n); i++) { - for (m = mons; m && m->next; m = m->next); - if (m) - m->next = createmon(); - else - mons = createmon(); - } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n - || unique[i].x_org != m->mx || unique[i].y_org != m->my - || unique[i].width != m->mw || unique[i].height != m->mh) - { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - } else { /* less monitors available nn < n */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - attachstack(c); - } - if (m == selmon) - selmon = mons; - cleanupmon(m); - } - } - free(unique); - } else -#endif /* XINERAMA */ - { /* default monitor setup */ - if (!mons) - mons = createmon(); - if (mons->mw != sw || mons->mh != sh) { - dirty = 1; - mons->mw = mons->ww = sw; - mons->mh = mons->wh = sh; - updatebarpos(mons); - } - } - if (dirty) { - selmon = mons; - selmon = wintomon(root); - } - return dirty; -} - -void -updatenumlockmask(void) -{ - unsigned int i, j; - XModifierKeymap *modmap; - - numlockmask = 0; - modmap = XGetModifierMapping(dpy); - for (i = 0; i < 8; i++) - for (j = 0; j < modmap->max_keypermod; j++) - if (modmap->modifiermap[i * modmap->max_keypermod + j] - == XKeysymToKeycode(dpy, XK_Num_Lock)) - numlockmask = (1 << i); - XFreeModifiermap(modmap); -} - -void -updatesizehints(Client *c) -{ - long msize; - XSizeHints size; - - if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) - /* size is uninitialized, ensure that size.flags aren't used */ - size.flags = PSize; - if (size.flags & PBaseSize) { - c->basew = size.base_width; - c->baseh = size.base_height; - } else if (size.flags & PMinSize) { - c->basew = size.min_width; - c->baseh = size.min_height; - } else - c->basew = c->baseh = 0; - if (size.flags & PResizeInc) { - c->incw = size.width_inc; - c->inch = size.height_inc; - } else - c->incw = c->inch = 0; - if (size.flags & PMaxSize) { - c->maxw = size.max_width; - c->maxh = size.max_height; - } else - c->maxw = c->maxh = 0; - if (size.flags & PMinSize) { - c->minw = size.min_width; - c->minh = size.min_height; - } else if (size.flags & PBaseSize) { - c->minw = size.base_width; - c->minh = size.base_height; - } else - c->minw = c->minh = 0; - if (size.flags & PAspect) { - c->mina = (float)size.min_aspect.y / size.min_aspect.x; - c->maxa = (float)size.max_aspect.x / size.max_aspect.y; - } else - c->maxa = c->mina = 0.0; - c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); -} - -void -updatestatus(void) -{ - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) - strcpy(stext, "dwm-"VERSION); - drawbar(selmon); - updatesystray(); -} - -void -updatesystrayicongeom(Client *i, int w, int h) -{ - if (i) { - 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)); - applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); - /* force icons into the systray dimenons if they don't want to */ - if (i->h > bh) { - if (i->w == i->h) - i->w = bh; - else - i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); - i->h = bh; - } - } -} - -void -updatesystrayiconstate(Client *i, XPropertyEvent *ev) -{ - long flags; - int code = 0; - - if (!showsystray || !i || ev->atom != xatom[XembedInfo] || - !(flags = getatomprop(i, xatom[XembedInfo]))) - return; - - if (flags & XEMBED_MAPPED && !i->tags) { - i->tags = 1; - code = XEMBED_WINDOW_ACTIVATE; - XMapRaised(dpy, i->win); - setclientstate(i, NormalState); - } - else if (!(flags & XEMBED_MAPPED) && i->tags) { - i->tags = 0; - code = XEMBED_WINDOW_DEACTIVATE; - XUnmapWindow(dpy, i->win); - setclientstate(i, WithdrawnState); - } - else - return; - sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, - systray->win, XEMBED_EMBEDDED_VERSION); -} - -void -updatesystray(void) -{ - XSetWindowAttributes wa; - XWindowChanges wc; - Client *i; - Monitor *m = systraytomon(NULL); - unsigned int x = m->mx + m->mw; - unsigned int w = 1; - - if (!showsystray) - return; - if (!systray) { - /* 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, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); - wa.event_mask = ButtonPressMask | ExposureMask; - wa.override_redirect = True; - wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - XSelectInput(dpy, systray->win, SubstructureNotifyMask); - XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, - PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); - 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) { - 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 (w = 0, i = systray->icons; i; i = i->next) { - /* make sure the background color stays the same */ - wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); - XMapRaised(dpy, i->win); - w += systrayspacing; - i->x = w; - XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); - w += i->w; - if (i->mon != m) - i->mon = m; - } - w = w ? w + systrayspacing : 1; - x -= w; - XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); - 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][ColBg].pixel); - XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); - XSync(dpy, False); -} - -void -updatetitle(Client *c) -{ - if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) - gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); - if (c->name[0] == '\0') /* hack to mark broken clients */ - strcpy(c->name, broken); -} - -void -updatewindowtype(Client *c) -{ - Atom state = getatomprop(c, netatom[NetWMState]); - Atom wtype = getatomprop(c, netatom[NetWMWindowType]); - - if (state == netatom[NetWMFullscreen]) - setfullscreen(c, 1); - if (wtype == netatom[NetWMWindowTypeDialog]) - c->isfloating = 1; -} - -void -updatewmhints(Client *c) -{ - XWMHints *wmh; - - if ((wmh = XGetWMHints(dpy, c->win))) { - if (c == selmon->sel && wmh->flags & XUrgencyHint) { - wmh->flags &= ~XUrgencyHint; - XSetWMHints(dpy, c->win, wmh); - } else - c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; - if (wmh->flags & InputHint) - c->neverfocus = !wmh->input; - else - c->neverfocus = 0; - XFree(wmh); - } -} - -void -view(const Arg *arg) -{ - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); -} - -Client * -wintoclient(Window w) -{ - Client *c; - Monitor *m; - - for (m = mons; m; m = m->next) - for (c = m->clients; c; c = c->next) - if (c->win == w) - return c; - return NULL; -} - -Client * -wintosystrayicon(Window w) { - Client *i = NULL; - - if (!showsystray || !w) - return i; - for (i = systray->icons; i && i->win != w; i = i->next) ; - return i; -} - -Monitor * -wintomon(Window w) -{ - int x, y; - Client *c; - Monitor *m; - - if (w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for (m = mons; m; m = m->next) - if (w == m->barwin) - return m; - if ((c = wintoclient(w))) - return c->mon; - return selmon; -} - -/* There's no way to check accesses to destroyed windows, thus those cases are - * ignored (especially on UnmapNotify's). Other types of errors call Xlibs - * default error handler, which may call exit. */ -int -xerror(Display *dpy, XErrorEvent *ee) -{ - if (ee->error_code == BadWindow - || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) - || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) - || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) - || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) - || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) - || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) - || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) - || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) - return 0; - fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", - ee->request_code, ee->error_code); - return xerrorxlib(dpy, ee); /* may call exit */ -} - -int -xerrordummy(Display *dpy, XErrorEvent *ee) -{ - return 0; -} - -/* Startup Error handler to check if another window manager - * is already running. */ -int -xerrorstart(Display *dpy, XErrorEvent *ee) -{ - die("dwm: another window manager is already running"); - return -1; -} - -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 -zoom(const Arg *arg) -{ - Client *c = selmon->sel; - - if (!selmon->lt[selmon->sellt]->arrange - || (selmon->sel && selmon->sel->isfloating)) - return; - if (c == nexttiled(selmon->clients)) - if (!c || !(c = nexttiled(c->next))) - return; - pop(c); -} - -int -main(int argc, char *argv[]) -{ - if (argc == 2 && !strcmp("-v", argv[1])) - die("dwm-"VERSION); - else if (argc != 1) - die("usage: dwm [-v]"); - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("warning: no locale support\n", stderr); - if (!(dpy = XOpenDisplay(NULL))) - die("dwm: cannot open display"); - checkotherwm(); - setup(); -#ifdef __OpenBSD__ - if (pledge("stdio proc exec", NULL) == -1) - die("pledge"); -#endif /* __OpenBSD__ */ - scan(); - runAutostart(); - run(); - cleanup(); - XCloseDisplay(dpy); - return EXIT_SUCCESS; -} diff --git a/dwm.o b/dwm.o deleted file mode 100644 index 8571e07e55dde5e3fc78e95923c2ba3fb12f5869..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72072 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 diff --git a/dwm.png b/dwm.png deleted file mode 100644 index b1f9ba7e5f4cc7350ee2392ebcea5fcbe00fb49b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^2Y@($g9*gC@m3f}u_bxCyDx`7I;J! zGca%iWx0hJ8D`Cq01C2~c>21sUt<^MF=V?Ztt9{yk}YwKC~?lu%}vcKVQ?-=O)N=G zQ7F$W$xsN%NL6t6^bL5QqM8R(c+=CxF{I+w+q;fj4F)_6j>`Z3pZ>_($QEQ&92OXP z%lpEKGwG8$G-U1H{@Y%;mx-mNK|p|siBVAj$Z~Mt-~h6K0!}~{PyozQ07(f5fTdVi zm=-zT`NweeJ#%S&{fequZGmkDDC*%x$$Sa*fAP=$`nJkhx1Y~k<8b2;Hq)FOdV=P$ q&oWzoxz_&nv&n0)xBzV8k*jsxheTIy&cCY600f?{elF{r5}E*x)opSB diff --git a/dwmgit.diff b/dwmgit.diff deleted file mode 100644 index 9e6b27c..0000000 --- a/dwmgit.diff +++ /dev/null @@ -1,747 +0,0 @@ -Authors: - Jan Christoph Ebersbach , inspired by http://code.google.com/p/dwm-plus - Eric Pruitt - Yury Shvedov -URL: http://dwm.suckless.org/patches/systray -Implements a system tray for dwm. - -Contributors: -- Carlos Pita, thanks for investigating multi monitor issues and sending in a - patch - -Index: dwm/config.def.h -=================================================================== ---- dwm/config.def.h.orig -+++ dwm/config.def.h -@@ -3,6 +3,10 @@ - /* appearance */ - 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 int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -+static const int showsystray = 1; /* 0 means no systray */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ - static const char *fonts[] = { "Hack:size=8.5:antialias=true:autohint=false" }; -Index: dwm/dwm.c -=================================================================== ---- dwm/dwm.c.orig -+++ dwm/dwm.c -@@ -59,12 +59,30 @@ - #define ColBorder 2 - #define ColFloat 3 - -+#define SYSTEM_TRAY_REQUEST_DOCK 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 { SchemeNorm, SchemeSel }; /* color schemes */ - enum { NetSupported, NetWMName, NetWMState, NetWMCheck, -+ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, NetWMWindowTypeDock, - 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 */ -@@ -146,6 +164,12 @@ typedef struct { - int monitor; - } Rule; - -+typedef struct Systray Systray; -+struct Systray { -+ Window win; -+ Client *icons; -+}; -+ - struct Clientlist { - Client *clients; - Client *stack; -@@ -184,8 +208,10 @@ static void focus(Client *c); - 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 int getrootptr(int *x, int *y); - static long getstate(Window w); -+static unsigned int getsystraywidth(); - static int gettextprop(Window w, Atom atom, char *text, unsigned int size); - static void grabbuttons(Client *c, int focused); - static void grabkeys(void); -@@ -203,13 +229,16 @@ static void pop(Client *); - 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(Client *i); - static void resize(Client *c, int x, int y, int w, int h, int 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); - static void run(void); - static void scan(void); --static int sendevent(Client *c, Atom proto); -+static int 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); -@@ -222,6 +251,7 @@ static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); - static void swapfocus(); -+static Monitor *systraytomon(Monitor *m); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -@@ -239,18 +269,23 @@ static void updateclientlist(void); - static void updatenumlockmask(void); - static void updatesizehints(Client *c); - static void updatestatus(void); -+static void updatesystray(void); -+static void updatesystrayicongeom(Client *i, int w, int h); -+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); - 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 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); - static void zoom(const Arg *arg); - - /* variables */ -+static Systray *systray = NULL; - static Client *prevclient = NULL; - static const char broken[] = "broken"; - static char stext[256]; -@@ -274,9 +309,10 @@ static void (*handler[LASTEvent]) (XEven - [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 int running = 1; - static int restart = 0; - static Cur *cursor[CurLast]; -@@ -558,6 +594,11 @@ cleanup(void) - XUngrabKey(dpy, AnyKey, AnyModifier, root); - while (mons) - cleanupmon(mons); -+ if (showsystray) { -+ XUnmapWindow(dpy, systray->win); -+ XDestroyWindow(dpy, systray->win); -+ free(systray); -+ } - for (i = 0; i < CurLast; i++) - drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) -@@ -588,9 +629,54 @@ cleanupmon(Monitor *mon) - void - clientmessage(XEvent *e) - { -+ XWindowAttributes wa; -+ XSetWindowAttributes swa; - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); - -+ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { -+ /* add systray icons */ -+ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { -+ if (!(c = (Client *)calloc(1, sizeof(Client)))) -+ die("fatal: could not malloc() %u bytes\n", sizeof(Client)); -+ if (!(c->win = cme->data.l[2])) { -+ free(c); -+ return; -+ } -+ c->mon = selmon; -+ c->next = systray->icons; -+ systray->icons = c; -+ XGetWindowAttributes(dpy, c->win, &wa); -+ c->x = c->oldx = c->y = c->oldy = 0; -+ c->w = c->oldw = wa.width; -+ c->h = c->oldh = wa.height; -+ c->oldbw = wa.border_width; -+ c->bw = 0; -+ c->isfloating = True; -+ /* reuse tags field as mapped status */ -+ c->tags = 1; -+ updatesizehints(c); -+ updatesystrayicongeom(c, wa.width, wa.height); -+ XAddToSaveSet(dpy, c->win); -+ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); -+ XReparentWindow(dpy, c->win, systray->win, 0, 0); -+ /* use parents background color */ -+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; -+ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); -+ XChangeProperty(dpy, c->win, netatom[NetWMWindowType], XA_ATOM, 32, -+ PropModeReplace, (unsigned char *)&netatom[NetWMWindowTypeDock], 1); -+ 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); -+ } -+ return; -+ } - if (!c) - return; - if (cme->message_type == netatom[NetWMState]) { -@@ -643,7 +729,7 @@ configurenotify(XEvent *e) - for (c = m->cl->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); -- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -+ resizebarwin(m); - } - focus(NULL); - arrange(NULL); -@@ -770,6 +856,11 @@ destroynotify(XEvent *e) - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); -+ else if ((c = wintosystrayicon(ev->window))) { -+ removesystrayicon(c); -+ resizebarwin(selmon); -+ updatesystray(); -+ } - } - - void -@@ -813,19 +904,24 @@ dirtomon(int dir) - void - drawbar(Monitor *m) - { -- int x, w, sw = 0; -+ int x, w, sw, stw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; - -+ if(showsystray && m == systraytomon(m)) -+ stw = getsystraywidth(); -+ - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon || 1) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ - drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); -+ drw_text(drw, m->ww - sw - stw, 0, sw, bh, 0, stext, 0); - } - -+ resizebarwin(m); - for(c = m->cl->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) -@@ -846,7 +942,7 @@ drawbar(Monitor *m) - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - -- if ((w = m->ww - sw - x) > bh) { -+ if ((w = m->ww - sw - stw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); -@@ -857,7 +953,7 @@ drawbar(Monitor *m) - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } -- drw_map(drw, m->barwin, 0, 0, m->ww, bh); -+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); - } - - void -@@ -894,8 +990,11 @@ expose(XEvent *e) - 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 -@@ -983,10 +1082,17 @@ getatomprop(Client *c, Atom prop) - unsigned long dl; - unsigned char *p = NULL; - Atom da, atom = None; -+ /* FIXME getatomprop should return the number of items and a pointer to -+ * the stored data instead of this workaround */ -+ Atom req = XA_ATOM; -+ if (prop == xatom[XembedInfo]) -+ req = xatom[XembedInfo]; - -- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, -+ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, - &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; -+ if (da == xatom[XembedInfo] && dl == 2) -+ atom = ((Atom *)p)[1]; - XFree(p); - } - return atom; -@@ -1020,6 +1126,16 @@ getstate(Window w) - return result; - } - -+unsigned int -+getsystraywidth() -+{ -+ unsigned int w = 0; -+ Client *i; -+ if(showsystray) -+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; -+ return w ? w + systrayspacing : 1; -+} -+ - int - gettextprop(Window w, Atom atom, char *text, unsigned int size) - { -@@ -1124,7 +1240,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); -@@ -1223,6 +1339,12 @@ maprequest(XEvent *e) - { - static XWindowAttributes wa; - XMapRequestEvent *ev = &e->xmaprequest; -+ 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; -@@ -1356,6 +1478,16 @@ propertynotify(XEvent *e) - Window trans; - XPropertyEvent *ev = &e->xproperty; - -+ if ((c = wintosystrayicon(ev->window))) { -+ if (ev->atom == XA_WM_NORMAL_HINTS) { -+ updatesizehints(c); -+ updatesystrayicongeom(c, c->w, c->h); -+ } -+ else -+ updatesystrayiconstate(c, ev); -+ resizebarwin(selmon); -+ updatesystray(); -+ } - if ((ev->window == root) && (ev->atom == XA_WM_NAME)) - updatestatus(); - else if (ev->state == PropertyDelete) -@@ -1409,6 +1541,20 @@ recttomon(int x, int y, int w, int h) - } - - void -+removesystrayicon(Client *i) -+{ -+ Client **ii; -+ -+ if (!showsystray || !i) -+ return; -+ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); -+ if (ii) -+ *ii = i->next; -+ free(i); -+} -+ -+ -+void - resize(Client *c, int x, int y, int w, int h, int interact) - { - if (applysizehints(c, &x, &y, &w, &h, interact)) -@@ -1416,6 +1562,14 @@ resize(Client *c, int x, int y, int w, i - } - - void -+resizebarwin(Monitor *m) { -+ unsigned int w = m->ww; -+ if (showsystray && m == systraytomon(m)) -+ w -= getsystraywidth(); -+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); -+} -+ -+void - resizeclient(Client *c, int x, int y, int w, int h) - { - XWindowChanges wc; -@@ -1488,6 +1642,19 @@ 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; -@@ -1574,26 +1741,36 @@ setclientstate(Client *c, long state) - } - - int --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; - int exists = 0; - 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; - } -@@ -1607,7 +1784,7 @@ setfocus(Client *c) - XA_WINDOW, 32, PropModeReplace, - (unsigned char *) &(c->win), 1); - } -- sendevent(c, wmatom[WMTakeFocus]); -+ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); - } - - void -@@ -1701,6 +1878,10 @@ setup(void) - wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); - netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); -+ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); -+ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); -+ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); -+ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); - netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); - netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); - netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); -@@ -1709,6 +1890,9 @@ setup(void) - netatom[NetWMWindowTypeDock] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", 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); - /* init cursors */ - cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); - cursor[CurResize] = drw_cur_create(drw, XC_sizing); -@@ -1717,6 +1901,8 @@ setup(void) - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 4); -+ /* init system tray */ -+ updatesystray(); - /* init bars */ - updatebars(); - updatestatus(); -@@ -1765,10 +1951,12 @@ showhide(Client *c) - if (ISVISIBLE(c, c->mon)) { - /* show clients top down */ - XMoveWindow(dpy, c->win, c->x, c->y); -- if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) -- if (c->isfloating) -+ if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) { -+ if (c->isfloating) { - keepfloatingposition(c); -+ } - resize(c, c->x, c->y, c->w, c->h, 0); -+ } - showhide(c->snext); - } else { - /* hide clients bottom up */ -@@ -1895,7 +2083,18 @@ togglebar(const Arg *arg) - { - selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; - updatebarpos(selmon); -- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); -+ resizebarwin(selmon); -+ if (showsystray) { -+ XWindowChanges wc; -+ if (!selmon->showbar) -+ wc.y = -bh; -+ else if (selmon->showbar) { -+ wc.y = 0; -+ if (!selmon->topbar) -+ wc.y = selmon->mh - bh; -+ } -+ XConfigureWindow(dpy, systray->win, CWY, &wc); -+ } - arrange(selmon); - } - -@@ -2040,11 +2239,18 @@ unmapnotify(XEvent *e) - else - unmanage(c, 0); - } -+ else if ((c = wintosystrayicon(ev->window))) { -+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do -+ * _not_ destroy them. We map those windows back */ -+ XMapRaised(dpy, c->win); -+ updatesystray(); -+ } - } - - void - updatebars(void) - { -+ unsigned int w; - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, -@@ -2055,12 +2261,17 @@ updatebars(void) - 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 == 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); - XChangeProperty(dpy, m->barwin, netatom[NetWMWindowType], XA_ATOM, 32, - PropModeReplace, (unsigned char *) & netatom[NetWMWindowTypeDock], 1); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); -+ if (showsystray && m == systraytomon(m)) -+ XMapRaised(dpy, systray->win); - XMapRaised(dpy, m->barwin); - XSetClassHint(dpy, m->barwin, &ch); - } -@@ -2246,6 +2457,123 @@ updatestatus(void) - strcpy(stext, "dwm-"VERSION); - for(m = mons; m; m = m->next) - drawbar(m); -+ updatesystray(); -+} -+ -+void -+updatesystrayicongeom(Client *i, int w, int h) -+{ -+ if (i) { -+ 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)); -+ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); -+ /* force icons into the systray dimenons if they don't want to */ -+ if (i->h > bh) { -+ if (i->w == i->h) -+ i->w = bh; -+ else -+ i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); -+ i->h = bh; -+ } -+ } -+} -+ -+void -+updatesystrayiconstate(Client *i, XPropertyEvent *ev) -+{ -+ long flags; -+ int code = 0; -+ -+ if (!showsystray || !i || ev->atom != xatom[XembedInfo] || -+ !(flags = getatomprop(i, xatom[XembedInfo]))) -+ return; -+ -+ if (flags & XEMBED_MAPPED && !i->tags) { -+ i->tags = 1; -+ code = XEMBED_WINDOW_ACTIVATE; -+ XMapRaised(dpy, i->win); -+ setclientstate(i, NormalState); -+ } -+ else if (!(flags & XEMBED_MAPPED) && i->tags) { -+ i->tags = 0; -+ code = XEMBED_WINDOW_DEACTIVATE; -+ XUnmapWindow(dpy, i->win); -+ setclientstate(i, WithdrawnState); -+ } -+ else -+ return; -+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, -+ systray->win, XEMBED_EMBEDDED_VERSION); -+} -+ -+void -+updatesystray(void) -+{ -+ XSetWindowAttributes wa; -+ XWindowChanges wc; -+ Client *i; -+ Monitor *m = systraytomon(NULL); -+ unsigned int x = m->mx + m->mw; -+ unsigned int w = 1; -+ -+ if (!showsystray) -+ return; -+ if (!systray) { -+ /* 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, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); -+ wa.event_mask = ButtonPressMask | ExposureMask; -+ wa.override_redirect = True; -+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; -+ XSelectInput(dpy, systray->win, SubstructureNotifyMask); -+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, -+ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); -+ XChangeProperty(dpy, systray->win, netatom[NetWMWindowType], XA_ATOM, 32, -+ PropModeReplace, (unsigned char *)&netatom[NetWMWindowTypeDock], 1); -+ 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) { -+ 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 (w = 0, i = systray->icons; i; i = i->next) { -+ /* make sure the background color stays the same */ -+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; -+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); -+ XMapRaised(dpy, i->win); -+ w += systrayspacing; -+ i->x = w; -+ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); -+ w += i->w; -+ if (i->mon != m) -+ i->mon = m; -+ } -+ w = w ? w + systrayspacing : 1; -+ x -= w; -+ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); -+ 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][ColBg].pixel); -+ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); -+ XSync(dpy, False); - } - - void -@@ -2344,6 +2672,16 @@ wintoclient(Window w) - return NULL; - } - -+Client * -+wintosystrayicon(Window w) { -+ Client *i = NULL; -+ -+ if (!showsystray || !w) -+ return i; -+ for (i = systray->icons; i && i->win != w; i = i->next) ; -+ return i; -+} -+ - Monitor * - wintomon(Window w) - { -@@ -2397,6 +2735,22 @@ xerrorstart(Display *dpy, XErrorEvent *e - return -1; - } - -+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 - zoom(const Arg *arg) - { diff --git a/util.o b/util.o deleted file mode 100644 index 3d20212b46e0b805b7e50d3db51c5fa4c9757933..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2224 zcmbW1&1(}u6u@7aYGZAaSUptgA%{^C&?OPXT2#^|ZPv21Ra1)|jA^`)Y3zzGlw>7e=pI|Z9AD@GTe0*bcHh#^*b_@XXEoGQ>Qd{$AQ~!G>yFga zrBgV;*(bI7MO|KGYdCvB4Zmt-9?KJF9(6g+0ax|41unhJr1SY= zrVk(yi}eM934PWq76T`gh!PHz@GsP`vCcjmB(7`cz%}o8^>nm(R&arCWCtt{z%SDM zUjN;eVecCE^>W{S?wjy>IB{0gb1Q7roxE@^$w}NGy&O`28``AVmg$E7 zdv1_sb#`tgbE^||m(;(tSIG9@@beg1(Y`uyr3t4~b&8KQ;loY%D01pk^kTF89OX6;Nkx{50dRIiehjZ$mZmQq`v`HwQhLDro5L}!KDCMgK zGd+pgG#WZ5EJM$y6;q!#L77UMX;3E1Wl)SFO(;B~L_o zQ|bPY9Ku1|{)HH^txK^ac6=Ba)!c4=gx5TZS{AXs=vVl}`a(z1L3UUKaD9OX1Z-U7 z34I3r!j?nloS;MOWzOVxlIqO!eEKfPVt<~C=yW>24+K%fbJ6)xuE-bXN6XmPMg*_< q`a;t;LewC?$lryw{p`rU!r=r>B(ZM`eV?83J^a(3lXA(l=l=uAuLd*#