import QtQuick import Quickshell import Quickshell.Wayland import Quickshell.Io import "../../config" as Cfg PanelWindow { id: root required property var modelData screen: modelData color: "transparent" anchors { top: true; bottom: true; left: true; right: true } WlrLayershell.layer: WlrLayer.Background WlrLayershell.exclusiveZone: -1 mask: Region {} readonly property string tz: Cfg.Config.timezone || "" property int tzOffsetMin: 0 property string fullDateString: "" property int typedChars: 0 property string secondsString: "" onTzOffsetMinChanged: { updateDate(new Date()) } Process { id: tzProc command: ["bash", "-c", "TZ=" + (root.tz || "UTC") + " date +%z"] running: root.tz !== "" stdout: SplitParser { onRead: data => { var s = data.trim() if (s.length < 5) return var sign = (s[0] === "-") ? -1 : 1 var h = parseInt(s.substring(1, 3), 10) var m = parseInt(s.substring(3, 5), 10) root.tzOffsetMin = sign * (h * 60 + m) } } } Timer { interval: 1800000; running: root.tz !== ""; repeat: true onTriggered: tzProc.running = true } function toTz(date) { if (!tz) return date return new Date(date.getTime() + date.getTimezoneOffset() * 60000 + root.tzOffsetMin * 60000) } function startTyping() { typedChars = 0 secondsText.opacity = 0 typingTimer.start() } function updateDate(d) { let now = d || new Date() fullDateString = toTz(now).toLocaleDateString(Qt.locale(), Cfg.Config.dateFormat === "DMY" ? "dddd, d MMMM yyyy" : "dddd, MMMM d, yyyy") startTyping() } Component.onCompleted: { let d = new Date() secondsString = Qt.formatTime(toTz(d), "hh:mm:ss") updateDate(d) } Column { anchors.centerIn: parent spacing: 10 Text { id: dateText anchors.horizontalCenter: parent.horizontalCenter color: Cfg.Config.theme.bgDateText styleColor: Cfg.Config.theme.bgDateShadow font.pixelSize: 64 font.weight: Font.ExtraLight font.letterSpacing: 4 opacity: 0.55 style: Text.Raised renderType: Text.NativeRendering layer.enabled: true layer.smooth: true text: fullDateString.substring(0, typedChars) } Text { id: secondsText anchors.horizontalCenter: parent.horizontalCenter color: Cfg.Config.theme.bgDateSecondsText styleColor: Cfg.Config.theme.bgDateShadow font.pixelSize: 22 font.weight: Font.ExtraLight font.letterSpacing: 6 opacity: 0 style: Text.Raised renderType: Text.NativeRendering layer.enabled: true layer.smooth: true text: secondsString Behavior on opacity { NumberAnimation { duration: 700 easing.type: Easing.InOutQuad } } } } Timer { id: typingTimer interval: 55 repeat: true onTriggered: { if (typedChars < fullDateString.length) { typedChars++ } else { stop() secondsText.opacity = 0.55 } } } Timer { interval: 1000 running: true repeat: true onTriggered: { let d = new Date() let tzd = toTz(d) secondsString = Qt.formatTime(tzd, "hh:mm:ss") if (tzd.getHours() === 0 && tzd.getMinutes() === 0 && tzd.getSeconds() === 0) updateDate(d) } } }