diff --git a/configs/releng/airootfs/usr/share/sddm/themes/fws/Main.qml b/configs/releng/airootfs/usr/share/sddm/themes/fws/Main.qml new file mode 100644 index 0000000..14cff6c --- /dev/null +++ b/configs/releng/airootfs/usr/share/sddm/themes/fws/Main.qml @@ -0,0 +1,249 @@ +// 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 + } +} diff --git a/configs/releng/airootfs/usr/share/sddm/themes/fws/metadata.desktop b/configs/releng/airootfs/usr/share/sddm/themes/fws/metadata.desktop new file mode 100644 index 0000000..0b43f10 --- /dev/null +++ b/configs/releng/airootfs/usr/share/sddm/themes/fws/metadata.desktop @@ -0,0 +1,17 @@ +[SddmGreeterTheme] +Name=FWS +Description=Écran de connexion FWS +Author=FWS +Copyright=FWS +License=GPL-2.0-or-later +Type=sddm-theme +Version=1.0 +Website= +Screenshot= +MainScript=Main.qml +ConfigFile=theme.conf +TranslationsDirectory= +Email= +Theme-Id=fws +Theme-API=2.0 +QtVersion=6 diff --git a/configs/releng/airootfs/usr/share/sddm/themes/fws/theme.conf b/configs/releng/airootfs/usr/share/sddm/themes/fws/theme.conf new file mode 100644 index 0000000..1b647d9 --- /dev/null +++ b/configs/releng/airootfs/usr/share/sddm/themes/fws/theme.conf @@ -0,0 +1,7 @@ +# Thème SDDM « fws » — valeurs par défaut, surchargées par theme.conf.user +# (écrit par le %post du kickstart : accent différent selon le bureau choisi). +[General] +accent=#3daee9 +colorTop=#1a1a2e +colorBottom=#16213e +greeting=Bienvenue sur FWS