diff options
Diffstat (limited to 'theme')
| -rw-r--r-- | theme/Main.qml | 126 | ||||
| -rw-r--r-- | theme/metadata.desktop | 12 | ||||
| -rw-r--r-- | theme/theme.conf | 33 |
3 files changed, 171 insertions, 0 deletions
diff --git a/theme/Main.qml b/theme/Main.qml new file mode 100644 index 0000000..f1b91ee --- /dev/null +++ b/theme/Main.qml @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2026 Danilo M. <danix@danix.xyz> +// +// UDT SDDM greeter. The root item spans every screen. The wallpaper is drawn +// once per screen; the login card is pinned to one screen (config uiScreen, +// else the primary screen); input wakes the card after it fades. + +import QtQuick + +Item { + id: root + + // SDDM sizes the greeter to the union of every screen. + readonly property var union: screenModel.geometry(-1) + width: union.width + height: union.height + + // Palette. Values come from theme.conf, overridden live by theme.conf.user. + readonly property string baseColor: config.stringValue("base") + readonly property int cardRadius: 10 + readonly property string wallpaperUrl: + config.stringValue("background") === "" + ? "" + : "file://" + config.stringValue("background") + + readonly property string wantedScreen: config.stringValue("uiScreen") + property var primaryGeometry: screenModel.geometry(screenModel.primary >= 0 ? screenModel.primary : 0) + property var namedGeometry: primaryGeometry + readonly property var cardGeometry: wantedScreen === "" ? primaryGeometry : namedGeometry + + // The Image delegate of the screen the card sits on. The frosted card + // samples it. Null until the model has populated. + property Item cardScreenImage: null + + Repeater { + id: screens + model: screenModel + delegate: Item { + x: geometry.x + y: geometry.y + width: geometry.width + height: geometry.height + + Image { + id: screenImage + anchors.fill: parent + source: root.wallpaperUrl + fillMode: Image.PreserveAspectCrop + sourceSize.width: parent.width + sourceSize.height: parent.height + smooth: true + asynchronous: true + } + + // Scrim so the card and text read on any wallpaper. + Rectangle { + anchors.fill: parent + color: root.baseColor + opacity: 0.45 + } + + readonly property string screenName: name + + Component.onCompleted: root.registerScreen(index, screenName, screenImage, geometry) + } + } + + // Filled as the model populates: the primary screen's name, and the + // wallpaper image plus geometry of whichever screen owns the card. + property string primaryName: "" + + function registerScreen(index, screenName, image, geom) { + if (index === screenModel.primary) + root.primaryName = screenName + if (screenName === root.cardScreenName()) { + root.cardScreenImage = image + root.namedGeometry = geom + } + } + + function cardScreenName() { + return root.wantedScreen !== "" ? root.wantedScreen : root.primaryName + } + + // Idle: fade the card after fadeoutMs, restore on any input. + property bool uiVisible: true + + Timer { + id: idle + interval: config.intValue("fadeoutMs") > 0 ? config.intValue("fadeoutMs") : 60000 + running: root.uiVisible + repeat: false + onTriggered: root.uiVisible = false + } + + function wake() { + root.uiVisible = true + idle.restart() + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onPressed: root.wake() + onPositionChanged: root.wake() + } + + Keys.onPressed: event => { + root.wake() + event.accepted = false + } + + // Placeholder card. Task 2 replaces this with components/LoginCard.qml. + Rectangle { + id: card + x: root.cardGeometry.x + (root.cardGeometry.width - width) / 2 + y: root.cardGeometry.y + (root.cardGeometry.height - height) / 2 + width: 380 + height: 220 + radius: root.cardRadius + color: config.stringValue("mantle") + opacity: root.uiVisible ? 0.9 : 0 + visible: opacity > 0 + Behavior on opacity { NumberAnimation { duration: 260; easing.type: Easing.OutCubic } } + } +} diff --git a/theme/metadata.desktop b/theme/metadata.desktop new file mode 100644 index 0000000..e345597 --- /dev/null +++ b/theme/metadata.desktop @@ -0,0 +1,12 @@ +[SddmGreeterTheme] +Name=UDT +Description=Unified Desktop Theme login screen +Author=Danilo M. +Copyright=(c) 2026 Danilo M. +License=GPL-2.0-only +Type=sddm-theme +Version=0.1 +MainScript=Main.qml +ConfigFile=theme.conf +Theme-API=2.0 +QtVersion=6 diff --git a/theme/theme.conf b/theme/theme.conf new file mode 100644 index 0000000..c2b8269 --- /dev/null +++ b/theme/theme.conf @@ -0,0 +1,33 @@ +# Static defaults and fallbacks. udt-accent writes the live values into +# theme.conf.user, which SDDM merges over this file. Every key here is the +# Catppuccin Macchiato value of the matching UDT role, so the theme parses and +# renders before a wallpaper has ever been set. +[General] +type=image +background= + +base=#24273a +mantle=#1e2030 +crust=#181926 +surface0=#363a4f +surface1=#494d64 +surface2=#5b6078 +text=#cad3f5 +subtext0=#a5adcb +subtext1=#b8c0e0 +overlay0=#6e738d +overlay1=#8087a2 +overlay2=#939ab7 +red=#ed8796 +yellow=#eed49f +green=#a6da95 +teal=#8bd5ca +blue=#8aadf4 +lavender=#b7bdf8 +accent=#b7bdf8 + +# Empty uiScreen pins the card to the primary screen. +uiScreen= +# 60000 matches the stock theme's idle timeout. +fadeoutMs=60000 +blur=true |
