small code cleanup and added components/ folder for reusable code
This commit is contained in:
@@ -22,7 +22,7 @@ Rectangle {
|
|||||||
readonly property var bat: UPower.displayDevice
|
readonly property var bat: UPower.displayDevice
|
||||||
readonly property bool batReady: bat && bat.ready && bat.isLaptopBattery
|
readonly property bool batReady: bat && bat.ready && bat.isLaptopBattery
|
||||||
|
|
||||||
readonly property bool moduleEnabled: batready
|
readonly property bool moduleEnabled: batReady
|
||||||
|
|
||||||
readonly property real pct: batReady ? bat.percentage * 100 : 72
|
readonly property real pct: batReady ? bat.percentage * 100 : 72
|
||||||
readonly property int state: batReady ? bat.state : UPowerDeviceState.Unknown
|
readonly property int state: batReady ? bat.state : UPowerDeviceState.Unknown
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import QtQuick
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Io
|
|
||||||
|
|
||||||
import "../../config" as Cfg
|
import "../../config" as Cfg
|
||||||
|
import "../../components"
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
@@ -18,44 +18,8 @@ Rectangle {
|
|||||||
property int barMargin: Cfg.Config.margin
|
property int barMargin: Cfg.Config.margin
|
||||||
|
|
||||||
readonly property var t: Cfg.Config.theme
|
readonly property var t: Cfg.Config.theme
|
||||||
readonly property string tz: Cfg.Config.timezone || ""
|
|
||||||
|
|
||||||
|
TimezoneProvider { id: timezone }
|
||||||
property int tzOffsetMin: 0
|
|
||||||
|
|
||||||
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
|
|
||||||
+ tzOffsetMin * 60000)
|
|
||||||
}
|
|
||||||
|
|
||||||
function tzOffsetHours() {
|
|
||||||
if (!tz) return -timeManager.now.getTimezoneOffset() / 60
|
|
||||||
return tzOffsetMin / 60
|
|
||||||
}
|
|
||||||
|
|
||||||
width: clockLayout.implicitWidth + 24
|
width: clockLayout.implicitWidth + 24
|
||||||
height: Cfg.Config.moduleHeight
|
height: Cfg.Config.moduleHeight
|
||||||
@@ -103,7 +67,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: root.toTz(timeManager.now).toLocaleTimeString(Qt.locale(), "HH:mm")
|
text: timezone.toTz(timeManager.now).toLocaleTimeString(Qt.locale(), "HH:mm")
|
||||||
color: root.t.clockTime
|
color: root.t.clockTime
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
font.bold: true
|
font.bold: true
|
||||||
@@ -112,7 +76,7 @@ Rectangle {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: secondsText
|
id: secondsText
|
||||||
text: ":" + root.toTz(timeManager.now).toLocaleTimeString(Qt.locale(), "ss")
|
text: ":" + timezone.toTz(timeManager.now).toLocaleTimeString(Qt.locale(), "ss")
|
||||||
color: root.t.clockSeconds
|
color: root.t.clockSeconds
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
font.bold: true
|
font.bold: true
|
||||||
@@ -267,7 +231,7 @@ Rectangle {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: root.toTz(timeManager.now).toLocaleDateString(Qt.locale(), "dddd")
|
text: timezone.toTz(timeManager.now).toLocaleDateString(Qt.locale(), "dddd")
|
||||||
color: root.t.clockPopupDim
|
color: root.t.clockPopupDim
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.capitalization: Font.AllUppercase
|
font.capitalization: Font.AllUppercase
|
||||||
@@ -276,7 +240,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: root.toTz(timeManager.now).toLocaleDateString(Qt.locale(), "d MMMM yyyy")
|
text: timezone.toTz(timeManager.now).toLocaleDateString(Qt.locale(), "d MMMM yyyy")
|
||||||
color: root.t.clockPopupHeader
|
color: root.t.clockPopupHeader
|
||||||
font.pixelSize: 22
|
font.pixelSize: 22
|
||||||
font.bold: true
|
font.bold: true
|
||||||
@@ -306,8 +270,8 @@ Rectangle {
|
|||||||
id: cal
|
id: cal
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: gridCol.implicitHeight
|
implicitHeight: gridCol.implicitHeight
|
||||||
property int displayYear: root.toTz(timeManager.now).getFullYear()
|
property int displayYear: timezone.toTz(timeManager.now).getFullYear()
|
||||||
property int displayMonth: root.toTz(timeManager.now).getMonth()
|
property int displayMonth: timezone.toTz(timeManager.now).getMonth()
|
||||||
property int pendingYear: displayYear
|
property int pendingYear: displayYear
|
||||||
property int pendingMonth: displayMonth
|
property int pendingMonth: displayMonth
|
||||||
property int slideDir: 1
|
property int slideDir: 1
|
||||||
@@ -316,7 +280,7 @@ Rectangle {
|
|||||||
target: calendarPopup
|
target: calendarPopup
|
||||||
function onPopupOpenChanged() {
|
function onPopupOpenChanged() {
|
||||||
if (calendarPopup.popupOpen) {
|
if (calendarPopup.popupOpen) {
|
||||||
let tzd = root.toTz(timeManager.now)
|
let tzd = timezone.toTz(timeManager.now)
|
||||||
cal.displayYear = tzd.getFullYear()
|
cal.displayYear = tzd.getFullYear()
|
||||||
cal.displayMonth = tzd.getMonth()
|
cal.displayMonth = tzd.getMonth()
|
||||||
}
|
}
|
||||||
@@ -378,7 +342,7 @@ Rectangle {
|
|||||||
readonly property int dayNum: (weekRow.weekIndex * 7 + index) - ((new Date(cal.displayYear, cal.displayMonth, 1).getDay() + 6) % 7) + 1
|
readonly property int dayNum: (weekRow.weekIndex * 7 + index) - ((new Date(cal.displayYear, cal.displayMonth, 1).getDay() + 6) % 7) + 1
|
||||||
readonly property bool inMonth: dayNum >= 1 && dayNum <= new Date(cal.displayYear, cal.displayMonth + 1, 0).getDate()
|
readonly property bool inMonth: dayNum >= 1 && dayNum <= new Date(cal.displayYear, cal.displayMonth + 1, 0).getDate()
|
||||||
readonly property bool isToday: {
|
readonly property bool isToday: {
|
||||||
let tzd = root.toTz(timeManager.now)
|
let tzd = timezone.toTz(timeManager.now)
|
||||||
return inMonth && dayNum === tzd.getDate()
|
return inMonth && dayNum === tzd.getDate()
|
||||||
&& cal.displayYear === tzd.getFullYear()
|
&& cal.displayYear === tzd.getFullYear()
|
||||||
&& cal.displayMonth === tzd.getMonth()
|
&& cal.displayMonth === tzd.getMonth()
|
||||||
@@ -414,7 +378,7 @@ Rectangle {
|
|||||||
Layout.rightMargin: 6
|
Layout.rightMargin: 6
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "UTC " + (root.tzOffsetHours() >= 0 ? "+" : "") + root.tzOffsetHours()
|
text: "UTC " + (timezone.tzOffsetHours() >= 0 ? "+" : "") + timezone.tzOffsetHours()
|
||||||
color: root.t.clockPopupUtc
|
color: root.t.clockPopupUtc
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
font.bold: true
|
font.bold: true
|
||||||
@@ -425,7 +389,7 @@ Rectangle {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: {
|
text: {
|
||||||
let d = root.toTz(timeManager.now)
|
let d = timezone.toTz(timeManager.now)
|
||||||
let month = d.getMonth() + 1
|
let month = d.getMonth() + 1
|
||||||
let day = d.getDate()
|
let day = d.getDate()
|
||||||
let year = d.getFullYear()
|
let year = d.getFullYear()
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ Item {
|
|||||||
|
|
||||||
property bool expanded: false
|
property bool expanded: false
|
||||||
property bool manuallyExpanded: false
|
property bool manuallyExpanded: false
|
||||||
property var menuWindow: null
|
|
||||||
|
|
||||||
readonly property bool effectiveExpanded: expanded || trayMenuPopup.popupOpen
|
readonly property bool effectiveExpanded: expanded || trayMenuPopup.popupOpen
|
||||||
|
|
||||||
|
|||||||
48
components/TimezoneProvider.qml
Normal file
48
components/TimezoneProvider.qml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import "../config" as Cfg
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property string tz: Cfg.Config.timezone || ""
|
||||||
|
property int tzOffsetMin: 0
|
||||||
|
property bool ready: false
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: tzProc
|
||||||
|
command: ["/usr/bin/env", "TZ=" + root.tz, "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)
|
||||||
|
root.ready = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 1800000
|
||||||
|
running: root.tz !== ""
|
||||||
|
repeat: true
|
||||||
|
onTriggered: tzProc.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function toTz(date) {
|
||||||
|
if (!root.tz) return date
|
||||||
|
return new Date(date.getTime()
|
||||||
|
+ date.getTimezoneOffset() * 60000
|
||||||
|
+ root.tzOffsetMin * 60000)
|
||||||
|
}
|
||||||
|
|
||||||
|
function tzOffsetHours() {
|
||||||
|
if (!root.tz) return -(new Date().getTimezoneOffset()) / 60
|
||||||
|
return root.tzOffsetMin / 60
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@ QtObject {
|
|||||||
// ── Clock Module ─────────────────────────────────────────────────────────
|
// ── Clock Module ─────────────────────────────────────────────────────────
|
||||||
property bool clockExtendEnabled: true // seconds extension on hover for clock
|
property bool clockExtendEnabled: true // seconds extension on hover for clock
|
||||||
|
|
||||||
// ── Timezone (IANA name, e.g. "America/New_York", "Europe/London")g ──────────
|
// ── Timezone (IANA name, e.g. "America/New_York", "Europe/London") ──────────
|
||||||
// Leave empty to use the system timezone.
|
// Leave empty to use the system timezone.
|
||||||
property string timezone: "America/New_York"
|
property string timezone: "America/New_York"
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ QtObject {
|
|||||||
property int volumeSliderHeight: 2
|
property int volumeSliderHeight: 2
|
||||||
property int volumeHandleSize: 20
|
property int volumeHandleSize: 20
|
||||||
property int volumePopupWidth: 280
|
property int volumePopupWidth: 280
|
||||||
property int volumeOutputMax: 170
|
property int volumeOutputMax: 100
|
||||||
property int volumeInputMax: 200
|
property int volumeInputMax: 200
|
||||||
|
|
||||||
|
|
||||||
@@ -105,6 +105,7 @@ QtObject {
|
|||||||
// ────────────────────────────────────────────────────────────────────────
|
// ────────────────────────────────────────────────────────────────────────
|
||||||
property string launcherScript: Quickshell.env("HOME") + "/.config/quickshell/launcher/launcher.sh"
|
property string launcherScript: Quickshell.env("HOME") + "/.config/quickshell/launcher/launcher.sh"
|
||||||
property string launcherCacheDir: "/tmp/qs_launcher"
|
property string launcherCacheDir: "/tmp/qs_launcher"
|
||||||
|
property bool launcherCloseOnClickOutside: true
|
||||||
property bool launcherSelectFirst: false
|
property bool launcherSelectFirst: false
|
||||||
property bool launcherMipmapIcons: false
|
property bool launcherMipmapIcons: false
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ PanelWindow {
|
|||||||
property bool _keyboardNav: false
|
property bool _keyboardNav: false
|
||||||
property var allItems: []
|
property var allItems: []
|
||||||
property bool loading: false
|
property bool loading: false
|
||||||
|
property int lastCacheUpdate: 0
|
||||||
|
|
||||||
|
|
||||||
readonly property int defaultIndex: Cfg.Config.launcherSelectFirst ? 0 : -1
|
readonly property int defaultIndex: Cfg.Config.launcherSelectFirst ? 0 : -1
|
||||||
@@ -67,7 +68,14 @@ PanelWindow {
|
|||||||
|
|
||||||
function loadItems() {
|
function loadItems() {
|
||||||
loading = true
|
loading = true
|
||||||
|
var now = Date.now()
|
||||||
|
var staleMs = 300000
|
||||||
|
if (now - lastCacheUpdate < staleMs) {
|
||||||
readCache()
|
readCache()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
readCache()
|
||||||
|
lastCacheUpdate = now
|
||||||
updateProc.command = [Cfg.Config.launcherScript, "--update-only"]
|
updateProc.command = [Cfg.Config.launcherScript, "--update-only"]
|
||||||
updateProc.running = true
|
updateProc.running = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,6 @@ ShellRoot {
|
|||||||
source: Qt.resolvedUrl("polkit/Polkit.qml")
|
source: Qt.resolvedUrl("polkit/Polkit.qml")
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: polkitComp
|
|
||||||
Polkit {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Spacing Gap: Top / Bottom ────────────────────────────────────────
|
// ── Spacing Gap: Top / Bottom ────────────────────────────────────────
|
||||||
Variants {
|
Variants {
|
||||||
model: Quickshell.screens
|
model: Quickshell.screens
|
||||||
@@ -101,6 +96,7 @@ ShellRoot {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: {
|
source: {
|
||||||
var p = Cfg.Config.theme.wallpaper
|
var p = Cfg.Config.theme.wallpaper
|
||||||
|
if (!p) return ""
|
||||||
return p.startsWith("file://") ? p : "file://" + p
|
return p.startsWith("file://") ? p : "file://" + p
|
||||||
}
|
}
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Io
|
|
||||||
import "../../config" as Cfg
|
import "../../config" as Cfg
|
||||||
|
import "../../components"
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: root
|
id: root
|
||||||
@@ -17,46 +17,12 @@ PanelWindow {
|
|||||||
WlrLayershell.exclusiveZone: -1
|
WlrLayershell.exclusiveZone: -1
|
||||||
mask: Region {}
|
mask: Region {}
|
||||||
|
|
||||||
readonly property string tz: Cfg.Config.timezone || ""
|
TimezoneProvider { id: timezone }
|
||||||
|
|
||||||
property int tzOffsetMin: 0
|
|
||||||
|
|
||||||
property string fullDateString: ""
|
property string fullDateString: ""
|
||||||
property int typedChars: 0
|
property int typedChars: 0
|
||||||
property string secondsString: ""
|
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() {
|
function startTyping() {
|
||||||
typedChars = 0
|
typedChars = 0
|
||||||
secondsText.opacity = 0
|
secondsText.opacity = 0
|
||||||
@@ -65,14 +31,14 @@ PanelWindow {
|
|||||||
|
|
||||||
function updateDate(d) {
|
function updateDate(d) {
|
||||||
let now = d || new Date()
|
let now = d || new Date()
|
||||||
fullDateString = toTz(now).toLocaleDateString(Qt.locale(),
|
fullDateString = timezone.toTz(now).toLocaleDateString(Qt.locale(),
|
||||||
Cfg.Config.dateFormat === "DMY" ? "dddd, d MMMM yyyy" : "dddd, MMMM d, yyyy")
|
Cfg.Config.dateFormat === "DMY" ? "dddd, d MMMM yyyy" : "dddd, MMMM d, yyyy")
|
||||||
startTyping()
|
startTyping()
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
let d = new Date()
|
let d = new Date()
|
||||||
secondsString = Qt.formatTime(toTz(d), "hh:mm:ss")
|
secondsString = Qt.formatTime(timezone.toTz(d), "hh:mm:ss")
|
||||||
updateDate(d)
|
updateDate(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +106,7 @@ PanelWindow {
|
|||||||
repeat: true
|
repeat: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
let d = new Date()
|
let d = new Date()
|
||||||
let tzd = toTz(d)
|
let tzd = timezone.toTz(d)
|
||||||
secondsString = Qt.formatTime(tzd, "hh:mm:ss")
|
secondsString = Qt.formatTime(tzd, "hh:mm:ss")
|
||||||
if (tzd.getHours() === 0 && tzd.getMinutes() === 0 && tzd.getSeconds() === 0)
|
if (tzd.getHours() === 0 && tzd.getMinutes() === 0 && tzd.getSeconds() === 0)
|
||||||
updateDate(d)
|
updateDate(d)
|
||||||
|
|||||||
Reference in New Issue
Block a user