// Thème SDDM « fws » — écran de connexion FWS (KDE / XFCE / Hyprland). // // VOLONTAIREMENT en pur QtQuick + QtQuick.Controls (style Basic) : ces // modules arrivent avec qt6-declarative, dépendance de sddm lui-même → // AUCUN paquet supplémentaire requis (pas de Breeze/plasma-workspace, pas // de QtGraphicalEffects — supprimé en Qt6). Le greeter fournit en contexte // les objets sddm, userModel, sessionModel, keyboard et config (theme.conf, // surchargé par theme.conf.user écrit par le %post : accent selon le DE). import QtQuick import QtQuick.Controls.Basic Rectangle { id: root width: 1280 height: 800 readonly property color accent: config.accent || "#3daee9" readonly property color fieldBg: "#2a2a44" gradient: Gradient { GradientStop { position: 0.0; color: config.colorTop || "#1a1a2e" } GradientStop { position: 1.0; color: config.colorBottom || "#16213e" } } Connections { target: sddm function onLoginFailed() { errorLabel.text = "Échec de la connexion — vérifiez le mot de passe" passwordField.text = "" passwordField.forceActiveFocus() } function onLoginSucceeded() { errorLabel.text = "" } } function doLogin() { errorLabel.text = "" sddm.login(userField.text, passwordField.text, sessionBox.currentIndex) } // --- Horloge ----------------------------------------------------------- Timer { interval: 1000 running: true repeat: true onTriggered: { var now = new Date() clockLabel.text = Qt.formatTime(now, "hh:mm") dateLabel.text = Qt.formatDate(now, "dddd d MMMM yyyy") } Component.onCompleted: triggered() } Column { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top anchors.topMargin: parent.height * 0.10 spacing: 4 Text { id: clockLabel anchors.horizontalCenter: parent.horizontalCenter color: "#f0f0f5" font.pixelSize: 84 font.weight: Font.Light } Text { id: dateLabel anchors.horizontalCenter: parent.horizontalCenter color: "#a0a0b8" font.pixelSize: 20 font.capitalization: Font.Capitalize } } // --- Carte de connexion -------------------------------------------------- Rectangle { id: card anchors.centerIn: parent anchors.verticalCenterOffset: parent.height * 0.08 width: 400 height: cardContent.implicitHeight + 56 radius: 14 color: "#232338" border.color: Qt.rgba(1, 1, 1, 0.10) border.width: 1 Column { id: cardContent anchors.centerIn: parent width: parent.width - 56 spacing: 14 Text { anchors.horizontalCenter: parent.horizontalCenter text: config.greeting || "Bienvenue sur FWS" color: "#f0f0f5" font.pixelSize: 22 font.weight: Font.Medium } Rectangle { width: 44; height: 3; radius: 1.5; color: accent anchors.horizontalCenter: parent.horizontalCenter } TextField { id: userField width: parent.width text: userModel.lastUser placeholderText: "Utilisateur" placeholderTextColor: "#7d7d95" color: "#f0f0f5" font.pixelSize: 15 leftPadding: 14 background: Rectangle { radius: 8 color: fieldBg border.color: userField.activeFocus ? accent : "transparent" border.width: 2 } onAccepted: passwordField.forceActiveFocus() } TextField { id: passwordField width: parent.width placeholderText: "Mot de passe" placeholderTextColor: "#7d7d95" color: "#f0f0f5" font.pixelSize: 15 leftPadding: 14 echoMode: TextInput.Password focus: true background: Rectangle { radius: 8 color: fieldBg border.color: passwordField.activeFocus ? accent : "transparent" border.width: 2 } onAccepted: doLogin() } Text { visible: keyboard.capsLock anchors.horizontalCenter: parent.horizontalCenter text: "⚠ Verrouillage majuscules activé" color: "#e6c07b" font.pixelSize: 13 } Text { id: errorLabel width: parent.width horizontalAlignment: Text.AlignHCenter wrapMode: Text.WordWrap color: "#e06c75" font.pixelSize: 13 } Button { id: loginButton width: parent.width height: 44 onClicked: doLogin() contentItem: Text { text: "Se connecter" color: "#ffffff" font.pixelSize: 16 font.weight: Font.Medium horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } background: Rectangle { radius: 8 color: loginButton.down ? Qt.darker(accent, 1.25) : loginButton.hovered ? Qt.lighter(accent, 1.10) : accent } } ComboBox { id: sessionBox width: parent.width model: sessionModel currentIndex: sessionModel.lastIndex textRole: "name" font.pixelSize: 13 contentItem: Text { leftPadding: 14 text: sessionBox.displayText color: "#a0a0b8" font.pixelSize: 13 verticalAlignment: Text.AlignVCenter } background: Rectangle { radius: 8 color: "transparent" border.color: Qt.rgba(1, 1, 1, 0.15) border.width: 1 } } } } // --- Boutons d'alimentation ---------------------------------------------- // PAS de Repeater avec des fonctions dans un modèle JS : en Qt6 elles ne // survivent pas toujours à la conversion QVariant (clic silencieusement // inopérant). Deux boutons explicites via un composant inline. component PowerButton: Button { id: powerButton property string label: "" height: 36 contentItem: Text { text: powerButton.label color: powerButton.hovered ? "#f0f0f5" : "#a0a0b8" font.pixelSize: 14 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter leftPadding: 14 rightPadding: 14 } background: Rectangle { radius: 8 color: powerButton.hovered ? Qt.rgba(1, 1, 1, 0.08) : "transparent" border.color: Qt.rgba(1, 1, 1, 0.15) border.width: 1 } } Row { anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 24 spacing: 10 PowerButton { label: "Redémarrer"; onClicked: sddm.reboot() } PowerButton { label: "Éteindre"; onClicked: sddm.powerOff() } } // Nom de la machine, discret, en bas à gauche. Text { anchors.left: parent.left anchors.bottom: parent.bottom anchors.margins: 24 text: sddm.hostName color: "#5d5d78" font.pixelSize: 13 } }