sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dwm-autostart-20210120-cb3f58a.diff (5257B)


      1 From 37e970479dc5d40e57fc0cbfeaa5e39941483237 Mon Sep 17 00:00:00 2001
      2 From: Gan Ainm <gan.ainm.riomhphost@gmail.com>
      3 Date: Wed, 10 Jun 2020 10:59:02 +0000
      4 Subject: [PATCH] dwm-xdgautostart-6.2.diff
      5 
      6 ===================================================================
      7 ---
      8  dwm.1 | 23 +++++++++++++++++
      9  dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     10  2 files changed, 105 insertions(+)
     11 
     12 diff --git a/dwm.1 b/dwm.1
     13 index 13b3729..9533aa6 100644
     14 --- a/dwm.1
     15 +++ b/dwm.1
     16 @@ -30,6 +30,14 @@ top left corner.  The tags which are applied to one or more windows are
     17  indicated with an empty square in the top left corner.
     18  .P
     19  dwm draws a small border around windows to indicate the focus state.
     20 +.P
     21 +On start, dwm can start additional programs that may be specified in two special
     22 +shell scripts (see the FILES section below), autostart_blocking.sh and
     23 +autostart.sh.  The former is executed first and dwm will wait for its
     24 +termination before starting.  The latter is executed in the background before
     25 +dwm enters its handler loop.
     26 +.P
     27 +Either of these files may be omitted.
     28  .SH OPTIONS
     29  .TP
     30  .B \-v
     31 @@ -152,6 +160,21 @@ Toggles focused window between floating and tiled state.
     32  .TP
     33  .B Mod1\-Button3
     34  Resize focused window while dragging. Tiled windows will be toggled to the floating state.
     35 +.SH FILES
     36 +The files containing programs to be started along with dwm are searched for in
     37 +the following directories:
     38 +.IP "1. $XDG_DATA_HOME/dwm"
     39 +.IP "2. $HOME/.local/share/dwm"
     40 +.IP "3. $HOME/.dwm"
     41 +.P
     42 +The first existing directory is scanned for any of the autostart files below.
     43 +.TP 15
     44 +autostart.sh
     45 +This file is started as a shell background process before dwm enters its handler
     46 +loop.
     47 +.TP 15
     48 +autostart_blocking.sh
     49 +This file is started before any autostart.sh; dwm waits for its termination.
     50  .SH CUSTOMIZATION
     51  dwm is customized by creating a custom config.h and (re)compiling the source
     52  code. This keeps it fast, secure and simple.
     53 diff --git a/dwm.c b/dwm.c
     54 index 4465af1..2156b49 100644
     55 --- a/dwm.c
     56 +++ b/dwm.c
     57 @@ -29,6 +29,7 @@
     58  #include <string.h>
     59  #include <unistd.h>
     60  #include <sys/types.h>
     61 +#include <sys/stat.h>
     62  #include <sys/wait.h>
     63  #include <X11/cursorfont.h>
     64  #include <X11/keysym.h>
     65 @@ -193,6 +194,7 @@ static void resizeclient(Client *c, int x, int y, int w, int h);
     66  static void resizemouse(const Arg *arg);
     67  static void restack(Monitor *m);
     68  static void run(void);
     69 +static void runautostart(void);
     70  static void scan(void);
     71  static int sendevent(Client *c, Atom proto);
     72  static void sendmon(Client *c, Monitor *m);
     73 @@ -235,7 +237,11 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee);
     74  static void zoom(const Arg *arg);
     75  
     76  /* variables */
     77 +static const char autostartblocksh[] = "autostart_blocking.sh";
     78 +static const char autostartsh[] = "autostart.sh";
     79  static const char broken[] = "broken";
     80 +static const char dwmdir[] = "dwm";
     81 +static const char localshare[] = ".local/share";
     82  static char stext[256];
     83  static int screen;
     84  static int sw, sh;           /* X display screen geometry width, height */
     85 @@ -1380,6 +1386,83 @@ run(void)
     86  			handler[ev.type](&ev); /* call handler */
     87  }
     88  
     89 +void
     90 +runautostart(void)
     91 +{
     92 +	char *pathpfx;
     93 +	char *path;
     94 +	char *xdgdatahome;
     95 +	char *home;
     96 +	struct stat sb;
     97 +
     98 +	if ((home = getenv("HOME")) == NULL)
     99 +		/* this is almost impossible */
    100 +		return;
    101 +
    102 +	/* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
    103 +	 * otherwise use ~/.local/share/dwm as autostart script directory
    104 +	 */
    105 +	xdgdatahome = getenv("XDG_DATA_HOME");
    106 +	if (xdgdatahome != NULL && *xdgdatahome != '\0') {
    107 +		/* space for path segments, separators and nul */
    108 +		pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
    109 +
    110 +		if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
    111 +			free(pathpfx);
    112 +			return;
    113 +		}
    114 +	} else {
    115 +		/* space for path segments, separators and nul */
    116 +		pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
    117 +		                     + strlen(dwmdir) + 3);
    118 +
    119 +		if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
    120 +			free(pathpfx);
    121 +			return;
    122 +		}
    123 +	}
    124 +
    125 +	/* check if the autostart script directory exists */
    126 +	if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
    127 +		/* the XDG conformant path does not exist or is no directory
    128 +		 * so we try ~/.dwm instead
    129 +		 */
    130 +		char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
    131 +		if(pathpfx_new == NULL) {
    132 +			free(pathpfx);
    133 +			return;
    134 +		}
    135 +		pathpfx = pathpfx_new;
    136 +
    137 +		if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
    138 +			free(pathpfx);
    139 +			return;
    140 +		}
    141 +	}
    142 +
    143 +	/* try the blocking script first */
    144 +	path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
    145 +	if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
    146 +		free(path);
    147 +		free(pathpfx);
    148 +	}
    149 +
    150 +	if (access(path, X_OK) == 0)
    151 +		system(path);
    152 +
    153 +	/* now the non-blocking script */
    154 +	if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
    155 +		free(path);
    156 +		free(pathpfx);
    157 +	}
    158 +
    159 +	if (access(path, X_OK) == 0)
    160 +		system(strcat(path, " &"));
    161 +
    162 +	free(pathpfx);
    163 +	free(path);
    164 +}
    165 +
    166  void
    167  scan(void)
    168  {
    169 @@ -2142,6 +2223,7 @@ main(int argc, char *argv[])
    170  		die("pledge");
    171  #endif /* __OpenBSD__ */
    172  	scan();
    173 +	runautostart();
    174  	run();
    175  	cleanup();
    176  	XCloseDisplay(dpy);
    177 -- 
    178 2.27.0
    179