Name: sl-desktop-utils Version: 1.1.1 Release: 3%{?dist} Summary: Custom sl-greeter and sl-lock tools for Niri, including idle and sleep services License: LicenseRef-SLSRepo URL: https://slsrepo.com BuildArch: noarch Source0: sl-greeter.zip Source1: sl-lock.zip BuildRequires: unzip BuildRequires: systemd-rpm-macros Requires: bash Requires: coreutils Requires: grep Requires: systemd Requires: greetd Requires: quickshell Requires: niri Requires: wayidle Requires: gnome-keyring %description Custom sl-greeter and sl-lock tools for Niri, including idle and sleep services. %prep rm -rf sl-greeter sl-lock mkdir -p sl-greeter sl-lock unzip -q %{SOURCE0} -d sl-greeter unzip -q %{SOURCE1} -d sl-lock # If either archive is wrapped in a single top-level folder, flatten it. for dir in sl-greeter sl-lock; do num_dirs=$(find "$dir" -mindepth 1 -maxdepth 1 -type d ! -name "__MACOSX" | wc -l) num_files=$(find "$dir" -mindepth 1 -maxdepth 1 -type f ! -name ".DS_Store" | wc -l) if [ "$num_dirs" -eq 1 ] && [ "$num_files" -eq 0 ]; then wrapper=$(find "$dir" -mindepth 1 -maxdepth 1 -type d ! -name "__MACOSX" | head -n 1) find "$wrapper" -mindepth 1 -maxdepth 1 -exec mv -t "$dir" {} + rm -rf "$wrapper" "$dir/__MACOSX" "$dir/.DS_Store" 2>/dev/null || true fi done %build # Nothing to build. %install rm -rf %{buildroot} # sl-greeter install -d -m 755 %{buildroot}%{_sysconfdir}/greetd/sl-greeter cp -a sl-greeter/. %{buildroot}%{_sysconfdir}/greetd/sl-greeter/ install -Dm644 sl-greeter/niri-greeter.kdl %{buildroot}%{_sysconfdir}/greetd/niri-greeter.kdl find %{buildroot}%{_sysconfdir}/greetd/sl-greeter -type d -exec chmod 755 {} + find %{buildroot}%{_sysconfdir}/greetd/sl-greeter -type f -exec chmod 644 {} + # sl-lock global template install -d -m 755 %{buildroot}%{_datadir}/quickshell/sl-lock cp -a sl-lock/. %{buildroot}%{_datadir}/quickshell/sl-lock/ find %{buildroot}%{_datadir}/quickshell/sl-lock -type d -exec chmod 755 {} + find %{buildroot}%{_datadir}/quickshell/sl-lock -type f -exec chmod 644 {} + # Executables install -d -m 755 %{buildroot}%{_bindir} cat > %{buildroot}%{_bindir}/sl-lock <<'EOF' #!/bin/bash USER_CONF_DIR="$HOME/.config/quickshell/sl-lock" SYS_CONF_DIR="/usr/share/quickshell/sl-lock" # If the user doesn't have their own copy of the lock screen yet, create it. if [ ! -d "$USER_CONF_DIR" ]; then echo "Initializing sl-lock configuration in $USER_CONF_DIR..." mkdir -p "$USER_CONF_DIR" cp -a "$SYS_CONF_DIR/." "$USER_CONF_DIR/" chmod -R u+rwX "$USER_CONF_DIR" fi exec qs -c "$USER_CONF_DIR" "$@" EOF chmod 755 %{buildroot}%{_bindir}/sl-lock cat > %{buildroot}%{_bindir}/sl-lock-listener <<'EOF' #!/bin/bash LOCK_FILE="${XDG_RUNTIME_DIR:-/tmp}/sl-lock-listener.lock" exec 200>"$LOCK_FILE" flock -n 200 || exit 0 SESSION_ID=$(loginctl show-user "$USER" -p Display --value 2>/dev/null) if [ -z "$SESSION_ID" ]; then SESSION_ID=$(loginctl list-sessions --no-legend | grep " $USER " | awk '{print $1}' | head -n 1) fi if [ -z "$SESSION_ID" ]; then echo "Error: Completely failed to find a session for user $USER" exit 1 fi SESSION_PATH=$(busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager GetSession s "$SESSION_ID" 2>/dev/null | awk '{print $2}' | tr -d '"') if [ -n "$SESSION_PATH" ]; then echo "Success! Listening for locks on session: $SESSION_ID ($SESSION_PATH)" gdbus monitor --system --dest org.freedesktop.login1 --object-path "$SESSION_PATH" | grep --line-buffered "Session.Lock" | while read -r line; do if ! pgrep -f "qs -c .*sl-lock" >/dev/null 2>&1; then /usr/bin/sl-lock & fi done else echo "Error: Could not determine DBus path for session $SESSION_ID" exit 1 fi EOF chmod 755 %{buildroot}%{_bindir}/sl-lock-listener cat > %{buildroot}%{_bindir}/sl-idle-lock <<'EOF' #!/bin/bash TIMEOUT=${1:-300} while true; do /usr/bin/wayidle -t "$TIMEOUT" loginctl lock-session while [ "$(loginctl show-session "$XDG_SESSION_ID" -p LockedHint)" = "LockedHint=yes" ]; do sleep 2; done sleep 2 done EOF chmod 755 %{buildroot}%{_bindir}/sl-idle-lock # Systemd services install -d -m 755 %{buildroot}%{_unitdir} cat > %{buildroot}%{_unitdir}/sl-sleep-lock.service <<'EOF' [Unit] Description=Lock sessions before sleep Before=sleep.target [Service] Type=oneshot ExecStart=/usr/bin/loginctl lock-sessions [Install] WantedBy=sleep.target EOF install -d -m 755 %{buildroot}%{_userunitdir} cat > %{buildroot}%{_userunitdir}/sl-lock-listener.service <<'EOF' [Unit] Description=Sl Lock DBus Listener PartOf=graphical-session.target After=graphical-session.target [Service] ExecStart=/usr/bin/sl-lock-listener Restart=always RestartSec=3 [Install] WantedBy=graphical-session.target EOF install -d -m 755 %{buildroot}%{_unitdir}/greetd.service.d cat > %{buildroot}%{_unitdir}/greetd.service.d/override.conf <<'EOF' [Unit] After=systemd-user-sessions.service plymouth-quit.service plymouth-quit-wait.service Conflicts=getty@tty2.service [Service] Environment=LIBSEAT_BACKEND=logind EOF # Elogind sleep hook for non-systemd systems install -d -m 755 %{buildroot}/usr/lib/elogind/system-sleep cat > %{buildroot}/usr/lib/elogind/system-sleep/10-sl-sleep-lock.sh <<'EOF' #!/bin/sh if [ "$1" = "pre" ]; then /usr/bin/loginctl lock-sessions fi EOF chmod 755 %{buildroot}/usr/lib/elogind/system-sleep/10-sl-sleep-lock.sh # Profile.d autostart hook for non-systemd systems install -d -m 755 %{buildroot}%{_sysconfdir}/profile.d cat > %{buildroot}%{_sysconfdir}/profile.d/sl-lock-autostart.sh <<'EOF' # Auto-start sl-lock-listener for graphical sessions on non-systemd systems if [ ! -d /run/systemd/system ] && [ "$XDG_SESSION_CLASS" != "greeter" ]; then ( timeout=60 while [ $timeout -gt 0 ]; do if [ -n "$WAYLAND_DISPLAY" ] && [ -S "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" ]; then break fi sock=$(ls -1t "$XDG_RUNTIME_DIR"/wayland-* 2>/dev/null | head -n 1) if [ -n "$sock" ] && [ -S "$sock" ]; then export WAYLAND_DISPLAY="$(basename "$sock")" break fi sleep 1 timeout=$((timeout - 1)) done if [ -n "$WAYLAND_DISPLAY" ]; then sleep 1 /usr/bin/sl-lock-listener >/dev/null 2>&1 & fi ) & fi EOF chmod 644 %{buildroot}%{_sysconfdir}/profile.d/sl-lock-autostart.sh %post if command -v systemd-sysusers >/dev/null 2>&1 && [ -f /usr/lib/sysusers.d/greetd.conf ]; then systemd-sysusers /usr/lib/sysusers.d/greetd.conf || true fi cat > /etc/greetd/config.toml <<'EOF' [terminal] vt = 2 [default_session] command = "niri -c /etc/greetd/niri-greeter.kdl > /dev/null 2>&1" user = "greeter" EOF mkdir -p /usr/local/share/backgrounds if [ -e /usr/share/backgrounds/archlinux/simple.png ]; then ln -sf /usr/share/backgrounds/archlinux/simple.png /usr/local/share/backgrounds/sl-greeter-current-background elif [ -e /usr/share/backgrounds/default.png ]; then ln -sf /usr/share/backgrounds/default.png /usr/local/share/backgrounds/sl-greeter-current-background fi ln -sf /usr/local/share/backgrounds/sl-greeter-current-background /etc/greetd/sl-greeter/current-background mkdir -p /var/lib/greetd/.config if getent passwd greeter >/dev/null 2>&1; then chown -R greeter:greeter /var/lib/greetd /etc/greetd fi if [ -f /etc/pam.d/greetd ] && ! grep -q 'pam_gnome_keyring\.so' /etc/pam.d/greetd; then echo 'auth optional pam_gnome_keyring.so' >> /etc/pam.d/greetd echo 'session optional pam_gnome_keyring.so auto_start' >> /etc/pam.d/greetd fi if [ -d /run/systemd/system ]; then systemctl daemon-reload || true systemctl enable sl-sleep-lock.service || true systemctl --global enable sl-lock-listener.service || true fi REAL_USER=${SUDO_USER:-$(awk -F ":" '$3 >= 1000 && $3 < 60000 && $6 ~ /^\/home\// {print $1; exit}' /etc/passwd)} if [ -n "$REAL_USER" ] && [ "$REAL_USER" != "root" ]; then USER_HOME=$(eval echo "~$REAL_USER") if [ -n "$USER_HOME" ] && [ -d "$USER_HOME" ]; then if [ ! -d "$USER_HOME/.config/quickshell/sl-lock" ]; then mkdir -p "$USER_HOME/.config/quickshell/sl-lock" cp -a /usr/share/quickshell/sl-lock/. "$USER_HOME/.config/quickshell/sl-lock/" fi chown -R "$REAL_USER:$REAL_USER" "$USER_HOME/.config/quickshell" || true chown -R "$REAL_USER:$REAL_USER" /usr/local/share/backgrounds || true fi fi cat <<'EOF' ================================================================= sl-desktop-utils installed successfully! To use sl-lock with Niri, add the following to your config.kdl: // Idle timer and listener spawn-at-startup "sl-lock-listener" spawn-at-startup "sl-idle-lock" "300" // Add a keybind inside your binds { ... } block Mod+Alt+L { spawn "sl-lock"; } // Lock the screen when the laptop lid is closed switch-events { lid-closed { spawn "sl-lock"; } } To apply the new greetd configuration, restart greetd or reboot. ================================================================= EOF %postun if [ $1 -eq 0 ]; then if [ -d /run/systemd/system ]; then systemctl disable --now sl-sleep-lock.service >/dev/null 2>&1 || true systemctl --global disable sl-lock-listener.service >/dev/null 2>&1 || true systemctl daemon-reload >/dev/null 2>&1 || true fi fi %files %config(noreplace) %{_sysconfdir}/greetd/niri-greeter.kdl %{_sysconfdir}/greetd/sl-greeter/ %{_bindir}/sl-lock %{_bindir}/sl-lock-listener %{_bindir}/sl-idle-lock %{_datadir}/quickshell/sl-lock/ %{_unitdir}/sl-sleep-lock.service %{_userunitdir}/sl-lock-listener.service %{_unitdir}/greetd.service.d/override.conf /usr/lib/elogind/system-sleep/10-sl-sleep-lock.sh %config(noreplace) %{_sysconfdir}/profile.d/sl-lock-autostart.sh