alebastr / sway-systemd

Systemd integration for Sway session
MIT License
141 stars 12 forks source link

Compositor-agnostic way of waiting for compositor exit #1

Open alebastr opened 3 years ago

alebastr commented 3 years ago

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.

Sunderland93 commented 1 year ago

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

Sunderland93 commented 1 year ago

@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"
alebastr commented 1 year ago

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.

Sunderland93 commented 1 year ago

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 commented 1 year ago

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 &
alebastr commented 1 year ago

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.

Sunderland93 commented 1 year ago

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