mirror of
https://github.com/alrayyes/dwm
synced 2023-11-14 15:56:31 +00:00
165 lines
4.8 KiB
Diff
165 lines
4.8 KiB
Diff
|
diff -up a/dwm.1 b/dwm.1
|
||
|
--- a/dwm.1 2020-12-01 10:01:44.217062949 +0100
|
||
|
+++ b/dwm.1 2020-12-01 10:04:30.247194027 +0100
|
||
|
@@ -30,6 +30,14 @@ top left corner. The tags which are app
|
||
|
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
|
||
|
.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 -up a/dwm.c b/dwm.c
|
||
|
--- a/dwm.c 2020-12-01 10:01:44.217062949 +0100
|
||
|
+++ b/dwm.c 2020-12-01 10:07:15.937309505 +0100
|
||
|
@@ -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>
|
||
|
@@ -222,6 +223,7 @@ 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);
|
||
|
@@ -269,8 +271,12 @@ static int xerrorstart(Display *dpy, XEr
|
||
|
static void zoom(const Arg *arg);
|
||
|
|
||
|
/* variables */
|
||
|
+static const char autostartblocksh[] = "autostart_blocking.sh";
|
||
|
+static const char autostartsh[] = "autostart.sh";
|
||
|
static Systray *systray = NULL;
|
||
|
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 */
|
||
|
@@ -1557,6 +1563,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;
|
||
|
@@ -2501,6 +2584,7 @@ main(int argc, char *argv[])
|
||
|
die("pledge");
|
||
|
#endif /* __OpenBSD__ */
|
||
|
scan();
|
||
|
+ runautostart();
|
||
|
run();
|
||
|
cleanup();
|
||
|
XCloseDisplay(dpy);
|