From 5b6a56419051c9cf40d02b3d88df7829b5a616c7 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Mon, 5 Jul 2021 09:21:21 +0200 Subject: [PATCH] main: signal readiness by notifying systemd This is useful if we want to be able to start some services depending on i3, notably some script using the socket or third-party bars like polybar. To make use of this change, user is expected to use the following stanza: ``` [Unit] Description=i3 window manager PartOf=graphical-session.target [Service] Type=notify ExecStart=/usr/bin/i3 ExecStopPost=/bin/systemctl --user stop graphical-session.target Restart=on-failure ``` Something similar is already possible using socket activation. For example, we could use: ``` [Unit] Description=i3 window manager socket PartOf=graphical-session.target [Socket] ListenStream=%t/i3.sock ExecStartPost=/bin/systemctl --user set-environment I3SOCK=%t/i3.sock ``` And other units could `Requires=i3.socket`. Unfortunately, not everything is using I3SOCK. Notably, `i3 --get-socketpath` does not and that's what i3ipcpp is doing. An alternative would be to patch `i3 --get-socketpath` to use I3SOCK if present, however, this may be a bit risky. Should we check the environment variable first or the root attribute? Another alternative not requiring any modification is to have a dedicated `i3-session.target`: ``` [Unit] Description=i3 session BindsTo=graphical-session.target Wants=wallpaper.service Wants=wallpaper.timer Wants=polybar.service Wants=i3-companion.service ``` And trigger it from i3: ``` exec_always --no-startup-id systemctl --user start --no-block i3-session.target ``` The proposed change being quite small, it seems harmless and low-maintenance. Signed-off-by: Vincent Bernat --- RELEASE-NOTES-next | 1 + src/main.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/RELEASE-NOTES-next b/RELEASE-NOTES-next index 8542b8fc8..2975cef29 100644 --- a/RELEASE-NOTES-next +++ b/RELEASE-NOTES-next @@ -45,6 +45,7 @@ option is enabled and only then sets a screenshot as background. • Add 'all' window matching criterion • Acquire the WM_Sn selection when starting as required by ICCCM • Add --replace command line argument to replace an existing WM + • Notify systemd when i3 is ready, allowing other services to use i3 as a dependency ┌────────────────────────────┐ │ Bugfixes │ diff --git a/src/main.c b/src/main.c index a588a0a23..c73601da6 100644 --- a/src/main.c +++ b/src/main.c @@ -1010,9 +1010,9 @@ int main(int argc, char *argv[]) { ev_io_start(main_loop, log_io); } - /* Also handle the UNIX domain sockets passed via socket activation. The - * parameter 1 means "remove the environment variables", we don’t want to - * pass these to child processes. */ + /* Also handle the UNIX domain sockets passed via socket + * activation. The parameter 0 means "do not remove the + * environment variables", we need to be able to reexec. */ listen_fds = sd_listen_fds(0); if (listen_fds < 0) ELOG("socket activation: Error in sd_listen_fds\n"); @@ -1196,5 +1196,6 @@ int main(int argc, char *argv[]) { * when calling exit() */ atexit(i3_exit); + sd_notify(1, "READY=1"); ev_loop(main_loop, 0); }