From b50ee5dcea2b47d5b0d294a78b4c9fa3621f8ed9 Mon Sep 17 00:00:00 2001 From: Colin Date: Sun, 8 Oct 2023 17:12:53 +0000 Subject: [PATCH] WIP: sxmo: port to systemd --- hosts/by-name/lappy/polyfill.nix | 2 +- hosts/modules/gui/sxmo/default.nix | 76 +++++++++++++++++-- .../modules/gui/sxmo/hooks/sxmo_hook_start.sh | 36 ++++----- hosts/modules/gui/sxmo/hooks/sxmo_suspend.sh | 4 +- modules/users.nix | 19 ++++- pkgs/additional/sxmo-utils/common.nix | 12 ++- 6 files changed, 116 insertions(+), 33 deletions(-) diff --git a/hosts/by-name/lappy/polyfill.nix b/hosts/by-name/lappy/polyfill.nix index 691ae125..bad5633c 100644 --- a/hosts/by-name/lappy/polyfill.nix +++ b/hosts/by-name/lappy/polyfill.nix @@ -33,7 +33,7 @@ # and so it just wouldn't handle any button inputs (sxmo_hook_inputhandler.sh not on path) SXMO_DEVICE_NAME = "three_button_touchscreen"; }; - package = pkgs.sxmo-utils-latest.overrideAttrs (base: { + package = (pkgs.sxmo-utils-latest.override { preferSystemd = true; }).overrideAttrs (base: { postPatch = (base.postPatch or "") + '' # after volume-button navigation mode, restore full keyboard functionality cp ${./xkb_mobile_normal_buttons} ./configs/xkb/xkb_mobile_normal_buttons diff --git a/hosts/modules/gui/sxmo/default.nix b/hosts/modules/gui/sxmo/default.nix index bd38261f..ee31b7ba 100644 --- a/hosts/modules/gui/sxmo/default.nix +++ b/hosts/modules/gui/sxmo/default.nix @@ -20,7 +20,8 @@ # # sxmo technical overview: # - inputs -# - dwm: handles vol/power buttons; hardcoded in config.h +# - bonsaid: handles vol/power buttons +# - it receives those buttons from dwm (if x11) harcoded in config.h or sway (if wayland) # - lisgd: handles gestures # - startup # - daemon based (lisgsd, idle_locker, statusbar_periodics) @@ -44,9 +45,6 @@ # - menus: bemenu (if wayland), dmenu (if X) # - gestures: lisgd # - on-screen keyboard: wvkbd (if wayland), svkbd (if X) -# -# TODO: -# - theme `mako` notifications { config, lib, pkgs, ... }: let @@ -85,7 +83,7 @@ let start = pkgs.static-nix-shell.mkBash { pname = "sxmo_hook_start.sh"; src = ./hooks; - pkgs = [ "superd" "xdg-user-dirs" ]; + pkgs = [ "systemd" "xdg-user-dirs" ]; }; suspend = pkgs.static-nix-shell.mkBash { pname = "sxmo_suspend.sh"; @@ -123,7 +121,7 @@ in }; sane.gui.sxmo.package = mkOption { type = types.package; - default = pkgs.sxmo-utils-latest; + default = pkgs.sxmo-utils-latest.override { preferSystemd = true; }; description = '' sxmo base scripts and hooks collection. consider overriding the outputs under /share/sxmo/default_hooks @@ -436,6 +434,33 @@ in sane.user.fs = lib.mkMerge [ { + # link the superd services into a place where systemd can find them. + # the unit files should be compatible, except maybe for PATH handling + # ".config/systemd/user/autocutsel-primary.service".symlink.target = "${package}/share/superd/services/autocutsel-primary.service"; + # ".config/systemd/user/autocutsel.service".symlink.target = "${package}/share/superd/services/autocutsel.service"; + # ".config/systemd/user/bonsaid.service".symlink.target = "${package}/share/superd/services/bonsaid.service"; + # # ".config/systemd/user/dunst.service".symlink.target = "${package}/share/superd/services/dunst.service"; + # # ".config/systemd/user/mako.service".symlink.target = "${package}/share/superd/services/mako.service"; + # ".config/systemd/user/mmsd-tng.service".symlink.target = "${package}/share/superd/services/mmsd-tng.service"; + # ".config/systemd/user/sxmo_autosuspend.service".symlink.target = "${package}/share/superd/services/sxmo_autosuspend.service"; + # ".config/systemd/user/sxmo_battery_monitor.service".symlink.target = "${package}/share/superd/services/sxmo_battery_monitor.service"; + # ".config/systemd/user/sxmo_conky.service".symlink.target = "${package}/share/superd/services/sxmo_conky.service"; + # ".config/systemd/user/sxmo_desktop_widget.service".symlink.target = "${package}/share/superd/services/sxmo_desktop_widget.service"; + # ".config/systemd/user/sxmo_hook_lisgd.service".symlink.target = "${package}/share/superd/services/sxmo_hook_lisgd.service"; + # ".config/systemd/user/sxmo_menumode_toggler.service".symlink.target = "${package}/share/superd/services/sxmo_menumode_toggler.service"; + # ".config/systemd/user/sxmo_modemmonitor.service".symlink.target = "${package}/share/superd/services/sxmo_modemmonitor.service"; + # ".config/systemd/user/sxmo_networkmonitor.service".symlink.target = "${package}/share/superd/services/sxmo_networkmonitor.service"; + # ".config/systemd/user/sxmo_notificationmonitor.service".symlink.target = "${package}/share/superd/services/sxmo_notificationmonitor.service"; + # ".config/systemd/user/sxmo_soundmonitor.service".symlink.target = "${package}/share/superd/services/sxmo_soundmonitor.service"; + # ".config/systemd/user/sxmo_wob.service".symlink.target = "${package}/share/superd/services/sxmo_wob.service"; + # ".config/systemd/user/sxmo-x11-status.service".symlink.target = "${package}/share/superd/services/sxmo-x11-status.service"; + # ".config/systemd/user/unclutter.service".symlink.target = "${package}/share/superd/services/unclutter.service"; + # ".config/systemd/user/unclutter-xfixes.service".symlink.target = "${package}/share/superd/services/unclutter-xfixes.service"; + # ".config/systemd/user/vvmd.service".symlink.target = "${package}/share/superd/services/vvmd.service"; + + # service code further below tells systemd to put ~/.config/sxmo/hooks on PATH, but it puts hooks/bin on PATH instead, so symlink that + ".config/sxmo/hooks/bin".symlink.target = "."; + ".cache/sxmo/sxmo.noidle" = lib.mkIf cfg.noidle { symlink.text = ""; }; @@ -455,6 +480,45 @@ in value.symlink.target = value; }) cfg.hooks) ]; + + sane.user.services = let + sxmoPath = [ "/home/colin/.config/sxmo/hooks" package ] ++ package.runtimeDeps ++ [ + "/run/current-system/sw" # for flock wrapper + "/run/wrappers" # for doas + ]; + sxmoService = name: { + description = "sxmo ${name}"; + path = sxmoPath; + serviceConfig.ExecStart = "${pkgs.coreutils}/bin/env sxmo_${name}.sh"; + serviceConfig.Type = "simple"; + serviceConfig.Restart = "always"; + serviceConfig.RestartSec = "20s"; + }; + in { + sxmo_autosuspend = sxmoService "autosuspend"; + sxmo_battery_monitor = sxmoService "battery_monitor"; + sxmo_desktop_widget = sxmoService "hook_desktop_widget"; + sxmo_hook_lisgd = sxmoService "hook_lisgdstart"; + sxmo_menumode_toggler = sxmoService "menumode_toggler"; + sxmo_modemmonitor = sxmoService "modemmonitor"; + sxmo_networkmonitor = sxmoService "networkmonitor"; + sxmo_notificationmonitor = sxmoService "notificationmonitor"; + sxmo_soundmonitor = sxmoService "soundmonitor"; + sxmo_wob = sxmoService "wob"; + sxmo-x11-status = sxmoService "status_xsetroot"; + + bonsaid = { + description = "programmable input dispatcher"; + path = sxmoPath; + # systemd expands %E to $XDG_CONFIG_HOME + serviceConfig.ExecStart = "${pkgs.bonsai}/bin/bonsaid -t %E/sxmo/bonsai_tree.json"; + serviceConfig.ExecStartPre = "${pkgs.coreutils}/bin/rm -f %t/bonsai"; # systemd expands %t to $XDG_RUNTIME_DIR + serviceConfig.Type = "simple"; + serviceConfig.Restart = "always"; + serviceConfig.RestartSec = "5s"; + environment.SXMO_STATE = "/run/user/1000/sxmo.state"; #< TODO: this is $XDG_RUNTIME_DIR/sxmo.state + }; + }; } (lib.mkIf (cfg.greeter == "lightdm-mobile") { diff --git a/hosts/modules/gui/sxmo/hooks/sxmo_hook_start.sh b/hosts/modules/gui/sxmo/hooks/sxmo_hook_start.sh index 63339077..a4796257 100755 --- a/hosts/modules/gui/sxmo/hooks/sxmo_hook_start.sh +++ b/hosts/modules/gui/sxmo/hooks/sxmo_hook_start.sh @@ -1,5 +1,5 @@ #!/usr/bin/env nix-shell -#!nix-shell -i bash -p superd -p xdg-user-dirs +#!nix-shell -i bash -p systemd -p xdg-user-dirs # this is based on upstream sxmo-utils sxmo_hook_start.sh # but modified for nixos integration and specialize a bit to my needs . sxmo_common.sh @@ -7,23 +7,19 @@ # Create xdg user directories, such as ~/Pictures xdg-user-dirs-update -sxmo_daemons.sh start daemon_manager superd - -# let time to superd to start correctly -while ! superctl status > /dev/null 2>&1; do - sleep 0.5 -done +sxmo_daemons.sh start daemon_manager # Periodically update some status bar components sxmo_hook_statusbar.sh all sxmo_daemons.sh start statusbar_periodics sxmo_run_aligned.sh 60 \ sxmo_hook_statusbar.sh periodics -# don't: mako can be started lazily (via dbus activation, i think) +# TODO: start these externally, via `wantedBy` in nix +# don't: mako is managed externally # superctl start mako -superctl start sxmo_wob -superctl start sxmo_menumode_toggler -superctl start bonsaid +systemctl --user start sxmo_wob +systemctl --user start sxmo_menumode_toggler +systemctl --user start bonsaid # don't: sway background is managed externally # swaymsg output '*' bg "$SXMO_BG_IMG" fill @@ -32,17 +28,17 @@ sxmo_state_switch.sh set unlock # Turn on auto-suspend if [ -w "/sys/power/wakeup_count" ] && [ -f "/sys/power/wake_lock" ]; then - superctl start sxmo_autosuspend + systemctl --user start sxmo_autosuspend fi # Turn on lisgd if [ ! -e "$XDG_CACHE_HOME"/sxmo/sxmo.nogesture ]; then - superctl start sxmo_hook_lisgd + systemctl --user start sxmo_hook_lisgd fi if [ "$(command -v ModemManager)" ]; then # Turn on the dbus-monitors for modem-related tasks - superctl start sxmo_modemmonitor + systemctl --user start sxmo_modemmonitor # place a wakelock for 120s to allow the modem to fully warm up (eg25 + # elogind/systemd would do this for us, but we don't use those.) @@ -53,16 +49,16 @@ fi # superctl start sxmo_conky # Monitor the battery -superctl start sxmo_battery_monitor +systemctl --user start sxmo_battery_monitor # It watch network changes and update the status bar icon by example -superctl start sxmo_networkmonitor +systemctl --user start sxmo_networkmonitor # The daemon that display notifications popup messages -superctl start sxmo_notificationmonitor +systemctl --user start sxmo_notificationmonitor # monitor for headphone for statusbar -superctl start sxmo_soundmonitor +systemctl --user start sxmo_soundmonitor # rotate UI based on physical display angle by default if [ -n "$SXMO_AUTOROTATE" ]; then @@ -75,11 +71,11 @@ fi # mmsd and vvmd if [ -f "${SXMO_MMS_BASE_DIR:-"$HOME"/.mms/modemmanager}/mms" ]; then - superctl start mmsd-tng + systemctl --user start mmsd-tng fi if [ -f "${SXMO_VVM_BASE_DIR:-"$HOME"/.vvm/modemmanager}/vvm" ]; then - superctl start vvmd + systemctl --user start vvmd fi # add some warnings if things are not setup correctly diff --git a/hosts/modules/gui/sxmo/hooks/sxmo_suspend.sh b/hosts/modules/gui/sxmo/hooks/sxmo_suspend.sh index 57328f0f..7756a926 100755 --- a/hosts/modules/gui/sxmo/hooks/sxmo_suspend.sh +++ b/hosts/modules/gui/sxmo/hooks/sxmo_suspend.sh @@ -11,11 +11,11 @@ suspend_time=300 -sxmo_log "calling suspend with suspend_time <$suspend_time>" +sxmo_log "calling suspend for duration: $suspend_time" rtcwake -m mem -s "$suspend_time" || exit 1 -cat /proc/net/rtl8723cs/wlan0/wowlan_last_wake_reason +sxmo_log "exited suspend: $(cat /proc/net/rtl8723cs/wlan0/wowlan_last_wake_reason)" sxmo_hook_postwake.sh diff --git a/modules/users.nix b/modules/users.nix index 15fde29d..2f5cb5fa 100644 --- a/modules/users.nix +++ b/modules/users.nix @@ -56,6 +56,18 @@ let }; }; }; + defaultUserOptions = { + options = userOptions.options // { + services = mkOption { + # type = utils.systemdUtils.types.services; + # map to listOf attrs so that we can pass through + # w/o worrying about merging at this layer + type = types.attrsOf (types.coercedTo types.attrs (a: [ a ]) (types.listOf types.attrs)); + default = {}; + inherit (userOptions.options.services) description; + }; + }; + }; userModule = let nixConfig = config; in types.submodule ({ name, config, ... }: { options = userOptions.options // { default = mkOption { @@ -77,7 +89,10 @@ let config = lib.mkMerge [ # if we're the default user, inherit whatever settings were routed to the default user - (mkIf config.default sane-user-cfg) + (mkIf config.default { + inherit (sane-user-cfg) fs persist environment; + services = lib.mapAttrs (_: lib.mkMerge) sane-user-cfg.services; + }) { fs."/".dir.acl = { user = name; @@ -158,7 +173,7 @@ in }; sane.user = mkOption { - type = types.nullOr (types.submodule userOptions); + type = types.nullOr (types.submodule defaultUserOptions); default = null; description = '' options to pass down to the default user diff --git a/pkgs/additional/sxmo-utils/common.nix b/pkgs/additional/sxmo-utils/common.nix index efc832cf..b306cb0a 100644 --- a/pkgs/additional/sxmo-utils/common.nix +++ b/pkgs/additional/sxmo-utils/common.nix @@ -28,6 +28,7 @@ , mako , modemmanager , nettools +, networkmanager , playerctl , procps , pulseaudio @@ -39,6 +40,7 @@ , superd , sway , swayidle +, systemd , wob , wl-clipboard , wtype @@ -53,6 +55,7 @@ , patches ? [] , supportSway ? true , supportDwm ? false +, preferSystemd ? false }: let @@ -75,15 +78,17 @@ let mako modemmanager # mmcli nettools # netstat + networkmanager # nmcli playerctl procps # pgrep pulseaudio # pactl sfeed - superd wob xdg-user-dirs # used by sxmo_hook_start.sh xrdb # for sxmo_xinit AND sxmo_winit - ] ++ lib.optionals supportSway [ + ] ++ ( + if preferSystemd then [ systemd ] else [ superd ] + ) ++ lib.optionals supportSway [ bemenu grim slurp # for sxmo_screenshot.sh @@ -127,6 +132,8 @@ stdenv.mkDerivation rec { substituteInPlace configs/udev/90-sxmo.rules \ --replace "/bin/chgrp" "${coreutils}/bin/chgrp" \ --replace "/bin/chmod" "${coreutils}/bin/chmod" + '' + lib.optionalString preferSystemd '' + sed -i 's/superctl/systemctl --user/g' **/*.sh ''; nativeBuildInputs = [ @@ -171,6 +178,7 @@ stdenv.mkDerivation rec { ''; passthru = { + inherit runtimeDeps; providedSessions = (lib.optional supportSway "swmo") ++ (lib.optional supportDwm "sxmo"); updateScript = gitUpdater { }; };