aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--LICENSE1
-rw-r--r--README48
-rw-r--r--README.md63
-rw-r--r--config.def.h180
-rw-r--r--dwm.123
-rw-r--r--dwm.c84
7 files changed, 278 insertions, 127 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e462188
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+dwm
+config.h
+*.o
+*.orig
+*.tar.gz
+*.diff
diff --git a/LICENSE b/LICENSE
index d221f09..1877c63 100644
--- a/LICENSE
+++ b/LICENSE
@@ -17,6 +17,7 @@ MIT/X Consortium License
© 2015-2016 Quentin Rameau <quinq@fifth.space>
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
+© 2021 la-ninpre <aaoth at aaoth dot xyz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/README b/README
deleted file mode 100644
index 95d4fd0..0000000
--- a/README
+++ /dev/null
@@ -1,48 +0,0 @@
-dwm - dynamic window manager
-============================
-dwm is an extremely fast, small, and dynamic window manager for X.
-
-
-Requirements
-------------
-In order to build dwm you need the Xlib header files.
-
-
-Installation
-------------
-Edit config.mk to match your local setup (dwm is installed into
-the /usr/local namespace by default).
-
-Afterwards enter the following command to build and install dwm (if
-necessary as root):
-
- make clean install
-
-
-Running dwm
------------
-Add the following line to your .xinitrc to start dwm using startx:
-
- exec dwm
-
-In order to connect dwm to a specific display, make sure that
-the DISPLAY environment variable is set correctly, e.g.:
-
- DISPLAY=foo.bar:1 exec dwm
-
-(This will start dwm on display :1 of the host foo.bar.)
-
-In order to display status info in the bar, you can do something
-like this in your .xinitrc:
-
- while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
- do
- sleep 1
- done &
- exec dwm
-
-
-Configuration
--------------
-The configuration of dwm is done by creating a custom config.h
-and (re)compiling the source code.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..43d4bd0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,63 @@
+*a note by la-ninpre*
+
+> this is my fork of dwm. it is pretty much close with the original, but
+> it will evolve as i learn and as i need more functionality.
+>
+> patches applied:
+>
+> * [dwm-autostart][1]
+
+[1]:https://dwm.suckless.org/patches/autostart/
+
+# dwm -- dynamic window manager
+
+dwm is an extremely fast, small, and dynamic window manager for x.
+
+## requirements
+
+in order to build dwm you need the xlib header files.
+
+## installation
+
+edit `config.mk` to match your local setup (dwm is installed into the
+`/usr/local` namespace by default).
+
+afterwards enter the following command to build and install dwm
+(if necessary as root):
+
+```terminal
+# make clean install
+```
+
+## running dwm
+
+add the following line to your `.xinitrc` to start dwm using startx:
+
+```
+exec dwm
+```
+
+in order to connect dwm to a specific display, make sure that the `DISPLAY`
+environment variable is set correctly, e.g.:
+
+```
+DISPLAY=foo.bar:1 exec dwm
+```
+
+(this will start dwm on display :1 of the host foo.bar.)
+
+in order to display status info in the bar, you can do something like this
+in your `.xinitrc`:
+
+```
+while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
+do
+ sleep 1
+done &
+exec dwm
+```
+
+## configuration
+
+the configuration of dwm is done by creating a custom config.h and (re)compiling
+the source code.
diff --git a/config.def.h b/config.def.h
index a2ac963..b729f59 100644
--- a/config.def.h
+++ b/config.def.h
@@ -5,112 +5,134 @@ static const unsigned int borderpx = 1; /* border pixel of 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 */
-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 *fonts[] = { "Lato Medium:size=11" };
+static const char dmenufont[] = "JetBrains Mono Medium:size=11";
+static const char norm_fg[] = "#cadcde";
+static const char norm_bg[] = "#19191a";
+static const char norm_border[] = "#393838";
+static const char sel_fg[] = "#c7ea76";
+static const char sel_bg[] = "#5a514b";
+static const char sel_border[] = "#5a514b";
static const char *colors[][3] = {
- /* fg bg border */
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ /* fg bg border */
+ [SchemeNorm] = { norm_fg, norm_bg, norm_border },
+ [SchemeSel] = { sel_fg, sel_bg, sel_border },
};
/* tagging */
-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+static const char *tags[] = {
+ "sona", "musi", "pali", "lipu", "poki", "toki", "suli", "lukin", "ante"
+};
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 },
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
+ /* xprop(1):
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+ /* class instance title tags mask isfloating monitor */
+ { "Qalculate-gtk", NULL, NULL, 0, 1, -1 },
+ { "Nitrogen", NULL, NULL, 0, 1, -1 },
+ { "Brave", NULL, NULL, 2, 0, -1 },
+ { "discord", NULL, NULL, 1 << 5, 0, -1 },
+ { "Gimp", NULL, NULL, 1 << 8, 1, -1 },
+ { "Blender", NULL, NULL, 1 << 8, 0, -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 int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
+static const float mfact = 0.5; /* 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 int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
+ /* symbol arrange function */
+ { "[]=", tile }, /* first entry is default */
+ { "><>", NULL }, /* no layout function means floating behavior */
+ { "[M]", monocle },
};
/* key definitions */
-#define MODKEY Mod1Mask
+#define MODKEY Mod4Mask
#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} },
+ { 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[] = { "st", NULL };
+static const char *dmenucmd[] = {
+ "dmenu_run", "-m", dmenumon, "-fn", dmenufont,
+ "-nb", norm_bg, "-nf", norm_fg, "-sb", sel_bg, "-sf", sel_fg, NULL
+};
+static const char *termcmd[] = { "alacritty", NULL };
+static const char *editorcmd[] = { "emacsclient", "-c", NULL };
+static const char *browsercmd[] = { "brave", NULL };
+
+/* scrot */
+static const char *scrot_full[] = { "scrot_cmd", "--full", NULL };
+static const char *scrot_focused[] = { "scrot_cmd", "--focused", NULL };
+static const char *scrot_area[] = { "scrot_cmd", "--area", NULL };
static Key keys[] = {
- /* modifier key function argument */
- { 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} },
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+ { MODKEY, XK_Return, spawn, {.v = termcmd } },
+ { MODKEY|ShiftMask, XK_e, spawn, {.v = editorcmd } },
+ { MODKEY, XK_w, spawn, {.v = browsercmd } },
+ { 0, XK_Print, spawn, {.v = scrot_full } },
+ { ControlMask, XK_Print, spawn, {.v = scrot_area } },
+ { Mod1Mask, XK_Print, spawn, {.v = scrot_focused } },
+ { 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.01} },
+ { MODKEY, XK_l, setmfact, {.f = +0.01} },
+ { MODKEY|ShiftMask, 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} },
+ /* 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/dwm.1 b/dwm.1
index ddc8321..86e73f9 100644
--- a/dwm.1
+++ b/dwm.1
@@ -30,6 +30,14 @@ top left corner. The tags which are applied to one or more windows are
indicated with an empty square in the top left corner.
.P
dwm draws a small border around windows to indicate the focus state.
+.P
+On start, dwm can start additional programs that may be specified in two special
+shell scripts (see the FILES section below), autostart_blocking.sh and
+autostart.sh. The former is executed first and dwm will wait for its
+termination before starting. The latter is executed in the background before
+dwm enters its handler loop.
+.P
+Either of these files may be omitted.
.SH OPTIONS
.TP
.B \-v
@@ -152,6 +160,21 @@ Toggles focused window between floating and tiled state.
.TP
.B Mod1\-Button3
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
+.SH FILES
+The files containing programs to be started along with dwm are searched for in
+the following directories:
+.IP "1. $XDG_DATA_HOME/dwm"
+.IP "2. $HOME/.local/share/dwm"
+.IP "3. $HOME/.dwm"
+.P
+The first existing directory is scanned for any of the autostart files below.
+.TP 15
+autostart.sh
+This file is started as a shell background process before dwm enters its handler
+loop.
+.TP 15
+autostart_blocking.sh
+This file is started before any autostart.sh; dwm waits for its termination.
.SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.
diff --git a/dwm.c b/dwm.c
index 5e4d494..531ee5c 100644
--- a/dwm.c
+++ b/dwm.c
@@ -29,6 +29,7 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/wait.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
@@ -194,6 +195,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);
@@ -236,7 +238,11 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
/* variables */
+static const char autostartblocksh[] = "autostart_blocking.sh";
+static const char autostartsh[] = "autostart.sh";
static const char broken[] = "broken";
+static const char dwmdir[] = "dwm";
+static const char localshare[] = ".local/share";
static char stext[256];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
@@ -1382,6 +1388,83 @@ run(void)
}
void
+runautostart(void)
+{
+ char *pathpfx;
+ char *path;
+ char *xdgdatahome;
+ char *home;
+ struct stat sb;
+
+ if ((home = getenv("HOME")) == NULL)
+ /* this is almost impossible */
+ return;
+
+ /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
+ * otherwise use ~/.local/share/dwm as autostart script directory
+ */
+ xdgdatahome = getenv("XDG_DATA_HOME");
+ if (xdgdatahome != NULL && *xdgdatahome != '\0') {
+ /* space for path segments, separators and nul */
+ pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
+
+ if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
+ free(pathpfx);
+ return;
+ }
+ } else {
+ /* space for path segments, separators and nul */
+ pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
+ + strlen(dwmdir) + 3);
+
+ if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
+ free(pathpfx);
+ return;
+ }
+ }
+
+ /* check if the autostart script directory exists */
+ if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
+ /* the XDG conformant path does not exist or is no directory
+ * so we try ~/.dwm instead
+ */
+ char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
+ if(pathpfx_new == NULL) {
+ free(pathpfx);
+ return;
+ }
+ pathpfx = pathpfx_new;
+
+ if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
+ free(pathpfx);
+ return;
+ }
+ }
+
+ /* try the blocking script first */
+ path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
+ if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
+ free(path);
+ free(pathpfx);
+ }
+
+ if (access(path, X_OK) == 0)
+ system(path);
+
+ /* now the non-blocking script */
+ if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
+ free(path);
+ free(pathpfx);
+ }
+
+ if (access(path, X_OK) == 0)
+ system(strcat(path, " &"));
+
+ free(pathpfx);
+ free(path);
+}
+
+void
scan(void)
{
unsigned int i, num;
@@ -2145,6 +2228,7 @@ main(int argc, char *argv[])
die("pledge");
#endif /* __OpenBSD__ */
scan();
+ runautostart();
run();
cleanup();
XCloseDisplay(dpy);