diff options
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | theme/Main.qml | 18 | ||||
| -rw-r--r-- | theme/components/Backdrop.qml | 8 | ||||
| -rw-r--r-- | theme/components/Credentials.qml | 7 | ||||
| -rw-r--r-- | theme/components/Panel.qml | 2 | ||||
| -rw-r--r-- | theme/components/PowerBar.qml | 2 | ||||
| -rw-r--r-- | theme/theme.conf | 6 |
7 files changed, 29 insertions, 20 deletions
@@ -12,7 +12,7 @@ its colours from the UDT palette, including the wallpaper-snapped accent. SDDM merges into the theme config at every greeter start. Wallpaper and accent need no root re-run; only theme code changes do. -Set `uiScreen` in the root-owned `theme/theme.conf` to pin the login card to a +Set `uiScreen` in the root-owned `theme/theme.conf` to pin the login panel to a named screen; leave it empty for the primary screen. It does not belong in the generated `theme.conf.user`, which is overwritten on every wallpaper change. @@ -24,6 +24,10 @@ From top to bottom it shows the clock (`timeFormat`) and date (`dateFormat`), the `greeting`, the avatar, one credential slot, the power row, and the session selector at the bottom. +If you override `dateFormat`, quote any value containing a comma (for example +`dateFormat="dddd, d MMMM"`): SDDM reads the config through QSettings, which +treats an unquoted comma as a list, and the date then comes out empty. + The credential slot is staged: type the username, confirm, and it slides out to reveal the password; confirm again to log in. Esc or the back chevron returns to the username. diff --git a/theme/Main.qml b/theme/Main.qml index a5acac9..0a7ce3d 100644 --- a/theme/Main.qml +++ b/theme/Main.qml @@ -3,8 +3,8 @@ // // UDT SDDM greeter. SDDM creates one window per screen, each sized to its own // screen and carrying a one-row ScreenModel, so this root item is exactly one -// screen. The wallpaper fills it; the login card draws only on the screen -// named by config uiScreen, else on the primary screen. Input wakes the card +// screen. The wallpaper fills it; the login panel draws only on the screen +// named by config uiScreen, else on the primary screen. Input wakes the panel // after it fades. import QtQuick @@ -27,7 +27,7 @@ Item { ? "" : "file://" + config.stringValue("background") - // The screen the card belongs on: config uiScreen if non-empty, else the + // The screen the panel belongs on: config uiScreen if non-empty, else the // primary screen. `primaryScreen` is a per-window context property SDDM // sets true only on the window showing the primary screen. readonly property string wantedScreen: config.stringValue("uiScreen") @@ -36,7 +36,7 @@ Item { ? primaryScreen : (thisScreenName === wantedScreen) - // The wallpaper fills this window's single screen. The frosted card + // The wallpaper fills this window's single screen. The frosted panel // samples this image. Image { id: wallpaperImage @@ -49,7 +49,7 @@ Item { asynchronous: true } - // Scrim so the card and text read on any wallpaper. + // Scrim so the panel and text read on any wallpaper. Rectangle { anchors.fill: parent color: root.baseColor @@ -65,11 +65,11 @@ Item { } } - // Idle: fade the card after fadeoutMs, restore on any input. + // Idle: fade the panel after fadeoutMs, restore on any input. property bool uiVisible: true - // While faded the card is disabled, which clears its focus; take focus on - // the root so the first key press wakes the card instead of vanishing. + // While faded the panel is disabled, which clears its focus; take focus on + // the root so the first key press wakes the panel instead of vanishing. onUiVisibleChanged: { if (!uiVisible) root.forceActiveFocus() @@ -107,7 +107,7 @@ Item { // key is missing or malformed. readonly property real panelWidth: { var v = parseFloat(config.stringValue("panelWidth")) - return v > 0 ? v : 0.30 + return v > 0 ? Math.min(v, 1) : 0.30 } Panel { diff --git a/theme/components/Backdrop.qml b/theme/components/Backdrop.qml index c13b766..de39bc2 100644 --- a/theme/components/Backdrop.qml +++ b/theme/components/Backdrop.qml @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only // Copyright (C) 2026 Danilo M. <danix@danix.xyz> // -// A frosted panel. It snapshots the wallpaper image the card sits on, blurs it -// and masks it to the card's rounded rect, then tints it for text contrast. -// When there is no source, only the tint draws, so the card still reads. +// A frosted panel. It snapshots the wallpaper image the panel sits on, blurs it +// and masks it to the panel's rounded rect, then tints it for text contrast. +// When there is no source, only the tint draws, so the panel still reads. import QtQuick import QtQuick.Effects @@ -25,7 +25,7 @@ Item { if (backdrop.sourceItem === null) return Qt.rect(0, 0, 0, 0) // Guard reads: mapToItem() hides its reads in C++, so the binding - // would not otherwise re-run when the card or image moves (e.g. + // would not otherwise re-run when the panel or image moves (e.g. // the failed-login shake). Reading the coordinates registers them. var _guard = backdrop.x + backdrop.y + backdrop.parent.x + backdrop.parent.y + backdrop.sourceItem.x + backdrop.sourceItem.y diff --git a/theme/components/Credentials.qml b/theme/components/Credentials.qml index c2aba29..2bfbaf5 100644 --- a/theme/components/Credentials.qml +++ b/theme/components/Credentials.qml @@ -56,6 +56,7 @@ Item { height: 44 clip: true visible: width > 0 + Behavior on width { NumberAnimation { duration: 220; easing.type: Easing.OutCubic } } Rectangle { anchors.fill: parent @@ -122,6 +123,7 @@ Item { height: slot.height text: userModel.lastUser !== undefined ? userModel.lastUser : "" placeholderText: "Username" + activeFocusOnTab: !creds.passwordStage font.family: "Noto Sans" color: config.stringValue("text") palette.base: config.stringValue("surface0") @@ -135,7 +137,7 @@ Item { x: creds.passwordStage ? -slot.width : 0 opacity: creds.passwordStage ? 0 : 1 Behavior on x { NumberAnimation { duration: 220; easing.type: Easing.OutCubic } } - Behavior on opacity { NumberAnimation { duration: 220 } } + Behavior on opacity { NumberAnimation { duration: 220; easing.type: Easing.OutCubic } } onAccepted: creds.confirm() onTextChanged: creds.wake() Keys.onPressed: event => { @@ -150,6 +152,7 @@ Item { height: slot.height echoMode: TextInput.Password placeholderText: "Password" + activeFocusOnTab: creds.passwordStage font.family: "Noto Sans" color: config.stringValue("text") palette.base: config.stringValue("surface0") @@ -163,7 +166,7 @@ Item { x: creds.passwordStage ? 0 : slot.width opacity: creds.passwordStage ? 1 : 0 Behavior on x { NumberAnimation { duration: 220; easing.type: Easing.OutCubic } } - Behavior on opacity { NumberAnimation { duration: 220 } } + Behavior on opacity { NumberAnimation { duration: 220; easing.type: Easing.OutCubic } } onAccepted: creds.confirm() Keys.onPressed: event => { creds.wake() diff --git a/theme/components/Panel.qml b/theme/components/Panel.qml index 4df989b..eac2c58 100644 --- a/theme/components/Panel.qml +++ b/theme/components/Panel.qml @@ -36,7 +36,7 @@ Item { property date now: new Date() Timer { interval: 1000 - running: true + running: panel.visible repeat: true onTriggered: panel.now = new Date() } diff --git a/theme/components/PowerBar.qml b/theme/components/PowerBar.qml index 1ce3e76..3d6b2c5 100644 --- a/theme/components/PowerBar.qml +++ b/theme/components/PowerBar.qml @@ -49,7 +49,7 @@ Row { source: modelData.icon !== "" ? modelData.icon : modelData.fallback visible: false onStatusChanged: { - if (status === Image.Error && source !== modelData.fallback) + if (status === Image.Error && String(source) !== modelData.fallback) source = modelData.fallback } } diff --git a/theme/theme.conf b/theme/theme.conf index 2db45a1..33e6bd3 100644 --- a/theme/theme.conf +++ b/theme/theme.conf @@ -26,7 +26,7 @@ blue=#8aadf4 lavender=#b7bdf8 accent=#b7bdf8 -# Empty uiScreen pins the card to the primary screen. Set a screen name here, +# Empty uiScreen pins the panel to the primary screen. Set a screen name here, # in this root-owned file: theme.conf.user is regenerated on every wallpaper # change and is not the place for uiScreen. uiScreen= @@ -41,7 +41,9 @@ panelWidth=0.30 # Clock and greeting. Qt date/time format strings. The date follows the # greeter's locale, which may be C. timeFormat=HH:mm -dateFormat=dddd, d MMMM +# Quote any format containing a comma, here and in theme.conf.user: QSettings +# reads an unquoted comma as a list, and SDDM's stringValue() then returns "". +dateFormat="dddd, d MMMM" greeting=hello there # Power button icons. udt-accent writes absolute paths here from the icon theme |
