diff options
Diffstat (limited to 'dwl.c')
-rw-r--r-- | dwl.c | 59 |
1 files changed, 54 insertions, 5 deletions
@@ -275,6 +275,7 @@ static void arrange(Monitor *m); static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); +static void autostartexec(void); static void axisnotify(struct wl_listener *listener, void *data); static bool bar_accepts_input(struct wlr_scene_buffer *buffer, double *sx, double *sy); static void buffer_destroy(struct wlr_buffer *buffer); @@ -490,6 +491,9 @@ static xcb_atom_t netatom[NetLast]; /* attempt to encapsulate suck into one file */ #include "client.h" +static pid_t *autostart_pids; +static size_t autostart_len; + /* function implementations */ void applybounds(Client *c, struct wlr_box *bbox) @@ -648,6 +652,27 @@ arrangelayers(Monitor *m) } void +autostartexec(void) { + const char *const *p; + size_t i = 0; + + /* count entries */ + for (p = autostart; *p; autostart_len++, p++) + while (*++p); + + autostart_pids = calloc(autostart_len, sizeof(pid_t)); + for (p = autostart; *p; i++, p++) { + if ((autostart_pids[i] = fork()) == 0) { + setsid(); + execvp(*p, (char *const *)p); + die("dwl: execvp %s:", *p); + } + /* skip arguments */ + while (*++p); + } +} + +void axisnotify(struct wl_listener *listener, void *data) { /* This event is forwarded by the cursor when a pointer emits an axis event, @@ -814,11 +839,21 @@ checkidleinhibitor(struct wlr_surface *exclude) void cleanup(void) { + size_t i; #ifdef XWAYLAND wlr_xwayland_destroy(xwayland); xwayland = NULL; #endif wl_display_destroy_clients(dpy); + + /* 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); + } + } + if (child_pid > 0) { kill(-child_pid, SIGTERM); waitpid(child_pid, NULL, 0); @@ -1742,18 +1777,31 @@ void handlesig(int signo) { if (signo == SIGCHLD) { -#ifdef XWAYLAND siginfo_t in; /* wlroots expects to reap the XWayland process itself, so we * use WNOWAIT to keep the child waitable until we know it's not * XWayland. */ while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid - && (!xwayland || in.si_pid != xwayland->server->pid)) - waitpid(in.si_pid, NULL, 0); -#else - while (waitpid(-1, NULL, WNOHANG) > 0); +#ifdef XWAYLAND + && (!xwayland || in.si_pid != xwayland->server->pid) #endif + ) { + pid_t *p, *lim; + waitpid(in.si_pid, NULL, 0); + if (in.si_pid == child_pid) + child_pid = -1; + if (!(p = autostart_pids)) + continue; + lim = &p[autostart_len]; + + for (; p < lim; p++) { + if (*p == in.si_pid) { + *p = -1; + break; + } + } + } } else if (signo == SIGINT || signo == SIGTERM) { quit(NULL); } @@ -2599,6 +2647,7 @@ run(char *startup_cmd) die("startup: backend_start"); /* Now that the socket exists and the backend is started, run the startup command */ + autostartexec(); if (startup_cmd) { if ((child_pid = fork()) < 0) die("startup: fork:"); |