aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--theme/Main.qml18
-rw-r--r--theme/components/Backdrop.qml8
-rw-r--r--theme/components/Credentials.qml7
-rw-r--r--theme/components/Panel.qml2
-rw-r--r--theme/components/PowerBar.qml2
-rw-r--r--theme/theme.conf6
7 files changed, 29 insertions, 20 deletions
diff --git a/README.md b/README.md
index 8316215..24c52c9 100644
--- a/README.md
+++ b/README.md
@@ -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