import Quickshell import Quickshell.Services.Greetd import QtQuick import QtQuick.Window Window { id: root visible: true visibility: Window.FullScreen flags: Qt.Window | Qt.FramelessWindowHint onClosing: close => { close.accepted = false; } color: "black" property string password: "" property string errorMessage: "" property bool busy: false Component.onCompleted: Quickshell.watchFiles = false function failed(message) { password = ""; busy = false; errorMessage = message; handoff.stop(); veil.opacity = 0; } Connections { target: Greetd function onAuthMessage(message, error, responseRequired, echoResponse) { if (responseRequired) { // This greeter supports the configured password-only PAM flow. if (echoResponse || root.password === "") { Greetd.cancelSession(); root.failed("Use a text console for this prompt"); return; } Greetd.respond(root.password); root.password = ""; } else if (error) root.errorMessage = message; } function onAuthFailure(message) { root.failed("Authentication failed"); } function onError(error) { root.failed("Login unavailable; try again"); } function onReadyToLaunch() { root.password = ""; handoff.start(); } } // Fade to black before greetd swaps compositors. Hyprland starts on // black and Quickshell fades the wallpaper in, so the VT gap between // the two hides inside the dark instead of flashing. SequentialAnimation { id: handoff NumberAnimation { target: veil; property: "opacity"; to: 1; duration: 350; easing.type: Easing.InQuad } ScriptAction { script: { // PAM/logind must know this is a graphical session before the // compositor starts, including for the pre-suspend lock check. Greetd.launch([Quickshell.env("FRED_SESSION_COMMAND")], [ "XDG_SESSION_TYPE=wayland", "XDG_CURRENT_DESKTOP=Hyprland", "XDG_SESSION_DESKTOP=Hyprland" ]); } } } AuthView { anchors.fill: parent theme: Theme busy: root.busy errorMessage: root.errorMessage onSubmitted: password => { if (root.busy || password === "") return; if (!Greetd.available) { root.failed("Login service unavailable"); return; } root.errorMessage = ""; root.password = password; root.busy = true; Greetd.createSession("fred"); } } Rectangle { id: veil; anchors.fill: parent; color: "black"; opacity: 0 } }