sway-systemd icon indicating copy to clipboard operation
sway-systemd copied to clipboard

Compositor-agnostic way of waiting for compositor exit

Open alebastr opened this issue 4 years ago • 7 comments

session.sh script is currently using swaymsg -t subscribe '["shutdown"]' to run tasks on compositor exit. That prevents the script from being reusable in other wayland compositors, e.g. wayfire.

The more portable options are to connect to the wayland socket and wait until it is closed or to lookup the compositor pid by the wayland socket and wait for it's exit with tail --pid.

alebastr avatar Feb 20 '21 22:02 alebastr

Is there any plans to implement this? I would like to use session.sh with River

Sunderland93 avatar Aug 24 '23 14:08 Sunderland93

@alebastr If I understand you correctly, then you are suggesting something like this?

if [[ -O "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY:-wayland-0}" ]]; then
    if tmp_pid="$(lsof -t "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY:-wayland-0}" 2>&1)" ||
        tmp_pid="$(fuser   "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY:-wayland-0}" 2>&1)"; then
            wm="$(ps -p "${tmp_pid}" -ho comm=)"
    fi
fi

wm_pid=$(pidof "$wm")

trap session_cleanup INT TERM

tail -f --pid="$wm_pid"

Sunderland93 avatar Sep 13 '23 20:09 Sunderland93

Something like this should be more accurate

// g++ $(pkg-config --cflags --libs wayland-client) wl-compositor-exit.cpp
#include <cstdio>
#include <cstdlib>
#include <wayland-client.h>

int main(int, char **) {
    auto *display = wl_display_connect(nullptr);
    if (display == nullptr) {
        fputs("Unable to connect to Wayland socket\n", stderr);
        return EXIT_FAILURE;
    }
    while (wl_display_dispatch(display) != -1) {}
    fputs("Wayland connection is lost\n", stderr);
    return EXIT_SUCCESS;
}

But neither are good options - at this point it's no better than doing cleanup in a wrapper script:

session_cleanup () {
    ...
}
trap session_cleanup INT TERM
# run the compositor
/usr/bin/some-wayland-compositor --args
# run cleanup handler on normal exit
session_cleanup

Wrapper script will also allow you to start graphical-session-pre.target at the right moment (before the compositor), it's just not compatible with the idea of the project here.


river gives you one more option: the config is an executable and the process group of init will receive SIGTERM on exit. I.e. the same trick with setting trap before passing control to the layout generator should work.

alebastr avatar Sep 14 '23 04:09 alebastr

river gives you one more option: the config is an executable and the process group of init will receive SIGTERM on exit. I.e. the same trick with setting trap before passing control to the layout generator should work.

I run River with this script https://github.com/Tile-OS/tileos-settings-river/blob/master/usr/bin/start-river so this should work?

session_cleanup () {
    ...
}
trap session_cleanup INT TERM
# run the compositor
/usr/bin/start-river
# run cleanup handler on normal exit
session_cleanup

should work?

Sunderland93 avatar Sep 14 '23 07:09 Sunderland93

Ah, I understand. It should look like this?:

session_cleanup () {
    ...
}
trap session_cleanup INT TERM

# Set the default layout generator to be rivertile and start it.
# River will send the process group of the init executable SIGTERM on exit.
riverctl default-layout rivertile
rivertile -view-padding 6 -outer-padding 6 &

Sunderland93 avatar Sep 14 '23 13:09 Sunderland93

Ah, I understand. It should look like this?:

session_cleanup () { ... } trap session_cleanup INT TERM

Set the default layout generator to be rivertile and start it.

River will send the process group of the init executable SIGTERM on exit.

riverctl default-layout rivertile rivertile -view-padding 6 -outer-padding 6 &

& will make init script exit immediately after starting rivertile in the background. Probably not the behavior you want. This also doesn't call session_cleanup on normal exit. You can either do that explicitly after rivertile command or add 'EXIT' to the trap conditions.

alebastr avatar Sep 14 '23 16:09 alebastr

Thank you! This works as expected

trap session_cleanup EXIT INT TERM

# Set the default layout generator to be rivertile and start it.
# River will send the process group of the init executable SIGTERM on exit.
riverctl default-layout rivertile
rivertile -view-padding 6 -outer-padding 6

Sunderland93 avatar Sep 14 '23 18:09 Sunderland93