From 37777035016a90eccefd0cf00b276b8b89714b02 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Wed, 30 Jul 2025 13:59:08 +0200 Subject: [PATCH] Fix lockscreen temperature, System Panel, small change in shell.qml --- Widgets/LockScreen.qml | 71 +++++++++++++------------------- Widgets/Sidebar/Panel/System.qml | 40 +++++++++++++----- shell.qml | 34 ++++++++++++++- 3 files changed, 90 insertions(+), 55 deletions(-) diff --git a/Widgets/LockScreen.qml b/Widgets/LockScreen.qml index 29f20fc..fd99d10 100644 --- a/Widgets/LockScreen.qml +++ b/Widgets/LockScreen.qml @@ -27,12 +27,10 @@ WlSessionLock { property double currentTemp: 0 locked: false - // On component completed, fetch weather data Component.onCompleted: { fetchWeatherData(); } - // Weather fetching function function fetchWeatherData() { WeatherHelper.fetchCityWeather(weatherCity, function (result) { weatherData = result.weather; @@ -62,7 +60,6 @@ WlSessionLock { return "cloud"; } - // Authentication function function unlockAttempt() { console.log("Unlock attempt started"); if (!pamAvailable) { @@ -126,9 +123,8 @@ WlSessionLock { console.log("PAM start result:", started); } - // Lock surface WlSessionLockSurface { - // Blurred wallpaper background + // Wallpaper image to blur Image { id: lockBgImage anchors.fill: parent @@ -136,28 +132,23 @@ WlSessionLock { source: WallpaperManager.currentWallpaper !== "" ? WallpaperManager.currentWallpaper : "" cache: true smooth: false - visible: true // Show the original for FastBlur input + visible: true // source for MultiEffect } - FastBlur { + + MultiEffect { + id: lockBgBlur anchors.fill: parent source: lockBgImage - radius: 22 // Adjust blur strength as needed - transparentBorder: true + blurEnabled: true + blur: 0.48 // controls blur strength (0 to 1) + blurMax: 128 // max blur radius in pixels } - Rectangle { - anchors.fill: parent - color: Qt.rgba( - Theme.backgroundPrimary.r, - Theme.backgroundPrimary.g, - Theme.backgroundPrimary.b, 0.6) - } - // Main content container (moved up, Rectangle removed) + ColumnLayout { anchors.centerIn: parent spacing: 30 width: Math.min(parent.width * 0.8, 400) - // User avatar/icon Rectangle { Layout.alignment: Qt.AlignHCenter width: 80 @@ -171,7 +162,7 @@ WlSessionLock { anchors.margins: 4 source: Settings.settings.profileImage fillMode: Image.PreserveAspectCrop - visible: false // Only show the masked version + visible: false asynchronous: true } OpacityMask { @@ -185,7 +176,6 @@ WlSessionLock { } visible: Settings.settings.profileImage !== "" } - // Fallback icon Text { anchors.centerIn: parent text: "person" @@ -194,7 +184,6 @@ WlSessionLock { color: Theme.onAccent visible: Settings.settings.profileImage === "" } - // Glow effect layer.enabled: true layer.effect: Glow { color: Theme.accentPrimary @@ -203,7 +192,6 @@ WlSessionLock { } } - // Username Text { Layout.alignment: Qt.AlignHCenter text: Quickshell.env("USER") @@ -213,7 +201,6 @@ WlSessionLock { color: Theme.textPrimary } - // Password input container Rectangle { Layout.fillWidth: true height: 50 @@ -239,7 +226,6 @@ WlSessionLock { text: lock.password onTextChanged: lock.password = text - // Placeholder text Text { anchors.centerIn: parent text: "Enter password..." @@ -249,7 +235,6 @@ WlSessionLock { visible: !passwordInput.text && !passwordInput.activeFocus } - // Handle Enter key Keys.onPressed: function (event) { if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { lock.unlockAttempt(); @@ -262,7 +247,6 @@ WlSessionLock { } } - // Error message Rectangle { id: errorMessageRect Layout.alignment: Qt.AlignHCenter @@ -271,7 +255,7 @@ WlSessionLock { color: Theme.overlay radius: 22 visible: lock.errorMessage !== "" - + Text { anchors.centerIn: parent text: lock.errorMessage @@ -283,7 +267,6 @@ WlSessionLock { } } - // Unlock button Rectangle { Layout.alignment: Qt.AlignHCenter width: 120 @@ -332,7 +315,6 @@ WlSessionLock { offsetX: screen.width / 2 + 30 offsetY: 0 anchors.top: parent.top - //anchors.horizontalCenter: parent.horizontalCenter visible: Settings.settings.showCorners z: 50 } @@ -345,11 +327,10 @@ WlSessionLock { offsetX: - Screen.width / 2 - 30 offsetY: 0 anchors.top: parent.top - //anchors.horizontalCenter: parent.horizontalCenter visible: Settings.settings.showCorners z: 51 } - + Rectangle { width: infoColumn.width + 16 height: infoColumn.height @@ -357,15 +338,14 @@ WlSessionLock { anchors.horizontalCenter: parent.horizontalCenter bottomLeftRadius: 20 bottomRightRadius: 20 - - // Top-center info panel (clock + weather) + ColumnLayout { id: infoColumn anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter anchors.topMargin: 0 spacing: 8 - // Clock + Text { id: timeText text: Qt.formatDateTime(new Date(), "HH:mm") @@ -386,12 +366,13 @@ WlSessionLock { horizontalAlignment: Text.AlignHCenter Layout.alignment: Qt.AlignHCenter } - // Weather info (centered, no city) + RowLayout { spacing: 6 Layout.alignment: Qt.AlignHCenter anchors.horizontalCenter: parent.horizontalCenter visible: weatherData && weatherData.current_weather + Text { text: weatherData && weatherData.current_weather ? materialSymbolForCode(weatherData.current_weather.weathercode) : "cloud" font.family: "Material Symbols Outlined" @@ -399,15 +380,16 @@ WlSessionLock { color: Theme.accentPrimary verticalAlignment: Text.AlignVCenter } + Text { - text: weatherData && weatherData.current_weather ? (Settings.settings.useFahrenheit ? `${Math.round(weatherData.current_weather.temperature * 9 / 5 + 32)}°F` : `${Math.round(weatherData.current_weather.temperature)}°C`) : (Settings.settings.useFahrenheit ? "--°F" : "--°C") + text: weatherData && weatherData.current_weather ? ((Settings.settings.useFahrenheit !== undefined ? Settings.settings.useFahrenheit : false) ? `${Math.round(weatherData.current_weather.temperature * 9 / 5 + 32)}°F` : `${Math.round(weatherData.current_weather.temperature)}°C`) : ((Settings.settings.useFahrenheit !== undefined ? Settings.settings.useFahrenheit : false) ? "--°F" : "--°C") font.family: Theme.fontFamily font.pixelSize: 18 color: Theme.textSecondary verticalAlignment: Text.AlignVCenter } } - // Weather error + Text { text: weatherError color: Theme.error @@ -420,7 +402,6 @@ WlSessionLock { } } - // Update clock every second Timer { interval: 1000 running: true @@ -431,7 +412,6 @@ WlSessionLock { } } - // Update weather every 10 minutes Timer { interval: 600000 // 10 minutes running: true @@ -441,13 +421,12 @@ WlSessionLock { } } - // System control buttons (bottom right) ColumnLayout { anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 32 spacing: 12 - // Shutdown + Rectangle { width: 48 height: 48 @@ -455,6 +434,7 @@ WlSessionLock { color: shutdownArea.containsMouse ? Theme.error : "transparent" border.color: Theme.error border.width: 1 + MouseArea { id: shutdownArea anchors.fill: parent @@ -463,6 +443,7 @@ WlSessionLock { Qt.createQmlObject('import Quickshell.Io; Process { command: ["shutdown", "-h", "now"]; running: true }', lock); } } + Text { anchors.centerIn: parent text: "power_settings_new" @@ -471,7 +452,7 @@ WlSessionLock { color: shutdownArea.containsMouse ? Theme.onAccent : Theme.error } } - // Reboot + Rectangle { width: 48 height: 48 @@ -479,6 +460,7 @@ WlSessionLock { color: rebootArea.containsMouse ? Theme.accentPrimary : "transparent" border.color: Theme.accentPrimary border.width: 1 + MouseArea { id: rebootArea anchors.fill: parent @@ -487,6 +469,7 @@ WlSessionLock { Qt.createQmlObject('import Quickshell.Io; Process { command: ["reboot"]; running: true }', lock); } } + Text { anchors.centerIn: parent text: "refresh" @@ -495,7 +478,7 @@ WlSessionLock { color: rebootArea.containsMouse ? Theme.onAccent : Theme.accentPrimary } } - // Logout + Rectangle { width: 48 height: 48 @@ -503,6 +486,7 @@ WlSessionLock { color: logoutArea.containsMouse ? Theme.accentSecondary : "transparent" border.color: Theme.accentSecondary border.width: 1 + MouseArea { id: logoutArea anchors.fill: parent @@ -511,6 +495,7 @@ WlSessionLock { Qt.createQmlObject('import Quickshell.Io; Process { command: ["loginctl", "terminate-user", "' + Quickshell.env("USER") + '"]; running: true }', lock); } } + Text { anchors.centerIn: parent text: "exit_to_app" diff --git a/Widgets/Sidebar/Panel/System.qml b/Widgets/Sidebar/Panel/System.qml index fe095a6..9266958 100644 --- a/Widgets/Sidebar/Panel/System.qml +++ b/Widgets/Sidebar/Panel/System.qml @@ -155,7 +155,7 @@ Rectangle { Rectangle { width: 160 - height: 180 + height: 220 color: Theme.surface radius: 8 border.color: Theme.outline @@ -395,34 +395,54 @@ Rectangle { command: ["shutdown", "-h", "now"] running: false } + Process { id: rebootProcess command: ["reboot"] running: false } - Process { - id: logoutProcess - command: ["niri", "msg", "action", "quit", "--skip-confirmation"] - running: false - } + Process { id: suspendProcess command: ["systemctl", "suspend"] running: false } + Process { + id: logoutProcessNiri + command: ["niri", "msg", "action", "quit", "--skip-confirmation"] + running: false + } + + Process { + id: logoutProcessHyprland + command: ["hyprctl", "dispatch", "exit"] + running: false + } + + function logout() { + if (WorkspaceManager.isNiri) { + logoutProcessNiri.running = true; + } else if (WorkspaceManager.isHyprland) { + logoutProcessHyprland.running = true; + } else { + // fallback or error + console.warn("No supported compositor detected for logout"); + } + } + function suspend() { suspendProcess.running = true; } + function shutdown() { shutdownProcess.running = true; } + function reboot() { rebootProcess.running = true; } - function logout() { - logoutProcess.running = true; - } + property bool panelVisible: false @@ -453,4 +473,4 @@ Rectangle { LockScreen { id: lockScreen } -} +} \ No newline at end of file diff --git a/shell.qml b/shell.qml index 7459e94..066b599 100644 --- a/shell.qml +++ b/shell.qml @@ -26,13 +26,20 @@ Scope { return Math.round(value / step) * step; } + // Volume property reflecting current audio volume in 0-100 + // Will be kept in sync dynamically below + property int volume: (defaultAudioSink && defaultAudioSink.audio && !defaultAudioSink.audio.muted) + ? Math.round(defaultAudioSink.audio.volume * 100) + : 0 + + // Function to update volume with clamping, stepping, and applying to audio sink function updateVolume(vol) { var clamped = Math.max(0, Math.min(100, vol)); var stepped = roundToStep(clamped, 5); - volume = stepped; if (defaultAudioSink && defaultAudioSink.audio) { defaultAudioSink.audio.volume = stepped / 100; } + volume = stepped; } Component.onCompleted: { @@ -94,8 +101,8 @@ Scope { id: notificationHistoryWin } + // Reference to the default audio sink from Pipewire property var defaultAudioSink: Pipewire.defaultAudioSink - property int volume: defaultAudioSink && defaultAudioSink.audio && defaultAudioSink.audio.volume && !defaultAudioSink.audio.muted ? Math.round(defaultAudioSink.audio.volume * 100) : 0 PwObjectTracker { objects: [Pipewire.defaultAudioSink] @@ -137,4 +144,27 @@ Scope { } } } + + // --- NEW: Keep volume property in sync with actual Pipewire audio sink volume --- + + Connections { + target: defaultAudioSink.audio + onVolumeChanged: { + if (defaultAudioSink.audio && !defaultAudioSink.audio.muted) { + volume = Math.round(defaultAudioSink.audio.volume * 100); + console.log("Volume changed externally to:", volume); + } + } + onMutedChanged: { + if (defaultAudioSink.audio) { + if (defaultAudioSink.audio.muted) { + volume = 0; + console.log("Audio muted, volume set to 0"); + } else { + volume = Math.round(defaultAudioSink.audio.volume * 100); + console.log("Audio unmuted, volume restored to:", volume); + } + } + } + } }