diff --git a/mango/local-bin/init-lockscreen b/mango/local-bin/init-lockscreen index 266c715..4de867a 100755 --- a/mango/local-bin/init-lockscreen +++ b/mango/local-bin/init-lockscreen @@ -1,9 +1,6 @@ #!/bin/bash -LOCK="$HOME/.local/share/quickshell-lockscreen/lock.sh" -killall swayidle +LOCK="$HOME/.config/qylock-ready/lock-before-sleep.sh" +killall swayidle 2>/dev/null || true sleep 0.1 swayidle -w \ - before-sleep "bash $LOCK" \ - # lock "bash $LOCK" & - # before-sleep 'swaylock -i ~/pictures/bgs/lockscreen/neco2.png --effect-blur 7x5 --effect-vignette 0.5:0.5 --clock --indicator --ring-color E8D4A0FF --key-hl-color F4A261FF --bs-hl-color EE9B00FF --inside-color 00000088 --text-color FFFFFFFF --line-color 00000000 --separator-color 00000000' \ - # lock 'swaylock -i ~/pictures/bgs/lockscreen/neco2.png.jpg --effect-blur 7x5 --effect-vignette 0.5:0.5 --clock --indicator --ring-color E8D4A0FF --key-hl-color F4A261FF --bs-hl-color EE9B00FF --inside-color 00000088 --text-color FFFFFFFF --line-color 00000000 --separator-color 00000000' & + before-sleep "bash $LOCK" & diff --git a/mango/qylock-ready/README.md b/mango/qylock-ready/README.md new file mode 100644 index 0000000..baae575 --- /dev/null +++ b/mango/qylock-ready/README.md @@ -0,0 +1,8 @@ +# Custom qylock system + +Purpose of this is to add a lock file to safely initialize the lockscreen after hibernate + +shim from original qylock is required: +``` +ln -sfn $HOME/.local/share/quickshell-lockscreen/shim $HOME/.config/qylock-ready/shim +``` diff --git a/mango/qylock-ready/lock-before-sleep.sh b/mango/qylock-ready/lock-before-sleep.sh new file mode 100755 index 0000000..b8b182c --- /dev/null +++ b/mango/qylock-ready/lock-before-sleep.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -euo pipefail + +CUSTOM_DIR="/home/kokopi/.config/qylock-ready" +UPSTREAM_DIR="/home/kokopi/.local/share/quickshell-lockscreen" +QML="$CUSTOM_DIR/lock_shell_ready.qml" +READY_FILE="$(mktemp -u "${XDG_RUNTIME_DIR:-/tmp}/qylock-ready.XXXXXX")" + +cleanup() { + rm -f "$READY_FILE" +} +trap cleanup EXIT + +# Match upstream lock.sh environment setup +export QML2_IMPORT_PATH="$UPSTREAM_DIR/imports:${QML2_IMPORT_PATH:-}" +export QML_XHR_ALLOW_FILE_READ=1 +export XDG_SESSION_TYPE="${XDG_SESSION_TYPE:-$(loginctl show-session "$(loginctl | grep "$(whoami)" | awk '{print $1}')" -p Type --value 2>/dev/null || echo wayland)}" + +CONFIG_FILE="$HOME/.config/qylock/theme" +if [ -n "${1:-}" ]; then + export QS_THEME="${1:-nier-automata}" +elif [ -f "$CONFIG_FILE" ]; then + export QS_THEME="${1:-nier-automata}" +else + export QS_THEME="${1:-nier-automata}" +fi + +if [ -d "$UPSTREAM_DIR/../themes" ] && [ ! -d "$UPSTREAM_DIR/themes_link" ]; then + export QS_THEME_PATH="$UPSTREAM_DIR/../themes/$QS_THEME" +else + export QS_THEME_PATH="$UPSTREAM_DIR/themes_link/$QS_THEME" +fi + +rm -f "$READY_FILE" +killall -9 hyprlock swaylock wlogout 2>/dev/null || true + +QYLOCK_READY_FILE="$READY_FILE" quickshell -p "$QML" & +pid=$! + +for _ in $(seq 1 200); do + if [[ -e "$READY_FILE" ]]; then + exit 0 + fi + + if ! kill -0 "$pid" 2>/dev/null; then + wait "$pid" + echo "qylock exited before becoming ready" >&2 + exit 1 + fi + + sleep 0.05 +done + +echo "qylock did not become ready in time" >&2 +exit 1 diff --git a/mango/qylock-ready/lock_shell_ready.qml b/mango/qylock-ready/lock_shell_ready.qml new file mode 100644 index 0000000..1c7dd69 --- /dev/null +++ b/mango/qylock-ready/lock_shell_ready.qml @@ -0,0 +1,135 @@ +import QtQuick +import Quickshell +import Quickshell.Wayland +import QtMultimedia +import "./shim" + +ShellRoot { + id: shellRoot + + property string baseDir: "/home/kokopi/.local/share/quickshell-lockscreen" + property string activeTheme: Quickshell.env("QS_THEME") || "nier-automata" + property string themePath: Quickshell.env("QS_THEME_PATH") || (baseDir + "/themes_link/" + activeTheme) + property string readyFile: Quickshell.env("QYLOCK_READY_FILE") || "" + property bool readySent: false + + readonly property var sddm: sddmShim.sddm + readonly property var config: sddmShim.config + readonly property var userModel: sddmShim.userModel + readonly property var sessionModel: sddmShim.sessionModel + readonly property bool isWayland: Quickshell.env("XDG_SESSION_TYPE") === "wayland" + property bool authenticated: false + property bool sessionLocked: true + property bool isTesting: Quickshell.env("QS_TESTING") === "1" + + function signalReady() { + if (readySent || readyFile === "") + return + + readySent = true + Quickshell.execDetached([ + "sh", "-c", + "umask 077; : > \"$1\"", + "sh", readyFile + ]) + } + + SddmShim { + id: sddmShim + themePath: shellRoot.themePath + } + + Connections { + target: sddmShim.sddm + function onLoginSucceeded() { + shellRoot.authenticated = true + shellRoot.sessionLocked = false + + if (Quickshell.env("XDG_CURRENT_DESKTOP") === "Hyprland" || Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE") !== "") { + Quickshell.execDetached(["hyprctl", "keyword", "misc:allow_session_lock_restore", "1"]); + } + Quickshell.execDetached(["loginctl", "unlock-session"]); + quitTimer.start() + } + } + + Timer { + id: quitTimer + interval: 1500 + onTriggered: Qt.quit() + } + + Component { + id: themeComponent + Loader { + anchors.fill: parent + source: "file://" + shellRoot.themePath + "/Main.qml" + + onLoaded: item.forceActiveFocus() + onStatusChanged: { + if (status === Loader.Error) { + console.error("FAILED to load theme:", source) + } + } + } + } + + Loader { + id: waylandLoader + active: shellRoot.isWayland + sourceComponent: Component { + WlSessionLock { + id: lock + locked: shellRoot.sessionLocked + + onSecureStateChanged: { + if (secure) + shellRoot.signalReady() + } + + surface: Component { + WlSessionLockSurface { + color: "black" + Loader { + anchors.fill: parent + sourceComponent: themeComponent + } + } + } + } + } + } + + Loader { + id: x11Loader + active: !shellRoot.isWayland + sourceComponent: Component { + Variants { + model: Quickshell.screens + delegate: Window { + id: window + required property var modelData + screen: modelData + width: isTesting ? 1280 : screen.width + height: isTesting ? 720 : screen.height + visible: shellRoot.sessionLocked + visibility: isTesting ? Window.Windowed : Window.FullScreen + + Component.onCompleted: shellRoot.signalReady() + + onClosing: (close) => { + close.accepted = shellRoot.authenticated || shellRoot.isTesting; + } + + flags: Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.MaximizeUsingFullscreenGeometryHint + color: "black" + + Loader { + anchors.fill: parent + sourceComponent: themeComponent + } + } + } + } + } +}