|
|
|
@ -29,6 +29,7 @@ |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
#include <sys/types.h> |
|
|
|
|
#include <sys/stat.h> |
|
|
|
|
#include <sys/wait.h> |
|
|
|
|
#include <sys/epoll.h> |
|
|
|
|
#include <X11/cursorfont.h> |
|
|
|
@ -222,6 +223,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 void scantray(void); |
|
|
|
|
static int sendevent(Client *c, Atom proto); |
|
|
|
@ -274,7 +276,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 */ |
|
|
|
@ -1688,6 +1694,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) |
|
|
|
|
{ |
|
|
|
@ -2628,6 +2711,7 @@ main(int argc, char *argv[]) |
|
|
|
|
die("pledge"); |
|
|
|
|
#endif /* __OpenBSD__ */ |
|
|
|
|
scan(); |
|
|
|
|
runautostart(); |
|
|
|
|
run(); |
|
|
|
|
cleanup(); |
|
|
|
|
XCloseDisplay(dpy); |
|
|
|
|