From 1c88b990159cbf663076f4fe6fb94b614c6d8d10 Mon Sep 17 00:00:00 2001 From: Fyodor Doletov Date: Fri, 20 Mar 2026 23:11:33 +0300 Subject: [PATCH] feat: fd-based readiness notification --- src/mango.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/mango.c b/src/mango.c index 93c049f4..58bbb1f6 100644 --- a/src/mango.c +++ b/src/mango.c @@ -666,7 +666,7 @@ static void requestdecorationmode(struct wl_listener *listener, void *data); static void requestdrmlease(struct wl_listener *listener, void *data); static void requeststartdrag(struct wl_listener *listener, void *data); static void resize(Client *c, struct wlr_box geo, int32_t interact); -static void run(char *startup_cmd); +static void run(char *startup_cmd, int readiness_fd); static void setcursor(struct wl_listener *listener, void *data); static void setfloating(Client *c, int32_t floating); static void setfakefullscreen(Client *c, int32_t fakefullscreen); @@ -4918,7 +4918,7 @@ cleanup: } void // 17 -run(char *startup_cmd) { +run(char *startup_cmd, int readiness_fd) { set_env(); @@ -4979,6 +4979,15 @@ run(char *startup_cmd) { run_exec(); run_exec_once(); + /* + * If running inside supervision suite like s6, notify about successfull startup + * by writing \n to the provided file descriptor and closing it + */ + if (readiness_fd > 2){ + write(readiness_fd, "\n", 1); + close(readiness_fd); + } + /* Run the Wayland event loop. This does not return until you exit the * compositor. Starting the backend rigged up all of the necessary event * loop configuration to listen to libinput events, DRM events, generate @@ -6631,8 +6640,9 @@ static void setgeometrynotify(struct wl_listener *listener, void *data) { int32_t main(int32_t argc, char *argv[]) { char *startup_cmd = NULL; int32_t c; + int readiness_fd = 0; - while ((c = getopt(argc, argv, "s:c:hdvp")) != -1) { + while ((c = getopt(argc, argv, "s:c:r:hdvp")) != -1) { if (c == 's') { startup_cmd = optarg; } else if (c == 'd') { @@ -6644,6 +6654,11 @@ int32_t main(int32_t argc, char *argv[]) { cli_config_path = optarg; } else if (c == 'p') { return parse_config() ? EXIT_SUCCESS : EXIT_FAILURE; + } else if (c == 'r') { + readiness_fd = atoi(optarg); + if (readiness_fd < 3) { + goto usage; + } } else { goto usage; } @@ -6657,7 +6672,7 @@ int32_t main(int32_t argc, char *argv[]) { if (!getenv("XDG_RUNTIME_DIR")) die("XDG_RUNTIME_DIR must be set"); setup(); - run(startup_cmd); + run(startup_cmd, readiness_fd); cleanup(); return EXIT_SUCCESS; usage: @@ -6668,6 +6683,7 @@ usage: " -d Enable debug log\n" " -c Use custom configuration file\n" " -s Execute startup command\n" + " -r When WM is ready, write '\\n' to the given file descriptor and close it. fdnum >= 3\n" " -p Check configuration file error\n"); return EXIT_SUCCESS; }