~saurabhs/dwm

f9f60c762b6ea50d5d064b6333b50853c777da98 — Saurabh S 8 months ago 9f5a3d3
Add autostart patch
2 files changed, 107 insertions(+), 0 deletions(-)

M dwm.1
M dwm.c
M dwm.1 => dwm.1 +23 -0
@@ 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.

M dwm.c => dwm.c +84 -0
@@ 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 */


@@ 1381,6 1387,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;


@@ 2144,6 2227,7 @@ main(int argc, char *argv[])
		die("pledge");
#endif /* __OpenBSD__ */
	scan();
	runautostart();
	run();
	cleanup();
	XCloseDisplay(dpy);