Add autostart patch

This commit is contained in:
Sravan Balaji
2024-09-02 23:08:08 -04:00
parent 5c45bee8ff
commit 3bd02c9fb9
8 changed files with 282 additions and 6 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ dwl
*-protocol.c *-protocol.c
*-protocol.h *-protocol.h
.ccls-cache .ccls-cache
patches.h

View File

@@ -19,7 +19,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS)
all: dwl all: dwl
dwl: dwl.o util.o dwl: dwl.o util.o
$(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ $(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \ dwl.o: dwl.c client.h config.h config.mk patches.h cursor-shape-v1-protocol.h \
pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \ pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \
wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h
util.o: util.c util.h util.o: util.c util.h
@@ -48,8 +48,11 @@ xdg-shell-protocol.h:
config.h: config.h:
cp config.def.h $@ cp config.def.h $@
patches.h:
cp patches.def.h $@
clean: clean:
rm -f dwl *.o *-protocol.h rm -f dwl *.o *-protocol.h
rm -f patches.h
dist: clean dist: clean
mkdir -p dwl-$(VERSION) mkdir -p dwl-$(VERSION)

View File

@@ -6,10 +6,13 @@
* Table of Contents :TOC_3:noexport: * Table of Contents :TOC_3:noexport:
- [[#welcome][Welcome]] - [[#welcome][Welcome]]
- [[#dwl---dwm-for-wayland][dwl - dwm for Wayland]] - [[#dwl---dwm-for-wayland][dwl - dwm for Wayland]]
- [[#patches][Patches]]
- [[#auto-start][Auto Start]]
- [[#dwl-configuration][dwl Configuration]] - [[#dwl-configuration][dwl Configuration]]
- [[#apearance][Apearance]] - [[#appearance][Appearance]]
- [[#tagging][Tagging]] - [[#tagging][Tagging]]
- [[#logging][Logging]] - [[#logging][Logging]]
- [[#autostart][Autostart]]
- [[#window-rules][Window Rules]] - [[#window-rules][Window Rules]]
- [[#layouts][Layouts]] - [[#layouts][Layouts]]
- [[#monitor-rules][Monitor Rules]] - [[#monitor-rules][Monitor Rules]]
@@ -41,11 +44,23 @@ sudo make clean install
See [[./README.md][Upstream README]] for details on project. See [[./README.md][Upstream README]] for details on project.
* Patches
** [[https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/autostart][Auto Start]]
Allow dwl to execute commands from autostart array in your config.h file. And when you exit dwl all processes from autostart array will be killed.
Note: Commands from array are executed using execvp(). So if you need to execute shell command you need to prefix it with "sh", "-c" (change sh to any shell you like).
#+BEGIN_SRC c :tangle patches.def.h
#define AUTOSTART_PATCH 1
#+END_SRC
* dwl Configuration * dwl Configuration
Taken from https://github.com/djpohly/dwl/issues/466. Taken from https://github.com/djpohly/dwl/issues/466.
** Apearance ** Appearance
#+BEGIN_SRC c :tangle config.h #+BEGIN_SRC c :tangle config.h
#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \ #define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \
@@ -79,6 +94,17 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR; static int log_level = WLR_ERROR;
#+END_SRC #+END_SRC
** Autostart
#+BEGIN_SRC c :tangle config.h
#if AUTOSTART_PATCH
static const char *const autostart[] = {
"wbg", "/path/to/your/image", NULL,
NULL /* terminate */
};
#endif // AUTOSTART_PATCH
#+END_SRC
** Window Rules ** Window Rules
#+BEGIN_SRC c :tangle config.h #+BEGIN_SRC c :tangle config.h

View File

@@ -20,6 +20,13 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
/* logging */ /* logging */
static int log_level = WLR_ERROR; static int log_level = WLR_ERROR;
/* Autostart */
static const char *const autostart[] = {
"wbg", "/path/to/your/image", NULL,
NULL /* terminate */
};
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */ /* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = { static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */ /* app_id title tags mask isfloating monitor */

View File

@@ -18,6 +18,13 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR; static int log_level = WLR_ERROR;
#if AUTOSTART_PATCH
static const char *const autostart[] = {
"wbg", "/path/to/your/image", NULL,
NULL /* terminate */
};
#endif // AUTOSTART_PATCH
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */ /* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = { static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */ /* app_id title tags mask isfloating monitor */

77
dwl.c
View File

@@ -67,6 +67,7 @@
#include <xcb/xcb_icccm.h> #include <xcb/xcb_icccm.h>
#endif #endif
#include "patches.h"
#include "util.h" #include "util.h"
/* macros */ /* macros */
@@ -249,6 +250,9 @@ static void arrange(Monitor *m);
static void arrangelayer(Monitor *m, struct wl_list *list, static void arrangelayer(Monitor *m, struct wl_list *list,
struct wlr_box *usable_area, int exclusive); struct wlr_box *usable_area, int exclusive);
static void arrangelayers(Monitor *m); static void arrangelayers(Monitor *m);
#if AUTOSTART_PATCH
static void autostartexec(void);
#endif // AUTOSTART_PATCH
static void axisnotify(struct wl_listener *listener, void *data); static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data); static void buttonpress(struct wl_listener *listener, void *data);
static void chvt(const Arg *arg); static void chvt(const Arg *arg);
@@ -432,6 +436,11 @@ static xcb_atom_t netatom[NetLast];
/* attempt to encapsulate suck into one file */ /* attempt to encapsulate suck into one file */
#include "client.h" #include "client.h"
#if AUTOSTART_PATCH
static pid_t *autostart_pids;
static size_t autostart_len;
#endif // AUTOSTART_PATCH
/* function implementations */ /* function implementations */
void void
applybounds(Client *c, struct wlr_box *bbox) applybounds(Client *c, struct wlr_box *bbox)
@@ -580,6 +589,29 @@ arrangelayers(Monitor *m)
} }
} }
#if AUTOSTART_PATCH
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);
}
}
#endif // AUTOSTART_PATCH
void void
axisnotify(struct wl_listener *listener, void *data) axisnotify(struct wl_listener *listener, void *data)
{ {
@@ -676,11 +708,25 @@ checkidleinhibitor(struct wlr_surface *exclude)
void void
cleanup(void) cleanup(void)
{ {
#if AUTOSTART_PATCH
size_t i;
#endif // AUTOSTART_PATCH
#ifdef XWAYLAND #ifdef XWAYLAND
wlr_xwayland_destroy(xwayland); wlr_xwayland_destroy(xwayland);
xwayland = NULL; xwayland = NULL;
#endif #endif
wl_display_destroy_clients(dpy); wl_display_destroy_clients(dpy);
#if AUTOSTART_PATCH
/* 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);
}
}
#endif // AUTOSTART_PATCH
if (child_pid > 0) { if (child_pid > 0) {
kill(-child_pid, SIGTERM); kill(-child_pid, SIGTERM);
waitpid(child_pid, NULL, 0); waitpid(child_pid, NULL, 0);
@@ -1500,6 +1546,33 @@ void
handlesig(int signo) handlesig(int signo)
{ {
if (signo == SIGCHLD) { if (signo == SIGCHLD) {
#if AUTOSTART_PATCH
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
#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 // AUTOSTART_PATCH
#ifdef XWAYLAND #ifdef XWAYLAND
siginfo_t in; siginfo_t in;
/* wlroots expects to reap the XWayland process itself, so we /* wlroots expects to reap the XWayland process itself, so we
@@ -1512,6 +1585,7 @@ handlesig(int signo)
#else #else
while (waitpid(-1, NULL, WNOHANG) > 0); while (waitpid(-1, NULL, WNOHANG) > 0);
#endif #endif
#endif // AUTOSTART_PATCH
} else if (signo == SIGINT || signo == SIGTERM) { } else if (signo == SIGINT || signo == SIGTERM) {
quit(NULL); quit(NULL);
} }
@@ -2227,6 +2301,9 @@ run(char *startup_cmd)
die("startup: backend_start"); die("startup: backend_start");
/* Now that the socket exists and the backend is started, run the startup command */ /* Now that the socket exists and the backend is started, run the startup command */
#if AUTOSTART_PATCH
autostartexec();
#endif // AUTOSTART_PATCH
if (startup_cmd) { if (startup_cmd) {
int piperw[2]; int piperw[2];
if (pipe(piperw) < 0) if (pipe(piperw) < 0)

1
patches.def.h Normal file
View File

@@ -0,0 +1 @@
#define AUTOSTART_PATCH 1

154
patches/autostart-0.7.patch Normal file
View File

@@ -0,0 +1,154 @@
From 787f7252d63945996f009828aff3c44afd0f7781 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@proton.me>
Date: Sat, 8 Jul 2023 17:11:36 -0600
Subject: [PATCH] port autostart patch from dwm
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://dwm.suckless.org/patches/cool_autostart/
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
config.def.h | 7 +++++++
dwl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/config.def.h b/config.def.h
index 22d2171..8dc6502 100644
--- a/config.def.h
+++ b/config.def.h
@@ -20,6 +20,13 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
/* logging */
static int log_level = WLR_ERROR;
+/* Autostart */
+static const char *const autostart[] = {
+ "wbg", "/path/to/your/image", NULL,
+ NULL /* terminate */
+};
+
+
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */
diff --git a/dwl.c b/dwl.c
index 5bf995e..e8b8727 100644
--- a/dwl.c
+++ b/dwl.c
@@ -249,6 +249,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 void buttonpress(struct wl_listener *listener, void *data);
static void chvt(const Arg *arg);
@@ -432,6 +433,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)
@@ -580,6 +584,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)
{
@@ -676,11 +701,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);
@@ -1497,18 +1532,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);
}
@@ -2224,6 +2272,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) {
int piperw[2];
if (pipe(piperw) < 0)
--
2.45.2