Code Monkey home page Code Monkey logo

uwsm's Introduction

Universal Wayland Session Manager

This is an experiment in creating a versatile tool for launching any standalone Wayland WM with environment management and systemd integration.

WIP. Use at your onw risk.

Concepts and features

  • WM-specific behavior is handled by plugins
    • currently supported: sway, wayfire, labwc
  • Two (and a half) modes of operation:
    • Starting a service
    • Running from shell (with two choices of scopes)
  • Maximum use of systemd units and dependencies for startup, operation, and shutdown
  • Systemd units are treated with hierarchy and universality in mind:
    • use specifiers
    • named from common to specific: wayland-${category}@${wm}.${unit_type}
    • allow for high-level name-.d drop-ins
  • Idempotently (well, best-effort-idempotently) handle environment:
    • On startup environment is prepared by:
      • sourcing shell profile
      • sourcing common wayland-session-env files (from $XDG_CONFIG_DIRS, $XDG_CONFIG_HOME)
      • sourcing ${wm}/env files (from $XDG_CONFIG_DIRS, $XDG_CONFIG_HOME)
    • Difference between inital state and prepared environment is exported into systemd user manager
    • Special variables are imported back from systemd user manager at various stages of startup (in shell mode)
    • On shutdown variables that were exported are unset from systemd user manager
    • Lists of variables for export import-back and cleanup are determined algorithmically by:
      • comparing environment before and after preparation procedures
      • boolean operations with predefined lists (tweakable by plugins)
  • Better control of XDG autostart apps:
    • Propagate Stop from xdg-desktop-autostart.target via a drop-in
  • Try best to shutdown session cleanly via more dependencies between units
  • Written in POSIX shell (a smidgen of masochism went into this code)

Installation

Put wayland-session script somewhere in $PATH. Put wayland-session-plugins dir somewhere in /lib:/usr/lib:/usr/local/lib:${HOME}/.local/lib

Ensure your WM does this sequentially upon startup:

  • exports WAYLAND_DISPLAY to systemd user manager
  • runs systemd-notify --ready after that

Example snippet for sway:

exec dbus-update-activation-environment --systemd \
					SWAYSOCK \
					DISPLAY \
					I3SOCK \
					WAYLAND_DISPLAY \
					XCURSOR_SIZE \
					XCURSOR_THEME \
	&& systemctl --user import-environment \
					SWAYSOCK \
					DISPLAY \
					I3SOCK \
					WAYLAND_DISPLAY \
					XCURSOR_SIZE \
					XCURSOR_THEME \
	&& systemd-notify --ready

Full systemd service operation

Short story:

Start with wayland-session ${wm} sd-start

Stop with either wayland-session ${wm} sd-stop or systemctl --user stop "wayland-wm@*.service"

Longer story:

(At least for now) Units are generated by the script (and plugins).

Run wayland-session ${wm} unitgen to populate ${XDG_RUNTIME_DIR} with them.

After that: systemctl --user start wayland-wm@${wm}.service to start WM.

Add --wait to hold terminal until session ends.

exec it from login shell to bind to login session:

exec systemctl --user start --wait wayland-wm@${wm}.service

Then to stop: systemctl --user stop "wayland-wm@*.service" (no need to specify WM here). If start command was run with exec, (i.e. from login shell on a tty or via .profile), this stop command also doubles as a logout command.

wayland-session is smart enough to find login session associated with current TTY and export (and later cleanup) $XDG_SESSION_ID, $XDG_VTNR to user manager environment. Even though when started as a service it does not have those vars at immediate disposal. (I really do not know it this is a good idea, but since there can be only one graphical session per user with systemd, seems like such).

This example starts sway wayland session automatically upon login on tty1 if system is in graphical.target

Short snippet for ~/.profile:

if [ "${0}" != "${0#-}" -a "$XDG_VTNR" = "1" ]
then
    exec wayland-session sway sd-start
fi

Extended snippet for ~/.profile:

WM=sway
if [ "${0}" != "${0#-}" -a "$XDG_VTNR" = "1" ] \
  && systemctl is-active -q graphical.target \
  && ! systemctl --user is-active -q wayland-wm@*.service
then
    wayland-session ${WM} unitgen
    echo Starting ${WM} WM
    exec systemctl --user start --wait wayland-wm@${WM}.service
fi

Pros:

  • Everything happens automagcally, maximum usage of systemd features

Cons:

  • Pro#1 can be a con depending on your philosophy. I honestly understand both sides of this.
  • (Probably counts as such) WM and its descendants are not a part of login session. If recommended way of starting graphical session is to exec systemctl --user start --wait ... then this command will be the sole occupant of login session apart from /bin/login.

Partial systemd operation

In this mode WM is launched directly from the script, and the script manages startup, targets, and eventual cleanup.

wayland-session $wm shell-start to start WM, In this mode WM is put into diretly-descendant scope with logging to jouranl (unit: wayland-wm-${WM}.scope, log identifier: wayland-wm-${WM})

wayland-session $wm shell-intstart also reexec the script itself with logging to journald (log identifier: wayland-session-${WM})

To stop wm either run wayland-sesion $wm shell-stop or just kill already running script instance.

Pros:

  • (probably counts as such) WM and its descendants are a direct part of login session.

Cons:

  • This mode is kinda semi-abandoned ATM.

WM-specific actions

Plugins provide WM support and associated functions. See wayland-session-plugins/*.sh.in for examples.

TODO

  • more plugins
  • invent a better way to stop xdg-desktop-portal-gtk.service on WM stop
  • maybe drop shell mode altogether

Compliments

Inspired by and adapted some techniques from:

uwsm's People

Contributors

vladimir-csp avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.