aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--LICENSE37
-rw-r--r--Makefile7
-rw-r--r--README.org89
-rw-r--r--config.h200
-rw-r--r--config.mk11
-rw-r--r--drw.c1
-rw-r--r--dwm.112
-rw-r--r--dwm.c729
-rw-r--r--focusurgent.c14
9 files changed, 775 insertions, 325 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d221f09
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,37 @@
+MIT/X Consortium License
+
+© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
+© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
+© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
+© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
+© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
+© 2007-2009 Christof Musik <christof at sendfax dot de>
+© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
+© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
+© 2008 Martin Hurton <martin dot hurton at gmail dot com>
+© 2008 Neale Pickett <neale dot woozle dot org>
+© 2009 Mate Nagy <mnagy at port70 dot net>
+© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
+© 2010-2012 Connor Lane Smith <cls@lubutu.com>
+© 2011 Christoph Lohmann <20h@r-36.net>
+© 2015-2016 Quentin Rameau <quinq@fifth.space>
+© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
+© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/Makefile b/Makefile
index 8783714..9ae64c5 100644
--- a/Makefile
+++ b/Makefile
@@ -19,18 +19,15 @@ options:
${OBJ}: config.h config.mk
-config.h:
- cp config.def.h $@
-
dwm: ${OBJ}
- ${CC} -o $@ ${OBJ} ${LDFLAGS} -O2
+ ${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
dist: clean
mkdir -p dwm-${VERSION}
- cp -R LICENSE Makefile README config.def.h config.mk\
+ cp -R LICENSE Makefile README config.mk\
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
gzip dwm-${VERSION}.tar
diff --git a/README.org b/README.org
index 30a332e..5a00b6b 100644
--- a/README.org
+++ b/README.org
@@ -1,26 +1,25 @@
-* Joe's dwm (the dynamic window manager) build
+#+TITLE: Joe's dwm (the dynamic window manager) build
The original [[https://dwm.suckless.org/][dwm]] build I used to run. Based on version 6.2.
/Note:/ as I am not using dwm anymore, developpement on my build might be stuck on this version.
-** Dependencies
-**** Required:
+* Dependencies
+** Required:
- ~gcc~
- ~make~
- ~xorg~
- ~libX11~
- ~libXft~
-**** Optional:
+** Optional:
- ~st~ find my custom improved build [[https://github.com/JozanLeClerc/st][here]]
- - ~slock~
- ~dmenu~
-** Installation
+* Installation
To install this open a terminal and run these commands:
#+BEGIN_SRC shell
-git clone https://github.com/JozanLeClerc/dwm-laptop.git
-cd dwm-laptop
+git clone git://jozanleclerc.xyz/jozan/dwm.git
+cd dwm
sudo make clean install
#+END_SRC
To use it as a default WM, if you are using xinit, add this to your ~.xinitrc~:
@@ -29,65 +28,43 @@ exec dwm
#+END_SRC
I am not shure about how to set it up on regular desktop managers like ~gdm~ or ~lightdm~.
-** Bindings
-*Window* or *tile* is being called *stack* in this segment as it an apropriate name.
-
+* Bindings
Some of the main key bindings:
-- *switch* to workspace 1-10 with ~super+{F1-F10}~
-- *show all workspaces* at once with ~super+F12~
-- *move* selected stack to workspace 1-10 with ~super+shift+{F1-F10}~
-- *fire up* ~st~ terminal with ~super+return~. See how to set it to another terminal emulator in [[#optional-config][optional config]]
+- *switch* to workspace 1-12 with ~super+{F1-F12}~
+- *move* selected stack to workspace 1-12 with ~super+shift+{F1-F12}~
+- *fire up* ~st~ terminal with ~super+return~
- *kill* selected stack with ~super+q~
- *cycle through* stacks down/up with ~super+j/k~
- *move* selected stack down/up with ~super+shift+j/k~
- *resize* master stack to left/right with ~super+h/l~
- *invoke* ~dmenu_run~ application launcher with ~super+p~. Get it [[https://tools.suckless.org/dmenu/][here]]
-- *invoke* ~slock~ screen locker with ~super+shift+l~. Get it [[https://tools.suckless.org/slock/][here]]
-- *invoke* ~QuteBrowser~ if installed with ~super+3~. See how to set it up to your favorite web browser in [[#optional-config][optional config]]
-- toggle *normal tiled mode* with ~super+s~
+- toggle *better tiled mode* with ~super+s~
- toggle *alternative tiled mode* with ~super+shift+s~
-- toggle *maximized mode* (monocle) on selected stack with ~super+f~
+- toggle *normal tiled mode* with ~super+t~
+- toggle *fullscreen mode* on selected stack with ~super+f~
- toggle *floating mode* on selected stack with ~super+space~
-- toggle *top bar* with ~super+escape~. Hidden by default
+- toggle *top bar* with ~super+b~. Hidden by default
+- *restart* dwm with ~super+shift+r~
- *exit* dwm with ~super+shift+e~
-** Optional config
-You might want to change my ~st~ invocation to your terminal emulator of choice.
-To do exactly this change:
-#+BEGIN_SRC c
-static const char *termcmd[] = { "st", NULL };
-#+END_SRC
-to:
-#+BEGIN_SRC c
-static const char *termcmd[] = { "your-beloved-terminal-emulator", NULL };
-#+END_SRC
-in ~config.h~ on *line 80*.
-
-To change web browser:
-#+BEGIN_SRC c
-static const char *qbcmd[] = { "qutebrowser", NULL };
-#+END_SRC
-to:
-#+BEGIN_SRC c
-static const char *qbcmd[] = { "your-favorite-web-browser", NULL };
-#+END_SRC
-in ~config.h~ on *line 81*.
-
-** Patches
+* Patches
List of patches in use:
-- ~singularborders~
-- ~alwaysfullscreen~
-- ~autostart~
-- ~bottmstack~
-- ~fakefullscreen~
-- ~fibonacci~
-- ~focusurgent~
-- ~movestack~
-- ~noborder~
-- ~pertag~
-- ~systray~
+- /actualfullscreen/
+- /alwayscenter/
+- /attachaside/
+- /cool-autostart/
+- /fibonacci/
+- /focusonclick/
+- /moveresize/
+- /movestack/
+- /noborder/
+- /pertag/
+- /restartsig/
+- /swallow/
-** More
+* More
Thanks for checking my custom ~dwm~ build.
-My own autostart script can be found under my [[https://github.com/JozanLeClerc/dotfiles][dotfiles]] repository. It should be placed in =~/.dwm= directory.
+My own autostart script can be found under my
+[[https://git.jozanleclerc.xyz/jozan/dotfiles-bsd/files.html][dotfiles-bsd]] repository. It should
+be placed in =~/.config/dwm= directory.
diff --git a/config.h b/config.h
index 58d101c..85e7d4c 100644
--- a/config.h
+++ b/config.h
@@ -1,51 +1,44 @@
/* See LICENSE file for copyright and license details. */
-/* appearance */
+/* 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 swallowfloating = 1; /* 1 means swallow floating windows by default */
static const int showbar = 0; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
+static const int focusonwheel = 0;
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 col_cyan[] = "#9d2121";
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
};
+static const char *const autostart[] = {
+ "/home/jozan/.config/dwm/dwmrc", NULL,
+ NULL /* terminate */
+};
+
/* tagging */
-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
+static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" };
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
- /* class instance title tags mask isfloating monitor */
- { "Gimp", NULL, NULL, 0, 1, -1 },
- { "Tor Browser", "TorLauncher", NULL, 0, 1, -1 },
- { "Tor Browser", "Navigator", NULL, 1 << 2, 0, -1 },
- { "Firefox", NULL, NULL, 1 << 2, 0, -1 },
- { "trayer", NULL, NULL, 1 << 8, 0, -1 },
- { "Surf", NULL, NULL, 1 << 2, 0, -1 },
- { "tabbed", NULL, NULL, 1 << 2, 0, -1 },
- { "jetbrains-studio", NULL, NULL, 1 << 1, 1, -1 },
- { "trayer", NULL, NULL, 1 << 9, 0, -1 },
- { NULL, "MyTestApp", NULL, 0, 1, 1 },
- { NULL, NULL, "neomutt", 1 << 8, 0, -1 },
- { NULL, NULL, "ncmpcpp", 1 << 7, 0, -1 },
- { NULL, NULL, "calcurse", 1 << 6, 0, -1 },
- { NULL, NULL, "newsboat", 1 << 5, 0, -1 },
- { NULL, NULL, "pulsemixer", 1 << 4, 0, -1 },
+ /* class instance title tags mask isfloating isterminal noswallow monitor */
+ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 },
+ { "Firefox", NULL, NULL, 1 << 2, 0, 0, -1, -1 },
+ { "Sxiv", NULL, NULL, 0, 0, 0, -1, -1 },
+ { "St", NULL, NULL, 0, 0, 1, 0, -1 },
+ { NULL, NULL, "DergodsRealmII", 0, 1, 0, 0, -1 },
+ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
};
/* layout(s) */
@@ -56,11 +49,11 @@ static const int resizehints = 0; /* 1 means respect size hints in tiled resi
#include "fibonacci.c"
static const Layout layouts[] = {
/* symbol arrange function */
- { "[\\]", dwindle }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
+ { "[\\]", dwindle },
{ "[@]", spiral },
- { "[]=", tile },
+ { "[]=", tile }, /* first entry is default */
+ { "[M]", monocle },
+ { "><>", NULL }, /* no layout function means floating behavior */
};
/* key definitions */
@@ -72,75 +65,101 @@ static const Layout layouts[] = {
{ 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 } }
+#define SHCMD(cmd) { .v = (const char*[]){ "/usr/local/bin/dash", "-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[] = { "st", NULL };
-static const char *qbcmd[] = { "qutebrowser", NULL };
-static const char *lockcmd[] = { "slock", NULL };
-static const char *backlinccmd[] = { "xbacklight", "-inc", "10", NULL };
-static const char *backldeccmd[] = { "xbacklight", "-dec", "10", NULL };
-static const char *volupcmd[] = { "amixer", "set", "Master", "5%+", NULL };
-static const char *voldowncmd[] = { "amixer", "set", "Master", "5%-", NULL };
-static const char *volmutecmd[] = { "amixer", "set", "Master", "toggle", NULL };
-static const char *refbarcmd[] = { "refbar", NULL };
+/* commands */
+static const char *termcmd[] = { "/usr/local/bin/st", NULL };
+static const char *dmenucmd[] = { "/usr/local/bin/dmenu_run", "-i", "-m", dmenumon, NULL };
+static const char *dmpccmd[] = { "/home/jozan/.local/bin/dmpc", NULL };
+static const char *vifmcmd[] = { "/usr/local/bin/st", "-e", "/usr/local/bin/vifm", NULL };
+static const char *nvimcmd[] = { "/usr/local/bin/st", "-e", "/usr/local/bin/nvim", NULL };
+static const char *ffcmd[] = { "/usr/local/bin/firefox", "--kiosk", "https://start.duckduckgo.com/", NULL };
+static const char *w3mcmd[] = { "/usr/local/bin/st", "-e", "/usr/local/bin/w3m", "https://start.duckduckgo.com/", NULL };
+static const char *blinccmd[] = { "/usr/local/bin/xbacklight", "-inc", "10", NULL };
+static const char *bldeccmd[] = { "/usr/local/bin/xbacklight", "-dec", "10", NULL };
+static const char *volinccmd[] = { "/home/jozan/.local/bin/mixer-set", "raise", NULL };
+static const char *voldeccmd[] = { "/home/jozan/.local/bin/mixer-set", "lower", NULL };
+static const char *voltogcmd[] = { "/home/jozan/.local/bin/mixer-set", "toggle", NULL };
#include "movestack.c"
-#include "focusurgent.c"
#include <X11/XF86keysym.h>
static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
- { MODKEY, XK_Return, spawn, {.v = termcmd } },
- { MODKEY|ShiftMask, XK_l, spawn, {.v = lockcmd } },
- { MODKEY, XK_3, spawn, {.v = qbcmd } },
- { MODKEY, XK_Escape, 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|ShiftMask, XK_j, movestack, {.i = +1 } },
- { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
- { MODKEY|ShiftMask, XK_Return, zoom, {0} },
- { Mod1Mask, XK_Tab, view, {0} },
- { MODKEY, XK_q, killclient, {0} },
- { MODKEY, XK_s, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[2]} },
- { MODKEY|ShiftMask, XK_s, setlayout, {.v = &layouts[3]} },
- { MODKEY|ShiftMask, XK_m, setlayout, {.v = &layouts[4]} },
- { MODKEY|ShiftMask, XK_space, setlayout, {0} },
- { MODKEY, XK_space, togglefloating, {0} },
- { MODKEY, XK_F12, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_F12, 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 } },
- { 0, XF86XK_MonBrightnessUp, spawn, {.v = backlinccmd } },
- { 0, XF86XK_MonBrightnessDown, spawn, {.v = backldeccmd } },
- { 0, XF86XK_AudioRaiseVolume, spawn, {.v = volupcmd } },
- { 0, XF86XK_AudioLowerVolume, spawn, {.v = voldowncmd } },
- { 0, XF86XK_AudioMute, spawn, {.v = volmutecmd } },
- { Mod1Mask, XK_Shift_L, spawn, {.v = refbarcmd } },
- TAGKEYS( XK_F1, 0)
- TAGKEYS( XK_F2, 1)
- TAGKEYS( XK_F3, 2)
- TAGKEYS( XK_3, 2)
- TAGKEYS( XK_F4, 3)
- TAGKEYS( XK_F5, 4)
- TAGKEYS( XK_F6, 5)
- TAGKEYS( XK_F7, 6)
- TAGKEYS( XK_F8, 7)
- TAGKEYS( XK_F9, 8)
- TAGKEYS( XK_F10, 9)
- { MODKEY, XK_u, focusurgent, {0} },
- { MODKEY|ShiftMask, XK_e, quit, {0} },
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+ { MODKEY, XK_Return, spawn, {.v = termcmd } },
+ { MODKEY, XK_1, spawn, {.v = vifmcmd } },
+ { MODKEY, XK_2, spawn, {.v = nvimcmd } },
+ { MODKEY, XK_3, spawn, {.v = ffcmd } },
+ TAGKEYS( XK_3, 2)
+ { MODKEY, XK_4, spawn, {.v = w3mcmd } },
+ { MODKEY, XK_BackSpace, spawn, {.v = dmpccmd } },
+ { 0, XF86XK_MonBrightnessUp, spawn, {.v = blinccmd } },
+ { 0, XF86XK_MonBrightnessDown, spawn, {.v = bldeccmd } },
+ { 0, XF86XK_AudioRaiseVolume, spawn, {.v = volinccmd } },
+ { 0, XF86XK_AudioLowerVolume, spawn, {.v = voldeccmd } },
+ { 0, XF86XK_AudioMute, spawn, {.v = voltogcmd } },
+ { 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|ShiftMask, XK_h, setmfact, {.f = -0.025} },
+ { MODKEY|ShiftMask, XK_l, setmfact, {.f = +0.025} },
+ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY, XK_q, killclient, {0} },
+ { MODKEY, XK_s, setlayout, {.v = &layouts[0]} },
+ { MODKEY|ShiftMask, XK_s, setlayout, {.v = &layouts[1]} },
+ { MODKEY, XK_t, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_m, setlayout, {.v = &layouts[3]} },
+ { MODKEY, XK_n, setlayout, {.v = &layouts[4]} },
+ { MODKEY|ShiftMask, XK_space, setlayout, {0} },
+ { MODKEY, XK_space, togglefloating, {0} },
+ { MODKEY, XK_f, togglefullscr, {0} },
+ { MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } },
+ { MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } },
+ { MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } },
+ { MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } },
+ { MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } },
+ { MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } },
+ { MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } },
+ { MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } },
+ { MODKEY|ControlMask, XK_Up, moveresizeedge, {.v = "t"} },
+ { MODKEY|ControlMask, XK_Down, moveresizeedge, {.v = "b"} },
+ { MODKEY|ControlMask, XK_Left, moveresizeedge, {.v = "l"} },
+ { MODKEY|ControlMask, XK_Right, moveresizeedge, {.v = "r"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Up, moveresizeedge, {.v = "T"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Down, moveresizeedge, {.v = "B"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Left, moveresizeedge, {.v = "L"} },
+ { MODKEY|ControlMask|ShiftMask, XK_Right, moveresizeedge, {.v = "R"} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+ { MODKEY, XK_bracketleft, focusmon, {.i = -1 } },
+ { MODKEY, XK_bracketright, focusmon, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_bracketleft, tagmon, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_bracketright, tagmon, {.i = +1 } },
+ { MODKEY, XK_h, focusmon, {.i = +1 } },
+ { MODKEY, XK_l, focusmon, {.i = -1 } },
+ TAGKEYS( XK_F1, 0)
+ TAGKEYS( XK_F2, 1)
+ TAGKEYS( XK_F3, 2)
+ TAGKEYS( XK_F4, 3)
+ TAGKEYS( XK_F5, 4)
+ TAGKEYS( XK_F6, 5)
+ TAGKEYS( XK_F7, 6)
+ TAGKEYS( XK_F8, 7)
+ TAGKEYS( XK_F9, 8)
+ TAGKEYS( XK_F8, 7)
+ TAGKEYS( XK_F9, 8)
+ TAGKEYS( XK_F10, 9)
+ TAGKEYS( XK_F11, 10)
+ TAGKEYS( XK_F12, 11)
+ { MODKEY|ShiftMask, XK_e, quit, {0} },
+ { MODKEY|ShiftMask, XK_r, quit, {1} },
};
/* button definitions */
@@ -159,4 +178,3 @@ static Button buttons[] = {
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
-
diff --git a/config.mk b/config.mk
index 1d57398..2bd91ef 100644
--- a/config.mk
+++ b/config.mk
@@ -7,8 +7,8 @@ VERSION = 6.2
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
-X11INC = /usr/include/X11
-X11LIB = /usr/lib/X11
+X11INC = /usr/local/include
+X11LIB = /usr/local/lib
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
@@ -16,16 +16,17 @@ XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lfontconfig -lXft
-FREETYPEINC = /usr/include/freetype2
+FREETYPEINC = /usr/local/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = ${X11INC}/freetype2
+#KVMLIB = -lkvm
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC}
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB}
# flags
-CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
LDFLAGS = ${LIBS}
diff --git a/drw.c b/drw.c
index 8fd1ca4..4cdbcbe 100644
--- a/drw.c
+++ b/drw.c
@@ -95,6 +95,7 @@ drw_free(Drw *drw)
{
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
+ drw_fontset_free(drw->fonts);
free(drw);
}
diff --git a/dwm.1 b/dwm.1
index 13b3729..7b6cadb 100644
--- a/dwm.1
+++ b/dwm.1
@@ -33,7 +33,7 @@ dwm draws a small border around windows to indicate the focus state.
.SH OPTIONS
.TP
.B \-v
-prints version information to standard output, then exits.
+prints version information to stderr, then exits.
.SH USAGE
.SS Status bar
.TP
@@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view.
.TP
.B Mod1\-Shift\-q
Quit dwm.
+.TP
+.B Mod1\-Control\-Shift\-q
+Restart dwm.
.SS Mouse commands
.TP
.B Mod1\-Button1
@@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float
.SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.
+.SH SIGNALS
+.TP
+.B SIGHUP - 1
+Restart the dwm process.
+.TP
+.B SIGTERM - 15
+Cleanly terminate the dwm process.
.SH SEE ALSO
.BR dmenu (1),
.BR st (1)
diff --git a/dwm.c b/dwm.c
index 6c3753a..6792c84 100644
--- a/dwm.c
+++ b/dwm.c
@@ -40,6 +40,12 @@
#include <X11/extensions/Xinerama.h>
#endif /* XINERAMA */
#include <X11/Xft/Xft.h>
+#include <X11/Xlib-xcb.h>
+#include <xcb/res.h>
+#ifdef __OpenBSD__
+#include <sys/sysctl.h>
+#include <kvm.h>
+#endif /* __OpenBSD */
#include "drw.h"
#include "util.h"
@@ -49,7 +55,8 @@
#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 ISVISIBLEONTAG(C, T) ((C->tags & T))
+#define ISVISIBLE(C) ISVISIBLEONTAG(C, 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)
@@ -92,9 +99,11 @@ struct Client {
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw;
unsigned int tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow;
+ pid_t pid;
Client *next;
Client *snext;
+ Client *swallowing;
Monitor *mon;
Window win;
};
@@ -140,6 +149,8 @@ typedef struct {
const char *title;
unsigned int tags;
int isfloating;
+ int isterminal;
+ int noswallow;
int monitor;
} Rule;
@@ -149,6 +160,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac
static void arrange(Monitor *m);
static void arrangemon(Monitor *m);
static void attach(Client *c);
+static void attachaside(Client *c);
static void attachstack(Client *c);
static void buttonpress(XEvent *e);
static void checkotherwm(void);
@@ -165,12 +177,12 @@ 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 int gettextprop(Window w, Atom atom, char *text, unsigned int size);
@@ -183,8 +195,10 @@ 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 moveresize(const Arg *arg);
+static void moveresizeedge(const Arg *arg);
static void movemouse(const Arg *arg);
+static Client *nexttagged(Client *c);
static Client *nexttiled(Client *c);
static void pop(Client *);
static void propertynotify(XEvent *e);
@@ -195,7 +209,6 @@ 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);
@@ -208,12 +221,15 @@ static void setup(void);
static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
+static void sighup(int unused);
+static void sigterm(int unused);
static void spawn(const Arg *arg);
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 togglefullscr(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c, int setfocus);
@@ -236,6 +252,13 @@ 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);
+static void autostart_exec(void);
+
+static pid_t getparentprocess(pid_t p);
+static int isdescprocess(pid_t p, pid_t c);
+static Client *swallowingclient(Window w);
+static Client *termforwin(const Client *c);
+static pid_t winpid(Window w);
/* variables */
static const char broken[] = "broken";
@@ -252,17 +275,16 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[ConfigureRequest] = configurerequest,
[ConfigureNotify] = configurenotify,
[DestroyNotify] = destroynotify,
- [EnterNotify] = enternotify,
[Expose] = expose,
[FocusIn] = focusin,
[KeyPress] = keypress,
[MappingNotify] = mappingnotify,
[MapRequest] = maprequest,
- [MotionNotify] = motionnotify,
[PropertyNotify] = propertynotify,
[UnmapNotify] = unmapnotify
};
static Atom wmatom[WMLast], netatom[NetLast];
+static int restart = 0;
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
@@ -271,6 +293,8 @@ static Drw *drw;
static Monitor *mons, *selmon;
static Window root, wmcheckwin;
+static xcb_connection_t *xcon;
+
/* configuration, allows nested code to access above variables */
#include "config.h"
@@ -280,12 +304,39 @@ struct Pertag {
float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
- int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
};
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+/* dwm will keep pid's of processes from autostart array and kill them at quit */
+static pid_t *autostart_pids;
+static size_t autostart_len;
+
+/* execute command from autostart array */
+static void
+autostart_exec() {
+ const char *const *p;
+ size_t i = 0;
+
+ /* count entries */
+ for (p = autostart; *p; autostart_len++, p++)
+ while (*++p);
+
+ autostart_pids = malloc(autostart_len * sizeof(pid_t));
+ for (p = autostart; *p; i++, p++) {
+ if ((autostart_pids[i] = fork()) == 0) {
+ setsid();
+ execvp(*p, (char *const *)p);
+ fprintf(stderr, "dwm: execvp %s\n", *p);
+ perror(" failed");
+ _exit(EXIT_FAILURE);
+ }
+ /* skip arguments */
+ while (*++p);
+ }
+}
+
/* function implementations */
void
applyrules(Client *c)
@@ -309,6 +360,8 @@ applyrules(Client *c)
&& (!r->class || strstr(class, r->class))
&& (!r->instance || strstr(instance, r->instance)))
{
+ c->isterminal = r->isterminal;
+ c->noswallow = r->noswallow;
c->isfloating = r->isfloating;
c->tags |= r->tags;
for (m = mons; m && m->num != r->monitor; m = m->next);
@@ -406,24 +459,9 @@ arrange(Monitor *m)
void
arrangemon(Monitor *m)
{
- int n = 0;
- Client *c;
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
- if ((m->lt[m->sellt]->arrange != monocle && n > 1) || !m->lt[m->sellt]->arrange) {
- for (c = m->clients; c; c = c->next) {
- if (ISVISIBLE(c) && (!m->lt[m->sellt]->arrange || !c->isfloating) && (c->bw != borderpx)) {
- c->oldbw = c->bw;
- c->bw = borderpx;
- resizeclient(c, m->wx, m->wy, m->ww - (2 * c->bw), m->wh - (2 * c->bw));
- }
- }
- if (m->lt[m->sellt]->arrange) {
- m->lt[m->sellt]->arrange(m);
- }
- } else {
- monocle(m);
- }
+ if (m->lt[m->sellt]->arrange)
+ m->lt[m->sellt]->arrange(m);
}
void
@@ -434,6 +472,18 @@ attach(Client *c)
}
void
+attachaside(Client *c) {
+ Client *at = nexttagged(c);
+ if(!at) {
+ attach(c);
+ return;
+ }
+ c->next = at->next;
+ at->next = c;
+}
+
+
+void
attachstack(Client *c)
{
c->snext = c->mon->stack;
@@ -441,6 +491,53 @@ attachstack(Client *c)
}
void
+swallow(Client *p, Client *c)
+{
+
+ if (c->noswallow || c->isterminal)
+ return;
+ if (c->noswallow && !swallowfloating && c->isfloating)
+ return;
+
+ detach(c);
+ detachstack(c);
+
+ setclientstate(c, WithdrawnState);
+ XUnmapWindow(dpy, p->win);
+
+ p->swallowing = c;
+ c->mon = p->mon;
+
+ Window w = p->win;
+ p->win = c->win;
+ c->win = w;
+ updatetitle(p);
+ XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h);
+ arrange(p->mon);
+ configure(p);
+ updateclientlist();
+}
+
+void
+unswallow(Client *c)
+{
+ c->win = c->swallowing->win;
+
+ free(c->swallowing);
+ c->swallowing = NULL;
+
+ /* unfullscreen the client */
+ setfullscreen(c, 0);
+ updatetitle(c);
+ arrange(c->mon);
+ XMapWindow(dpy, c->win);
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
+ setclientstate(c, NormalState);
+ focus(NULL);
+ arrange(c->mon);
+}
+
+void
buttonpress(XEvent *e)
{
unsigned int i, x, click;
@@ -451,7 +548,8 @@ buttonpress(XEvent *e)
click = ClkRootWin;
/* focus monitor if necessary */
- if ((m = wintomon(ev->window)) && m != selmon) {
+ if ((m = wintomon(ev->window)) && m != selmon
+ && (focusonwheel || (ev->button != Button4 && ev->button != Button5))) {
unfocus(selmon->sel, 1);
selmon = m;
focus(NULL);
@@ -466,15 +564,15 @@ buttonpress(XEvent *e)
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - TEXTW(stext))
+ else if (ev->x > selmon->ww - (int)TEXTW(stext))
click = ClkStatusText;
else
click = ClkWinTitle;
} else if ((c = wintoclient(ev->window))) {
- focus(c);
- restack(selmon);
- XAllowEvents(dpy, ReplayPointer, CurrentTime);
- click = ClkClientWin;
+ if (focusonwheel || (ev->button != Button4 && ev->button != Button5))
+ focus(c);
+ 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
@@ -548,7 +646,7 @@ clientmessage(XEvent *e)
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 */));
+ || (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);
@@ -578,6 +676,7 @@ void
configurenotify(XEvent *e)
{
Monitor *m;
+ Client *c;
XConfigureEvent *ev = &e->xconfigure;
int dirty;
@@ -590,6 +689,9 @@ configurenotify(XEvent *e)
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);
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
}
focus(NULL);
@@ -654,7 +756,7 @@ Monitor *
createmon(void)
{
Monitor *m;
- unsigned int i;
+ int i;
m = ecalloc(1, sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
@@ -665,20 +767,21 @@ createmon(void)
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
- m->pertag = ecalloc(1, sizeof(Pertag));
+ if (!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag))))
+ die("fatal: could not malloc() %u bytes\n", sizeof(Pertag));
m->pertag->curtag = m->pertag->prevtag = 1;
-
- for (i = 0; i <= LENGTH(tags); i++) {
+ for (i=0; i <= LENGTH(tags); i++) {
+ /* init nmaster */
m->pertag->nmasters[i] = m->nmaster;
+
+ /* init mfacts */
m->pertag->mfacts[i] = m->mfact;
+ /* init layouts */
m->pertag->ltidxs[i][0] = m->lt[0];
m->pertag->ltidxs[i][1] = m->lt[1];
m->pertag->sellts[i] = m->sellt;
-
- m->pertag->showbars[i] = m->showbar;
}
-
return m;
}
@@ -690,6 +793,9 @@ destroynotify(XEvent *e)
if ((c = wintoclient(ev->window)))
unmanage(c, 1);
+
+ else if ((c = swallowingclient(ev->window)))
+ unmanage(c->swallowing, 1);
}
void
@@ -733,7 +839,7 @@ dirtomon(int dir)
void
drawbar(Monitor *m)
{
- int x, w, sw = 0;
+ int x, w, tw = 0;
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
@@ -742,8 +848,8 @@ drawbar(Monitor *m)
/* 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);
+ tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+ drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
}
for (c = m->clients; c; c = c->next) {
@@ -766,7 +872,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 - tw - 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);
@@ -790,25 +896,6 @@ drawbars(void)
}
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;
@@ -821,8 +908,6 @@ expose(XEvent *e)
void
focus(Client *c)
{
- XWindowChanges wc;
-
if (!c || !ISVISIBLE(c))
for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
if (selmon->sel && selmon->sel != c)
@@ -836,12 +921,6 @@ focus(Client *c)
attachstack(c);
grabbuttons(c, 1);
XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
-
- if(!c->isfloating) {
- wc.sibling = selmon->barwin;
- wc.stack_mode = Below;
- XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
- }
setfocus(c);
} else {
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
@@ -880,7 +959,7 @@ focusstack(const Arg *arg)
{
Client *c = NULL, *i;
- if (!selmon->sel || selmon->sel->isfullscreen)
+ if (!selmon->sel)
return;
if (arg->i > 0) {
for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
@@ -987,7 +1066,7 @@ grabbuttons(Client *c, int focused)
XGrabButton(dpy, buttons[i].button,
buttons[i].mask | modifiers[j],
c->win, False, BUTTONMASK,
- GrabModeAsync, GrabModeSync, None, None);
+ GrabModeSync, GrabModeSync, None, None);
}
}
@@ -1063,12 +1142,13 @@ killclient(const Arg *arg)
void
manage(Window w, XWindowAttributes *wa)
{
- Client *c, *t = NULL;
+ Client *c, *t = NULL, *term = NULL;
Window trans = None;
XWindowChanges wc;
c = ecalloc(1, sizeof(Client));
c->win = w;
+ c->pid = winpid(w);
/* geometry */
c->x = c->oldx = wa->x;
c->y = c->oldy = wa->y;
@@ -1083,6 +1163,7 @@ manage(Window w, XWindowAttributes *wa)
} else {
c->mon = selmon;
applyrules(c);
+ term = termforwin(c);
}
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
@@ -1102,13 +1183,15 @@ manage(Window w, XWindowAttributes *wa)
updatewindowtype(c);
updatesizehints(c);
updatewmhints(c);
+ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
+ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
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);
+ attachaside(c);
attachstack(c);
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &(c->win), 1);
@@ -1119,6 +1202,8 @@ manage(Window w, XWindowAttributes *wa)
c->mon->sel = c;
arrange(c->mon);
XMapWindow(dpy, c->win);
+ if (term)
+ swallow(term, c);
focus(NULL);
}
@@ -1155,37 +1240,10 @@ monocle(Monitor *m)
for (c = m->clients; c; c = c->next)
if (ISVISIBLE(c))
n++;
- if (n > 0 && m->lt[m->sellt]->arrange == monocle) /* override layout symbol */
+ if (n > 0) /* override layout symbol */
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
- for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
- // I'm not sure, but calling resize with the border width subtractions
- // fixes a glitch where windows would not redraw until they were
- // manually resized after restarting dwm.
- resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
-
- if (c->bw) {
- c->oldbw = c->bw;
- c->bw = 0;
- resizeclient(c, m->wx, m->wy, m->ww, m->wh);
- }
- }
-}
-
-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;
+ 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
@@ -1199,6 +1257,8 @@ movemouse(const Arg *arg)
if (!(c = selmon->sel))
return;
+ if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
+ return;
restack(selmon);
ocx = c->x;
ocy = c->y;
@@ -1246,6 +1306,163 @@ movemouse(const Arg *arg)
}
}
+ Client *
+nexttagged(Client *c) {
+ Client *walked = c->mon->clients;
+ for(;
+ walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags));
+ walked = walked->next
+ );
+ return walked;
+}
+
+void
+moveresize(const Arg *arg) {
+ /* only floating windows can be moved */
+ Client *c;
+ c = selmon->sel;
+ int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh;
+ char xAbs, yAbs, wAbs, hAbs;
+ int msx, msy, dx, dy, nmx, nmy;
+ unsigned int dui;
+ Window dummy;
+
+ if (!c || !arg)
+ return;
+ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
+ return;
+ if (sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8)
+ return;
+
+ /* compute new window position; prevent window from be positioned outside the current monitor */
+ nw = c->w + w;
+ if (wAbs == 'W')
+ nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw;
+
+ nh = c->h + h;
+ if (hAbs == 'H')
+ nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw;
+
+ nx = c->x + x;
+ if (xAbs == 'X') {
+ if (x < selmon->mx)
+ nx = selmon->mx;
+ else if (x > selmon->mx + selmon->mw)
+ nx = selmon->mx + selmon->mw - nw - 2 * c->bw;
+ else
+ nx = x;
+ }
+
+ ny = c->y + y;
+ if (yAbs == 'Y') {
+ if (y < selmon->my)
+ ny = selmon->my;
+ else if (y > selmon->my + selmon->mh)
+ ny = selmon->my + selmon->mh - nh - 2 * c->bw;
+ else
+ ny = y;
+ }
+
+ ox = c->x;
+ oy = c->y;
+ ow = c->w;
+ oh = c->h;
+
+ XRaiseWindow(dpy, c->win);
+ Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
+ resize(c, nx, ny, nw, nh, True);
+
+ /* move cursor along with the window to avoid problems caused by the sloppy focus */
+ if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy)
+ {
+ nmx = c->x - ox + c->w - ow;
+ nmy = c->y - oy + c->h - oh;
+ XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
+ }
+}
+
+void
+moveresizeedge(const Arg *arg) {
+ /* move or resize floating window to edge of screen */
+ Client *c;
+ c = selmon->sel;
+ char e;
+ int nx, ny, nw, nh, ox, oy, ow, oh;
+ int msx, msy, dx, dy, nmx, nmy;
+ int starty;
+ unsigned int dui;
+ Window dummy;
+
+ nx = c->x;
+ ny = c->y;
+ nw = c->w;
+ nh = c->h;
+
+ starty = selmon->showbar ? bh : 0;
+
+ if (!c || !arg)
+ return;
+ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
+ return;
+ if(sscanf((char *)arg->v, "%c", &e) != 1)
+ return;
+
+ if(e == 't')
+ ny = starty;
+
+ if(e == 'b')
+ ny = c->h > selmon->mh - 2 * c->bw ? c->h : selmon->mh - c->h - 2 * c->bw;
+
+ if(e == 'l')
+ nx = 0;
+
+ if(e == 'r')
+ nx = c->w > selmon->mw - 2 * c->bw ? c->w : selmon->mw - c->w - 2 * c->bw;
+
+ if(e == 'T') {
+ /* if you click to resize again, it will return to old size/position */
+ if(c->h + starty == c->oldh + c->oldy) {
+ nh = c->oldh;
+ ny = c->oldy;
+ } else {
+ nh = c->h + c->y - starty;
+ ny = starty;
+ }
+ }
+
+ if(e == 'B')
+ nh = c->h + c->y + 2 * c->bw == selmon->mh ? c->oldh : selmon->mh - c->y - 2 * c->bw;
+
+ if(e == 'L') {
+ if(c->w == c->oldw + c->oldx) {
+ nw = c->oldw;
+ nx = c->oldx;
+ } else {
+ nw = c->w + c->x;
+ nx = 0;
+ }
+ }
+
+ if(e == 'R')
+ nw = c->w + c->x + 2 * c->bw == selmon->mw ? c->oldw : selmon->mw - c->x - 2 * c->bw;
+
+ ox = c->x;
+ oy = c->y;
+ ow = c->w;
+ oh = c->h;
+
+ XRaiseWindow(dpy, c->win);
+ Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
+ resize(c, nx, ny, nw, nh, True);
+
+ /* move cursor along with the window to avoid problems caused by the sloppy focus */
+ if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) {
+ nmx = c->x - ox + c->w - ow;
+ nmy = c->y - oy + c->h - oh;
+ XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
+ }
+}
+
Client *
nexttiled(Client *c)
{
@@ -1302,6 +1519,17 @@ propertynotify(XEvent *e)
void
quit(const Arg *arg)
{
+ size_t i;
+
+ /* kill child processes */
+ for (i = 0; i < autostart_len; i++) {
+ if (0 < autostart_pids[i]) {
+ kill(autostart_pids[i], SIGTERM);
+ waitpid(autostart_pids[i], NULL, 0);
+ }
+ }
+
+ if(arg->i) restart = 1;
running = 0;
}
@@ -1336,6 +1564,13 @@ resizeclient(Client *c, int x, int y, int w, int h)
c->oldw = c->w; c->w = wc.width = w;
c->oldh = c->h; c->h = wc.height = h;
wc.border_width = c->bw;
+ if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next))
+ || &monocle == c->mon->lt[c->mon->sellt]->arrange)
+ && !c->isfullscreen && !c->isfloating) {
+ c->w = wc.width += c->bw * 2;
+ c->h = wc.height += c->bw * 2;
+ wc.border_width = 0;
+ }
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
configure(c);
XSync(dpy, False);
@@ -1352,6 +1587,8 @@ resizemouse(const Arg *arg)
if (!(c = selmon->sel))
return;
+ if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
+ return;
restack(selmon);
ocx = c->x;
ocy = c->y;
@@ -1433,12 +1670,6 @@ run(void)
}
void
-runAutostart(void) {
- system("cd ~/.dwm; ./autostart_blocking.sh");
- system("cd ~/.dwm; ./autostart.sh &");
-}
-
-void
scan(void)
{
unsigned int i, num;
@@ -1475,7 +1706,7 @@ sendmon(Client *c, Monitor *m)
detachstack(c);
c->mon = m;
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
- attach(c);
+ attachaside(c);
attachstack(c);
focus(NULL);
arrange(NULL);
@@ -1534,20 +1765,37 @@ setfullscreen(Client *c, int fullscreen)
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 = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
+ if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) {
+ selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
+ }
if (arg && arg->v)
- selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
+ selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
if (selmon->sel)
arrange(selmon);
@@ -1564,7 +1812,7 @@ setmfact(const Arg *arg)
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)
+ if (f < 0.05 || f > 0.95)
return;
selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
arrange(selmon);
@@ -1580,6 +1828,9 @@ setup(void)
/* clean up any zombies immediately */
sigchld(0);
+ signal(SIGHUP, sighup);
+ signal(SIGTERM, sigterm);
+
/* init screen */
screen = DefaultScreen(dpy);
sw = DisplayWidth(dpy, screen);
@@ -1662,7 +1913,7 @@ showhide(Client *c)
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)
+ 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 {
@@ -1675,9 +1926,39 @@ showhide(Client *c)
void
sigchld(int unused)
{
+ pid_t pid;
+
if (signal(SIGCHLD, sigchld) == SIG_ERR)
die("can't install SIGCHLD handler:");
- while (0 < waitpid(-1, NULL, WNOHANG));
+ while (0 < (pid = waitpid(-1, NULL, WNOHANG))) {
+ pid_t *p, *lim;
+
+ if (!(p = autostart_pids))
+ continue;
+ lim = &p[autostart_len];
+
+ for (; p < lim; p++) {
+ if (*p == pid) {
+ *p = -1;
+ break;
+ }
+ }
+
+ }
+}
+
+void
+sighup(int unused)
+{
+ Arg a = {.i = 1};
+ quit(&a);
+}
+
+void
+sigterm(int unused)
+{
+ Arg a = {.i = 0};
+ quit(&a);
}
void
@@ -1731,22 +2012,21 @@ tile(Monitor *m)
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);
- if(n == 1)
- resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
- else
- resize(c, m->wx - c->bw, m->wy + my, mw - c->bw, h - c->bw, False);
- my += HEIGHT(c) - c->bw;
+ resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
+ if (my + HEIGHT(c) < m->wh)
+ my += HEIGHT(c);
} else {
h = (m->wh - ty) / (n - i);
- resize(c, m->wx + mw - c->bw, m->wy + ty, m->ww - mw, h - c->bw, False);
- ty += HEIGHT(c) - c->bw;
+ resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
+ if (ty + HEIGHT(c) < m->wh)
+ ty += HEIGHT(c);
}
}
void
togglebar(const Arg *arg)
{
- selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
+ selmon->showbar = !selmon->showbar;
updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange(selmon);
@@ -1757,19 +2037,23 @@ 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) {
- if (selmon->sel->bw != borderpx) {
- selmon->sel->oldbw = selmon->sel->bw;
- selmon->sel->bw = borderpx;
- }
+ if (selmon->sel->isfloating)
resize(selmon->sel, selmon->sel->x, selmon->sel->y,
- selmon->sel->w - selmon->sel->bw * 2, selmon->sel->h - selmon->sel->bw * 2, 0);
- }
+ selmon->sel->w, selmon->sel->h, 0);
arrange(selmon);
}
void
+togglefullscr(const Arg *arg)
+{
+ if(selmon->sel)
+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
+}
+
+void
toggletag(const Arg *arg)
{
unsigned int newtags;
@@ -1791,19 +2075,17 @@ toggleview(const Arg *arg)
int i;
if (newtagset) {
- selmon->tagset[selmon->seltags] = newtagset;
-
if (newtagset == ~0) {
selmon->pertag->prevtag = selmon->pertag->curtag;
selmon->pertag->curtag = 0;
}
-
/* test if the user did not select the same tag */
if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
selmon->pertag->prevtag = selmon->pertag->curtag;
- for (i = 0; !(newtagset & 1 << i); i++) ;
+ for (i=0; !(newtagset & 1 << i); i++) ;
selmon->pertag->curtag = i + 1;
}
+ selmon->tagset[selmon->seltags] = newtagset;
/* apply settings for this view */
selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
@@ -1811,10 +2093,6 @@ toggleview(const Arg *arg)
selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-
- if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
- togglebar(NULL);
-
focus(NULL);
arrange(selmon);
}
@@ -1839,6 +2117,20 @@ unmanage(Client *c, int destroyed)
Monitor *m = c->mon;
XWindowChanges wc;
+ if (c->swallowing) {
+ unswallow(c);
+ return;
+ }
+
+ Client *s = swallowingclient(c->win);
+ if (s) {
+ free(s->swallowing);
+ s->swallowing = NULL;
+ arrange(m);
+ focus(NULL);
+ return;
+ }
+
detach(c);
detachstack(c);
if (!destroyed) {
@@ -1853,9 +2145,12 @@ unmanage(Client *c, int destroyed)
XUngrabServer(dpy);
}
free(c);
- focus(NULL);
- updateclientlist();
- arrange(m);
+
+ if (!s) {
+ arrange(m);
+ focus(NULL);
+ updateclientlist();
+ }
}
void
@@ -1972,6 +2267,7 @@ updategeom(void)
detachstack(c);
c->mon = mons;
attach(c);
+ attachaside(c);
attachstack(c);
}
if (m == selmon)
@@ -2116,13 +2412,12 @@ view(const Arg *arg)
return;
selmon->seltags ^= 1; /* toggle sel tagset */
if (arg->ui & TAGMASK) {
- selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
selmon->pertag->prevtag = selmon->pertag->curtag;
-
+ selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
if (arg->ui == ~0)
selmon->pertag->curtag = 0;
else {
- for (i = 0; !(arg->ui & 1 << i); i++) ;
+ for (i=0; !(arg->ui & 1 << i); i++) ;
selmon->pertag->curtag = i + 1;
}
} else {
@@ -2130,20 +2425,145 @@ view(const Arg *arg)
selmon->pertag->prevtag = selmon->pertag->curtag;
selmon->pertag->curtag = tmptag;
}
-
selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-
- if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
- togglebar(NULL);
-
focus(NULL);
arrange(selmon);
}
+pid_t
+winpid(Window w)
+{
+
+ pid_t result = 0;
+
+ #ifdef __linux__
+ xcb_res_client_id_spec_t spec = {0};
+ spec.client = w;
+ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
+
+ xcb_generic_error_t *e = NULL;
+ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
+ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
+
+ if (!r)
+ return (pid_t)0;
+
+ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
+ for (; i.rem; xcb_res_client_id_value_next(&i)) {
+ spec = i.data->spec;
+ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
+ uint32_t *t = xcb_res_client_id_value_value(i.data);
+ result = *t;
+ break;
+ }
+ }
+
+ free(r);
+
+ if (result == (pid_t)-1)
+ result = 0;
+
+ #endif /* __linux__ */
+
+ #ifdef __OpenBSD__
+ Atom type;
+ int format;
+ unsigned long len, bytes;
+ unsigned char *prop;
+ pid_t ret;
+
+ if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 1), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop)
+ return 0;
+
+ ret = *(pid_t*)prop;
+ XFree(prop);
+ result = ret;
+
+ #endif /* __OpenBSD__ */
+ return result;
+}
+
+pid_t
+getparentprocess(pid_t p)
+{
+ unsigned int v = 0;
+
+#ifdef __linux__
+ FILE *f;
+ char buf[256];
+ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
+
+ if (!(f = fopen(buf, "r")))
+ return 0;
+
+ fscanf(f, "%*u %*s %*c %u", &v);
+ fclose(f);
+#endif /* __linux__*/
+
+#ifdef __OpenBSD__
+ int n;
+ kvm_t *kd;
+ struct kinfo_proc *kp;
+
+ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL);
+ if (!kd)
+ return 0;
+
+ kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n);
+ v = kp->p_ppid;
+#endif /* __OpenBSD__ */
+
+ return (pid_t)v;
+}
+
+int
+isdescprocess(pid_t p, pid_t c)
+{
+ while (p != c && c != 0)
+ c = getparentprocess(c);
+
+ return (int)c;
+}
+
+Client *
+termforwin(const Client *w)
+{
+ Client *c;
+ Monitor *m;
+
+ if (!w->pid || w->isterminal)
+ return NULL;
+
+ for (m = mons; m; m = m->next) {
+ for (c = m->clients; c; c = c->next) {
+ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid))
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+Client *
+swallowingclient(Window w)
+{
+ Client *c;
+ Monitor *m;
+
+ for (m = mons; m; m = m->next) {
+ for (c = m->clients; c; c = c->next) {
+ if (c->swallowing && c->swallowing->win == w)
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
Client *
wintoclient(Window w)
{
@@ -2235,15 +2655,18 @@ main(int argc, char *argv[])
fputs("warning: no locale support\n", stderr);
if (!(dpy = XOpenDisplay(NULL)))
die("dwm: cannot open display");
+ if (!(xcon = XGetXCBConnection(dpy)))
+ die("dwm: cannot get xcb connection\n");
checkotherwm();
+ autostart_exec();
setup();
#ifdef __OpenBSD__
- if (pledge("stdio rpath proc exec", NULL) == -1)
+ if (pledge("stdio rpath proc exec ps", NULL) == -1)
die("pledge");
#endif /* __OpenBSD__ */
scan();
- runAutostart();
run();
+ if(restart) execvp(argv[0], argv);
cleanup();
XCloseDisplay(dpy);
return EXIT_SUCCESS;
diff --git a/focusurgent.c b/focusurgent.c
deleted file mode 100644
index bc6eee6..0000000
--- a/focusurgent.c
+++ /dev/null
@@ -1,14 +0,0 @@
-static void
-focusurgent(const Arg *arg) {
- Client *c;
- int i;
- for(c=selmon->clients; c && !c->isurgent; c=c->next);
- if(c) {
- for(i=0; i < LENGTH(tags) && !((1 << i) & c->tags); i++);
- if(i < LENGTH(tags)) {
- const Arg a = {.ui = 1 << i};
- view(&a);
- focus(c);
- }
- }
-}