diff --git a/Bin/run-qmlfmt.sh b/Bin/run-qmlfmt.sh index f9aaa46..85b8693 100755 --- a/Bin/run-qmlfmt.sh +++ b/Bin/run-qmlfmt.sh @@ -4,4 +4,4 @@ # Can be installed from AUR "qmlfmt-git" # Requires qt6-5compat -find . -name "*.qml" -exec qmlfmt -t 2 -i 2 -w {} \; \ No newline at end of file +find . -name "*.qml" -exec qmlfmt -e -b 120 -t 2 -i 2 -w {} \; \ No newline at end of file diff --git a/Modules/Background/Background.qml b/Modules/Background/Background.qml index 055cfcc..551c2d3 100644 --- a/Modules/Background/Background.qml +++ b/Modules/Background/Background.qml @@ -8,8 +8,7 @@ Variants { delegate: PanelWindow { required property ShellScreen modelData - property string wallpaperSource: Qt.resolvedUrl( - "../../Assets/Tests/wallpaper.png") + property string wallpaperSource: Qt.resolvedUrl("../../Assets/Tests/wallpaper.png") visible: wallpaperSource !== "" color: "transparent" diff --git a/Modules/Background/Overview.qml b/Modules/Background/Overview.qml index 438e612..9dc5f6f 100644 --- a/Modules/Background/Overview.qml +++ b/Modules/Background/Overview.qml @@ -9,8 +9,7 @@ Variants { delegate: PanelWindow { required property ShellScreen modelData - property string wallpaperSource: Qt.resolvedUrl( - "../../Assets/Tests/wallpaper.png") + property string wallpaperSource: Qt.resolvedUrl("../../Assets/Tests/wallpaper.png") visible: wallpaperSource !== "" color: "transparent" @@ -50,8 +49,7 @@ Variants { Rectangle { anchors.fill: parent - color: Qt.rgba(Colors.backgroundPrimary.r, Colors.backgroundPrimary.g, - Colors.backgroundPrimary.b, 0.5) + color: Qt.rgba(Colors.backgroundPrimary.r, Colors.backgroundPrimary.g, Colors.backgroundPrimary.b, 0.5) } } } diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index 9b59c1c..e803582 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -17,8 +17,7 @@ Variants { screen: modelData implicitHeight: Style.barHeight * scaling color: "transparent" - visible: Settings.data.bar.monitors.includes(modelData.name) - || (Settings.data.bar.monitors.length === 0) + visible: Settings.data.bar.monitors.includes(modelData.name) || (Settings.data.bar.monitors.length === 0) anchors { top: true diff --git a/Modules/Bar/Battery.qml b/Modules/Bar/Battery.qml index ccdea95..b278e71 100644 --- a/Modules/Bar/Battery.qml +++ b/Modules/Bar/Battery.qml @@ -6,7 +6,7 @@ import qs.Services import qs.Widgets import "../../Helpers/Duration.js" as Duration -Item { +NPill { id: root // Test mode @@ -15,9 +15,7 @@ Item { property bool testCharging: false property var battery: UPower.displayDevice - property bool isReady: testMode ? true : (battery && battery.ready - && battery.isLaptopBattery - && battery.isPresent) + property bool isReady: testMode ? true : (battery && battery.ready && battery.isLaptopBattery && battery.isPresent) property real percent: testMode ? testPercent : (isReady ? (battery.percentage * 100) : 0) property bool charging: testMode ? testCharging : (isReady ? battery.state === UPowerDeviceState.Charging : false) property bool show: isReady && percent > 0 @@ -51,54 +49,44 @@ Item { } visible: testMode || (isReady && battery.isLaptopBattery) - width: pill.width - height: pill.height - NPill { - id: pill - icon: root.batteryIcon() - text: Math.round(root.percent) + "%" - pillColor: Colors.surfaceVariant - iconCircleColor: Colors.accentPrimary - iconTextColor: Colors.backgroundPrimary - textColor: charging ? Colors.accentPrimary : Colors.textPrimary - tooltipText: { - let lines = [] - if (!root.isReady) { - return "" - } - - if (root.battery.timeToEmpty > 0) { - lines.push("Time left: " + Time.formatVagueHumanReadableTime( - root.battery.timeToEmpty)) - } - - if (root.battery.timeToFull > 0) { - lines.push("Time until full: " + Time.formatVagueHumanReadableTime( - root.battery.timeToFull)) - } - - if (root.battery.changeRate !== undefined) { - const rate = root.battery.changeRate - if (rate > 0) { - lines.push( - root.charging ? "Charging rate: " + rate.toFixed( - 2) + " W" : "Discharging rate: " + rate.toFixed( - 2) + " W") - } else if (rate < 0) { - lines.push("Discharging rate: " + Math.abs(rate).toFixed(2) + " W") - } else { - lines.push("Estimating...") - } - } else { - lines.push(root.charging ? "Charging" : "Discharging") - } - - if (root.battery.healthPercentage !== undefined - && root.battery.healthPercentage > 0) { - lines.push("Health: " + Math.round(root.battery.healthPercentage) + "%") - } - return lines.join("\n") + icon: root.batteryIcon() + text: Math.round(root.percent) + "%" + pillColor: Colors.surfaceVariant + iconCircleColor: Colors.accentPrimary + iconTextColor: Colors.backgroundPrimary + textColor: charging ? Colors.accentPrimary : Colors.textPrimary + tooltipText: { + let lines = [] + if (!root.isReady) { + return "" } + + if (root.battery.timeToEmpty > 0) { + lines.push("Time left: " + Time.formatVagueHumanReadableTime(root.battery.timeToEmpty)) + } + + if (root.battery.timeToFull > 0) { + lines.push("Time until full: " + Time.formatVagueHumanReadableTime(root.battery.timeToFull)) + } + + if (root.battery.changeRate !== undefined) { + const rate = root.battery.changeRate + if (rate > 0) { + lines.push(root.charging ? "Charging rate: " + rate.toFixed(2) + " W" : "Discharging rate: " + rate.toFixed( + 2) + " W") + } else if (rate < 0) { + lines.push("Discharging rate: " + Math.abs(rate).toFixed(2) + " W") + } else { + lines.push("Estimating...") + } + } else { + lines.push(root.charging ? "Charging" : "Discharging") + } + + if (root.battery.healthPercentage !== undefined && root.battery.healthPercentage > 0) { + lines.push("Health: " + Math.round(root.battery.healthPercentage) + "%") + } + return lines.join("\n") } } diff --git a/Modules/Bar/Workspace.qml b/Modules/Bar/Workspace.qml index 5428ba2..4c03f68 100644 --- a/Modules/Bar/Workspace.qml +++ b/Modules/Bar/Workspace.qml @@ -123,8 +123,7 @@ Item { anchors.verticalCenter: parent.verticalCenter radius: Math.round(12 * s) color: Colors.surfaceVariant - border.color: Qt.rgba(Colors.textPrimary.r, Colors.textPrimary.g, - Colors.textPrimary.b, 0.1) + border.color: Qt.rgba(Colors.textPrimary.r, Colors.textPrimary.g, Colors.textPrimary.b, 0.1) border.width: Math.max(1, Math.round(1 * s)) layer.enabled: true layer.effect: MultiEffect { @@ -252,10 +251,8 @@ Item { radius: width / 2 color: "transparent" border.color: root.effectColor - border.width: Math.max(1, Math.round( - (2 + 6 * (1.0 - root.masterProgress)) * s)) - opacity: root.effectsActive - && model.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0 + border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress)) * s)) + opacity: root.effectsActive && model.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0 visible: root.effectsActive && model.isFocused z: 1 } diff --git a/Modules/SidePanel/SidePanel.qml b/Modules/SidePanel/SidePanel.qml index 39796b7..030b47f 100644 --- a/Modules/SidePanel/SidePanel.qml +++ b/Modules/SidePanel/SidePanel.qml @@ -59,9 +59,8 @@ NLoader { // Place the panel just below the bar (overlay content starts below bar due to topMargin) y: Style.marginSmall * scaling // Center horizontally under the anchorX, clamped to the screen bounds - x: Math.max(Style.marginSmall * scaling, Math.min( - parent.width - width - Style.marginSmall * scaling, - Math.round(anchorX - width / 2))) + x: Math.max(Style.marginSmall * scaling, Math.min(parent.width - width - Style.marginSmall * scaling, + Math.round(anchorX - width / 2))) // Prevent closing when clicking in the panel bg MouseArea { diff --git a/Services/Niri.qml b/Services/Niri.qml index bb7f1c4..992991e 100644 --- a/Services/Niri.qml +++ b/Services/Niri.qml @@ -17,8 +17,7 @@ Singleton { function updateFocusedWindowTitle() { if (focusedWindowIndex >= 0 && focusedWindowIndex < windows.length) { - focusedWindowTitle = windows[focusedWindowIndex].title - || "(Unnamed window)" + focusedWindowTitle = windows[focusedWindowIndex].title || "(Unnamed window)" } else { focusedWindowTitle = "(No active window)" } @@ -113,8 +112,7 @@ Singleton { try { const focusedId = event.WindowFocusChanged.id if (focusedId) { - root.focusedWindowIndex = root.windows.findIndex( - w => w.id === focusedId) + root.focusedWindowIndex = root.windows.findIndex(w => w.id === focusedId) if (root.focusedWindowIndex < 0) { root.focusedWindowIndex = 0 } diff --git a/Services/Settings.qml b/Services/Settings.qml index 738a14f..2c034f3 100644 --- a/Services/Settings.qml +++ b/Services/Settings.qml @@ -7,13 +7,10 @@ pragma Singleton Singleton { property string shellName: "noctalia" property string settingsDir: Quickshell.env("NOCTALIA_SETTINGS_DIR") - || (Quickshell.env("XDG_CONFIG_HOME") - || Quickshell.env( + || (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env( "HOME") + "/.config") + "/" + shellName + "/" - property string settingsFile: Quickshell.env("NOCTALIA_SETTINGS_FILE") - || (settingsDir + "settings.json") - property string colorsFile: Quickshell.env("NOCTALIA_COLORS_FILE") - || (settingsDir + "colors.json") + property string settingsFile: Quickshell.env("NOCTALIA_SETTINGS_FILE") || (settingsDir + "settings.json") + property string colorsFile: Quickshell.env("NOCTALIA_COLORS_FILE") || (settingsDir + "colors.json") property var data: settingAdapter // Needed to only have one NPanel loaded at a time. diff --git a/Services/Time.qml b/Services/Time.qml index 27718ef..07650db 100644 --- a/Services/Time.qml +++ b/Services/Time.qml @@ -8,9 +8,7 @@ Singleton { id: root property var date: new Date() - property string time: Settings.data.location.use12HourClock ? Qt.formatDateTime( - date, - "h:mm AP") : Qt.formatDateTime( + property string time: Settings.data.location.use12HourClock ? Qt.formatDateTime(date, "h:mm AP") : Qt.formatDateTime( date, "HH:mm") property string dateString: { let now = date @@ -36,7 +34,8 @@ Singleton { } let month = now.toLocaleDateString(Qt.locale(), "MMMM") let year = now.toLocaleDateString(Qt.locale(), "yyyy") - return `${dayName}, ` + (Settings.data.location.reverseDayMonth ? `${month} ${day}${suffix} ${year}` : `${day}${suffix} ${month} ${year}`) + return `${dayName}, ` + + (Settings.data.location.reverseDayMonth ? `${month} ${day}${suffix} ${year}` : `${day}${suffix} ${month} ${year}`) } Timer { diff --git a/Services/Wallpapers.qml b/Services/Wallpapers.qml index 545c083..d73d5cc 100644 --- a/Services/Wallpapers.qml +++ b/Services/Wallpapers.qml @@ -26,8 +26,7 @@ Singleton { scanning = true wallpaperList = [] folderModel.folder = "" - folderModel.folder = "file://" + (Settings.data.wallpaper.directory - !== undefined ? Settings.data.wallpaper.directory : "") + folderModel.folder = "file://" + (Settings.data.wallpaper.directory !== undefined ? Settings.data.wallpaper.directory : "") } function changeWallpaper(path) { @@ -41,8 +40,7 @@ Singleton { } if (Settings.data.swww.enabled) { if (Settings.data.swww.transitionType === "random") { - transitionType = randomChoices[Math.floor(Math.random( - ) * randomChoices.length)] + transitionType = randomChoices[Math.floor(Math.random() * randomChoices.length)] } else { transitionType = Settings.data.swww.transitionType } @@ -107,8 +105,7 @@ Singleton { var files = [] var filesSwww = [] for (var i = 0; i < count; i++) { - var filepath = (Settings.data.wallpaper.folder - !== undefined ? Settings.data.wallpaper.folder : "") + "/" + get( + var filepath = (Settings.data.wallpaper.folder !== undefined ? Settings.data.wallpaper.folder : "") + "/" + get( i, "fileName") files.push(filepath) } diff --git a/Services/Workspaces.qml b/Services/Workspaces.qml index 8f3fb5f..f5de53b 100644 --- a/Services/Workspaces.qml +++ b/Services/Workspaces.qml @@ -143,9 +143,7 @@ Singleton { } } else if (isNiri) { try { - Quickshell.execDetached( - ["niri", "msg", "action", "focus-workspace", workspaceId.toString( - )]) + Quickshell.execDetached(["niri", "msg", "action", "focus-workspace", workspaceId.toString()]) } catch (e) { console.error("Error switching Niri workspace:", e) } diff --git a/Widgets/NPanel.qml b/Widgets/NPanel.qml index 7fc42ab..e995273 100644 --- a/Widgets/NPanel.qml +++ b/Widgets/NPanel.qml @@ -20,8 +20,7 @@ PanelWindow { function show() { // Ensure only one panel is visible at a time using Settings as ephemeral store try { - if (Settings.openPanel && Settings.openPanel !== outerPanel - && Settings.openPanel.hide) { + if (Settings.openPanel && Settings.openPanel !== outerPanel && Settings.openPanel.hide) { Settings.openPanel.hide() } Settings.openPanel = outerPanel diff --git a/Widgets/NPill.qml b/Widgets/NPill.qml index 20b8817..a809bfd 100644 --- a/Widgets/NPill.qml +++ b/Widgets/NPill.qml @@ -27,9 +27,7 @@ Item { readonly property int iconSize: Style.baseWidgetSize * sizeMultiplier * scaling readonly property int pillPaddingHorizontal: 14 * scaling readonly property int pillOverlap: iconSize * 0.5 - readonly property int maxPillWidth: Math.max( - 1, textItem.implicitWidth - + pillPaddingHorizontal * 2 + pillOverlap) + readonly property int maxPillWidth: Math.max(1, textItem.implicitWidth + pillPaddingHorizontal * 2 + pillOverlap) // TBC, do we use those ? signal shown diff --git a/Widgets/NSlider.qml b/Widgets/NSlider.qml index e6fe997..60a8367 100644 --- a/Widgets/NSlider.qml +++ b/Widgets/NSlider.qml @@ -52,10 +52,8 @@ Slider { height: knobDiameter + cutoutExtra radius: width / 2 color: root.cutoutColor !== undefined ? root.cutoutColor : Colors.backgroundPrimary - x: Math.max( - 0, Math.min( - parent.width - width, - root.visualPosition * (parent.width - root.knobDiameter) - cutoutExtra / 2)) + x: Math.max(0, Math.min(parent.width - width, + root.visualPosition * (parent.width - root.knobDiameter) - cutoutExtra / 2)) y: (parent.height - height) / 2 } } diff --git a/Widgets/NSystemMonitor.qml b/Widgets/NSystemMonitor.qml index 05b4083..bb28716 100644 --- a/Widgets/NSystemMonitor.qml +++ b/Widgets/NSystemMonitor.qml @@ -24,26 +24,17 @@ Item { command: ["sh", "-c", // Outputs: {"cpu":,"memper":,"cputemp":} "interval=" + intervalSeconds + "; " + "while true; do " + // First /proc/stat snapshot "read _ u1 n1 s1 id1 iw1 ir1 si1 st1 gs1 < /proc/stat; " - + "t1=$((u1+n1+s1+id1+iw1+ir1+si1+st1)); i1=$((id1+iw1)); " - + "sleep $interval; " + // Second /proc/stat snapshot - "read _ u2 n2 s2 id2 iw2 ir2 si2 st2 gs2 < /proc/stat; " - + "t2=$((u2+n2+s2+id2+iw2+ir2+si2+st2)); i2=$((id2+iw2)); " - + "dt=$((t2 - t1)); di=$((i2 - i1)); " + "cpu=$(( (100*(dt - di)) / (dt>0?dt:1) )); " - + // Memory percent via /proc/meminfo (kB) - "mt=$(awk '/MemTotal/ {print $2}' /proc/meminfo); " - + "ma=$(awk '/MemAvailable/ {print $2}' /proc/meminfo); " - + "mm=$((mt - ma)); mp=$(( (100*mm) / (mt>0?mt:1) )); " - + // Temperature: scan hwmon and thermal zones, choose max; convert m°C → °C - "ct=0; " - + "for f in /sys/class/hwmon/hwmon*/temp*_input /sys/class/thermal/thermal_zone*/temp; do " + + "t1=$((u1+n1+s1+id1+iw1+ir1+si1+st1)); i1=$((id1+iw1)); " + "sleep $interval; " + // Second /proc/stat snapshot + "read _ u2 n2 s2 id2 iw2 ir2 si2 st2 gs2 < /proc/stat; " + "t2=$((u2+n2+s2+id2+iw2+ir2+si2+st2)); i2=$((id2+iw2)); " + + "dt=$((t2 - t1)); di=$((i2 - i1)); " + "cpu=$(( (100*(dt - di)) / (dt>0?dt:1) )); " + // Memory percent via /proc/meminfo (kB) + "mt=$(awk '/MemTotal/ {print $2}' /proc/meminfo); " + "ma=$(awk '/MemAvailable/ {print $2}' /proc/meminfo); " + + "mm=$((mt - ma)); mp=$(( (100*mm) / (mt>0?mt:1) )); " + // Temperature: scan hwmon and thermal zones, choose max; convert m°C → °C + "ct=0; " + "for f in /sys/class/hwmon/hwmon*/temp*_input /sys/class/thermal/thermal_zone*/temp; do " + "[ -r \"$f\" ] || continue; v=$(cat \"$f\" 2>/dev/null); " + "[ -z \"$v\" ] && continue; " - + "if [ \"$v\" -gt 1000 ] 2>/dev/null; then v=$((v/1000)); fi; " - + "[ \"$v\" -gt \"$ct\" ] 2>/dev/null && ct=$v; " + "done; " - + // Disk usage percent for root filesystem - "dp=$(df -P / 2>/dev/null | awk 'NR==2{gsub(/%/,\"\",$5); print $5}'); " - + "[ -z \"$dp\" ] && dp=0; " + // Emit JSON line - "echo \"{\\\"cpu\\\":$cpu,\\\"memper\\\":$mp,\\\"cputemp\\\":$ct,\\\"diskper\\\":$dp}\"; " - + "done"] + + "if [ \"$v\" -gt 1000 ] 2>/dev/null; then v=$((v/1000)); fi; " + "[ \"$v\" -gt \"$ct\" ] 2>/dev/null && ct=$v; " + + "done; " + // Disk usage percent for root filesystem + "dp=$(df -P / 2>/dev/null | awk 'NR==2{gsub(/%/,\"\",$5); print $5}'); " + "[ -z \"$dp\" ] && dp=0; " + // Emit JSON line + "echo \"{\\\"cpu\\\":$cpu,\\\"memper\\\":$mp,\\\"cputemp\\\":$ct,\\\"diskper\\\":$dp}\"; " + "done"] stdout: SplitParser { onRead: function (line) { diff --git a/Widgets/NTooltip.qml b/Widgets/NTooltip.qml index 482f9e2..31ac67f 100644 --- a/Widgets/NTooltip.qml +++ b/Widgets/NTooltip.qml @@ -37,12 +37,8 @@ Window { function _showNow() { // Compute new size everytime we show the tooltip - width = Math.max( - 50 * scaling, - tooltipText.implicitWidth + Style.marginLarge * 2 * scaling) - height = Math.max( - 50 * scaling, - tooltipText.implicitHeight + Style.marginSmall * 2 * scaling) + width = Math.max(50 * scaling, tooltipText.implicitWidth + Style.marginLarge * 2 * scaling) + height = Math.max(50 * scaling, tooltipText.implicitHeight + Style.marginSmall * 2 * scaling) if (!target) { return