Fade login handoff through black, spinner while authenticating

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-09-23 10:59:58 +01:00
parent 554eec97b0
commit 55ac1c67ed
5 changed files with 51 additions and 9 deletions

View file

@ -224,7 +224,9 @@ in
# show as urgent in the bar instead.
focus_on_activate = false;
vrr = 2;
background_color = rgb c.base00;
# Black, not base00: login hands over greeter fade → black →
# Quickshell wallpaper fade, and only shows before that maps.
background_color = "rgb(000000)";
# If quickshell dies while holding the session lock, let its
# restarted instance re-attach instead of a dead red screen.
allow_session_lock_restore = true;

View file

@ -1137,6 +1137,15 @@ in
id: wallLayer
anchors.fill: parent
// Rise out of black at login: the greeter fades
// to black and Hyprland starts on black
// (misc.background_color), so no step shows.
NumberAnimation on opacity {
from: 0; to: 1
duration: 600
easing.type: Easing.OutQuad
}
readonly property string wanted: "file://" + Theme.wallImage
property bool bFront: false

View file

@ -194,6 +194,23 @@ Item {
Keys.onEscapePressed: text = ""
}
// Spinner while PAM checks the password (and, in the greeter,
// through the fade-out into the session).
Text {
anchors.centerIn: parent
visible: view.busy
text: "loader-circle"
font.family: view.theme.iconFont
font.pixelSize: 20
color: view.theme.accent
RotationAnimation on rotation {
running: view.busy
from: 0; to: 360
duration: 900
loops: Animation.Infinite
}
}
// Visible confirm button (after TextInput: on top)
Rectangle {
anchors.right: parent.right

View file

@ -19,6 +19,8 @@ Window {
password = "";
busy = false;
errorMessage = message;
handoff.stop();
veil.opacity = 0;
}
Connections {
target: Greetd
@ -38,6 +40,17 @@ Window {
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")], [
@ -47,6 +60,7 @@ Window {
]);
}
}
}
AuthView {
anchors.fill: parent
theme: Theme
@ -64,4 +78,5 @@ Window {
Greetd.createSession("fred");
}
}
Rectangle { id: veil; anchors.fill: parent; color: "black"; opacity: 0 }
}

View file

@ -304,7 +304,6 @@ let
+ ''["col.border_locked_active"]="rgb(${s.base05})",''
+ ''groupbar={text_color="rgb(${s.base05})",''
+ ''["col.active"]="rgb(${ink4})",["col.inactive"]="rgb(${ink3})"}}'')
''misc={background_color="rgb(${s.base00})"}''
] + "})");
# ── App icons ──────────────────────────────────────────────────────────