summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2021-01-24 10:15:15 -0500
committerJon Santmyer <jon@jonsantmyer.com>2021-01-24 10:15:15 -0500
commitafccac60825f9b270e95426a69b920ec76d3ba2e (patch)
tree608f88eda698a6f3555281b2db37a3ac53767cab
parent9127119771d66866c9ae698a799e01cbcffb4370 (diff)
downloaddwm-afccac60825f9b270e95426a69b920ec76d3ba2e.tar.gz
dwm-afccac60825f9b270e95426a69b920ec76d3ba2e.tar.bz2
dwm-afccac60825f9b270e95426a69b920ec76d3ba2e.zip
change autostart to cool-autostart
-rw-r--r--config.def.h8
-rw-r--r--dwm.c143
-rw-r--r--patches/autostart.diff179
-rw-r--r--patches/cool-autostart.diff116
4 files changed, 182 insertions, 264 deletions
diff --git a/config.def.h b/config.def.h
index c1a5570..f0b9a4f 100644
--- a/config.def.h
+++ b/config.def.h
@@ -35,6 +35,14 @@ static const char *colors[][3] = {
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
};
+static const char *const autostart[] = {
+ "dwmblocks", NULL,
+ "dunst", NULL,
+ NULL /* terminate */
+};
+
+
+
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
diff --git a/dwm.c b/dwm.c
index 3f4344c..bce54e6 100644
--- a/dwm.c
+++ b/dwm.c
@@ -29,7 +29,6 @@
#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>
@@ -185,6 +184,7 @@ static void arrange(Monitor *m);
static void arrangemon(Monitor *m);
static void attach(Client *c);
static void attachstack(Client *c);
+static void autostart_exec(void);
static void buttonpress(XEvent *e);
static void checkotherwm(void);
static void cleanup(void);
@@ -238,7 +238,6 @@ 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);
@@ -288,11 +287,7 @@ static void zoom(const Arg *arg);
/* variables */
static Systray *systray = NULL;
-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 */
@@ -333,6 +328,35 @@ static Window root, wmcheckwin;
/* 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)
@@ -1555,6 +1579,15 @@ 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);
+ }
+ }
running = 0;
}
@@ -1727,83 +1760,6 @@ 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;
@@ -2074,9 +2030,26 @@ 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
@@ -2757,13 +2730,13 @@ main(int argc, char *argv[])
if (!(dpy = XOpenDisplay(NULL)))
die("dwm: cannot open display");
checkotherwm();
+ autostart_exec();
setup();
#ifdef __OpenBSD__
if (pledge("stdio rpath proc exec", NULL) == -1)
die("pledge");
#endif /* __OpenBSD__ */
scan();
- runautostart();
run();
cleanup();
XCloseDisplay(dpy);
diff --git a/patches/autostart.diff b/patches/autostart.diff
deleted file mode 100644
index 7e17424..0000000
--- a/patches/autostart.diff
+++ /dev/null
@@ -1,179 +0,0 @@
-From 37e970479dc5d40e57fc0cbfeaa5e39941483237 Mon Sep 17 00:00:00 2001
-From: Gan Ainm <gan.ainm.riomhphost@gmail.com>
-Date: Wed, 10 Jun 2020 10:59:02 +0000
-Subject: [PATCH] dwm-xdgautostart-6.2.diff
-
-===================================================================
----
- dwm.1 | 23 +++++++++++++++++
- dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 105 insertions(+)
-
-diff --git a/dwm.1 b/dwm.1
-index 13b3729..9533aa6 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 4465af1..2156b49 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>
-@@ -193,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);
-@@ -235,7 +237,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 */
-@@ -1380,6 +1386,83 @@ run(void)
- handler[ev.type](&ev); /* call handler */
- }
-
-+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)
- {
-@@ -2142,6 +2223,7 @@ main(int argc, char *argv[])
- die("pledge");
- #endif /* __OpenBSD__ */
- scan();
-+ runautostart();
- run();
- cleanup();
- XCloseDisplay(dpy);
---
-2.27.0
-
diff --git a/patches/cool-autostart.diff b/patches/cool-autostart.diff
new file mode 100644
index 0000000..84a93ea
--- /dev/null
+++ b/patches/cool-autostart.diff
@@ -0,0 +1,116 @@
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..ed056a4 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -18,6 +18,11 @@ static const char *colors[][3] = {
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ };
+
++static const char *const autostart[] = {
++ "st", NULL,
++ NULL /* terminate */
++};
++
+ /* tagging */
+ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+
+diff --git a/dwm.c b/dwm.c
+index 9fd0286..1facd56 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -234,6 +234,7 @@ 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);
+
+ /* variables */
+ static const char broken[] = "broken";
+@@ -275,6 +276,34 @@ static Window root, wmcheckwin;
+ /* 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)
+@@ -1249,6 +1278,16 @@ 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);
++ }
++ }
++
+ running = 0;
+ }
+
+@@ -1632,9 +1671,25 @@ 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
+@@ -2139,6 +2194,7 @@ main(int argc, char *argv[])
+ if (!(dpy = XOpenDisplay(NULL)))
+ die("dwm: cannot open display");
+ checkotherwm();
++ autostart_exec();
+ setup();
+ #ifdef __OpenBSD__
+ if (pledge("stdio rpath proc exec", NULL) == -1)
+