From 14af84ffbe3b944d589519dff72996d6bd527f16 Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 16:01:31 +0200 Subject: [PATCH 1/9] LockScreen: make compact version buttons not overflow & edit clock CalendarPanel: edit clock Autoformat --- Modules/Bar/Calendar/CalendarPanel.qml | 10 +++-- Modules/LockScreen/LockScreen.qml | 56 ++++++++++++++++---------- Modules/OSD/OSD.qml | 6 ++- Widgets/NCircleStat.qml | 6 +-- Widgets/NPanel.qml | 16 ++++---- 5 files changed, 56 insertions(+), 38 deletions(-) diff --git a/Modules/Bar/Calendar/CalendarPanel.qml b/Modules/Bar/Calendar/CalendarPanel.qml index e8240e84..3b1b26a8 100644 --- a/Modules/Bar/Calendar/CalendarPanel.qml +++ b/Modules/Bar/Calendar/CalendarPanel.qml @@ -10,6 +10,8 @@ import qs.Widgets NPanel { id: root + readonly property var now: Time.date + preferredWidth: Settings.data.location.showWeekNumberInCalendar ? 400 : 380 preferredHeight: 520 @@ -193,12 +195,12 @@ NPanel { Canvas { id: secondsProgress anchors.fill: parent - property real progress: Time.date.getSeconds() / 60 + property real progress: now.getSeconds() / 60 onProgressChanged: requestPaint() Connections { target: Time function onDateChanged() { - const total = Time.date.getSeconds() * 1000 + Time.date.getMilliseconds() + const total = now.getSeconds() * 1000 + now.getMilliseconds() secondsProgress.progress = total / 60000 } } @@ -233,7 +235,7 @@ NPanel { NText { text: { - var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(Time.date, "hh AP") : Qt.locale().toString(Time.date, "HH") + var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(now, "hh AP") : Qt.locale().toString(now, "HH") return t.split(" ")[0] } @@ -245,7 +247,7 @@ NPanel { } NText { - text: Qt.formatTime(Time.date, "mm") + text: Qt.formatTime(now, "mm") pointSize: Style.fontSizeXXS * scaling font.weight: Style.fontWeightBold color: Color.mOnPrimary diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index a4f1d16d..1cb4a532 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -50,6 +50,7 @@ Loader { WlSessionLockSurface { readonly property real scaling: ScalingService.dynamicScale(screen) + readonly property var now: Time.date Item { id: batteryIndicator @@ -341,7 +342,6 @@ Loader { } } - // Spacer to push time to the right Item { Layout.fillWidth: true @@ -469,7 +469,7 @@ Loader { width: { var hasBattery = UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.isPresent var hasKeyboard = keyboardLayout.currentLayout !== "Unknown" - + if (hasBattery && hasKeyboard) { return 200 * scaling } else if (hasBattery || hasKeyboard) { @@ -729,7 +729,7 @@ Loader { spacing: 3 * scaling NText { - text: Qt.locale().toString(new Date(LocationService.data.weather.daily.time[index].replace(/-/g, "/")), "ddd") + text: Qt.locale().toString(now, "ddd") pointSize: Style.fontSizeM * scaling color: Color.mOnSurfaceVariant horizontalAlignment: Text.AlignHCenter @@ -798,10 +798,8 @@ Loader { } } } - } - // Password input RowLayout { Layout.fillWidth: true @@ -811,7 +809,6 @@ Loader { Layout.preferredWidth: Style.marginM * scaling } - Rectangle { Layout.fillWidth: true Layout.preferredHeight: 48 * scaling @@ -956,7 +953,6 @@ Loader { } } - Item { Layout.preferredWidth: Style.marginM * scaling } @@ -965,7 +961,7 @@ Loader { // System control buttons RowLayout { Layout.fillWidth: true - Layout.preferredHeight: 48 * scaling + Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 * scaling : 48 * scaling spacing: 10 * scaling Item { @@ -974,9 +970,11 @@ Loader { Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 48 * scaling - radius: 24 * scaling + Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 * scaling : 48 * scaling + radius: Settings.data.general.compactLockScreen ? 18 * scaling : 24 * scaling color: logoutButtonArea.containsMouse ? Color.mTertiary : "transparent" + border.color: Color.mOutline + border.width: 1 RowLayout { anchors.centerIn: parent @@ -984,14 +982,14 @@ Loader { NIcon { icon: "logout" - pointSize: Style.fontSizeL * scaling + pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM * scaling : Style.fontSizeL * scaling color: logoutButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant } NText { text: I18n.tr("session-menu.logout") color: logoutButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant - pointSize: Style.fontSizeM * scaling + pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS * scaling : Style.fontSizeM * scaling font.weight: Font.Medium } } @@ -1009,13 +1007,22 @@ Loader { easing.type: Easing.OutCubic } } + + Behavior on border.color { + ColorAnimation { + duration: 200 + easing.type: Easing.OutCubic + } + } } Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 48 * scaling - radius: 24 * scaling + Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 * scaling : 48 * scaling + radius: Settings.data.general.compactLockScreen ? 18 * scaling : 24 * scaling color: rebootButtonArea.containsMouse ? Color.mTertiary : "transparent" + border.color: Color.mOutline + border.width: 1 RowLayout { anchors.centerIn: parent @@ -1023,14 +1030,14 @@ Loader { NIcon { icon: "reboot" - pointSize: Style.fontSizeL * scaling + pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM * scaling : Style.fontSizeL * scaling color: rebootButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant } NText { text: I18n.tr("session-menu.reboot") color: rebootButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant - pointSize: Style.fontSizeM * scaling + pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS * scaling : Style.fontSizeM * scaling font.weight: Font.Medium } } @@ -1048,14 +1055,21 @@ Loader { easing.type: Easing.OutCubic } } + + Behavior on border.color { + ColorAnimation { + duration: 200 + easing.type: Easing.OutCubic + } + } } Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 48 * scaling - radius: 24 * scaling + Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 * scaling : 48 * scaling + radius: Settings.data.general.compactLockScreen ? 18 * scaling : 24 * scaling color: shutdownButtonArea.containsMouse ? Color.mError : "transparent" - border.color: shutdownButtonArea.containsMouse ? Color.mError : Color.transparent + border.color: shutdownButtonArea.containsMouse ? Color.mError : Color.mOutline border.width: 1 RowLayout { @@ -1064,14 +1078,14 @@ Loader { NIcon { icon: "shutdown" - pointSize: Style.fontSizeL * scaling + pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM * scaling : Style.fontSizeL * scaling color: shutdownButtonArea.containsMouse ? Color.mOnError : Color.mOnSurfaceVariant } NText { text: I18n.tr("session-menu.shutdown") color: shutdownButtonArea.containsMouse ? Color.mOnError : Color.mOnSurfaceVariant - pointSize: Style.fontSizeM * scaling + pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS * scaling : Style.fontSizeM * scaling font.weight: Font.Medium } } diff --git a/Modules/OSD/OSD.qml b/Modules/OSD/OSD.qml index 873933ba..12b261af 100644 --- a/Modules/OSD/OSD.qml +++ b/Modules/OSD/OSD.qml @@ -139,6 +139,7 @@ Variants { })() Component.onCompleted: { + } Connections { @@ -151,6 +152,7 @@ Variants { } Component.onDestruction: { + } // Anchor selection based on location (window edges) @@ -548,12 +550,12 @@ Variants { function onBrightnessChanged(newBrightness) { root.lastUpdatedBrightness = newBrightness - + if (!brightnessInitialized) { brightnessInitialized = true return } - + showOSD("brightness") } diff --git a/Widgets/NCircleStat.qml b/Widgets/NCircleStat.qml index 1305cec2..a0650692 100644 --- a/Widgets/NCircleStat.qml +++ b/Widgets/NCircleStat.qml @@ -27,12 +27,12 @@ Rectangle { // Repaint gauge when the bound value changes onValueChanged: gauge.requestPaint() - + // Force repaint when scaling changes onScalingChanged: { Qt.callLater(() => { - gauge.requestPaint() - }) + gauge.requestPaint() + }) } ColumnLayout { diff --git a/Widgets/NPanel.qml b/Widgets/NPanel.qml index e7c4c8a3..acef644e 100644 --- a/Widgets/NPanel.qml +++ b/Widgets/NPanel.qml @@ -146,12 +146,12 @@ Loader { Logger.log("NPanel", "Opened", root.objectName, "on", screen.name) dimmingOpacity = Style.opacityHeavy root.scaling = scaling = ScalingService.getScreenScale(screen) - + // Force refresh panel content when scaling is applied Qt.callLater(() => { - panelContentLoader.active = false - panelContentLoader.active = true - }) + panelContentLoader.active = false + panelContentLoader.active = true + }) } Connections { @@ -159,12 +159,12 @@ Loader { function onScaleChanged(screenName, scale) { if ((screen !== null) && (screenName === screen.name)) { root.scaling = scaling = scale - + // Force refresh panel content when scaling changes Qt.callLater(() => { - panelContentLoader.active = false - panelContentLoader.active = true - }) + panelContentLoader.active = false + panelContentLoader.active = true + }) } } } From 6da4acee09d8ec7780089cd0710001badf20c841 Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 17:51:07 +0200 Subject: [PATCH 2/9] Dock, Tray, ActiveWindow, Taskbar: add theming for app/tray icons appicon_colorize: create simple shader to colorize icons by theme color --- Assets/Translations/de.json | 18 +++++++++++ Assets/Translations/en.json | 18 +++++++++++ Assets/Translations/es.json | 18 +++++++++++ Assets/Translations/fr.json | 18 +++++++++++ Assets/Translations/pt.json | 18 +++++++++++ Assets/Translations/zh-CN.json | 18 +++++++++++ Assets/settings-default.json | 3 +- Commons/Settings.qml | 1 + Modules/Bar/Widgets/ActiveWindow.qml | 18 +++++++++++ Modules/Bar/Widgets/Taskbar.qml | 9 ++++++ Modules/Bar/Widgets/Tray.qml | 8 +++++ Modules/Dock/Dock.qml | 9 ++++++ .../WidgetSettings/ActiveWindowSettings.qml | 10 ++++++ .../Bar/WidgetSettings/TaskbarSettings.qml | 10 ++++++ .../Bar/WidgetSettings/TraySettings.qml | 13 +++++++- Modules/Settings/Tabs/DockTab.qml | 14 +++++++++ Services/BarWidgetRegistry.qml | 9 ++++-- Shaders/frag/appicon_colorize.frag | 29 ++++++++++++++++++ Shaders/qsb/appicon_colorize.frag.qsb | Bin 0 -> 1957 bytes 19 files changed, 236 insertions(+), 5 deletions(-) create mode 100644 Shaders/frag/appicon_colorize.frag create mode 100644 Shaders/qsb/appicon_colorize.frag.qsb diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 16d3042d..b97c91b8 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -318,6 +318,10 @@ "floating-distance": { "label": "Dock-Schwebeabstand", "description": "Schwebeabstand vom Bildschirmrand anpassen." + }, + "colorize-icons": { + "label": "Symbole einfärben", + "description": "Theme-Farben auf Dock-App-Symbole anwenden (nur nicht fokussierte Apps)." } }, "monitors": { @@ -929,6 +933,10 @@ "width": { "description": "Steuert die horizontale Größe des Widgets.", "label": "Widget-Breite" + }, + "colorize-icons": { + "label": "Symbole einfärben", + "description": "Theme-Farben auf das aktive Fenster-Symbol anwenden." } }, "system-monitor": { @@ -1122,6 +1130,16 @@ "only-same-output": { "label": "Nur vom gleichen Bildschirm", "description": "Zeige nur Apps vom dem Bildschirm an, wo sich die Taskbar befindet." + }, + "colorize-icons": { + "label": "Symbole einfärben", + "description": "Theme-Farben auf Taskbar-Symbole anwenden." + } + }, + "tray": { + "colorize-icons": { + "label": "Symbole einfärben", + "description": "Theme-Farben auf Tray-Symbole anwenden." } } } diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 41800513..1a0409a2 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -318,6 +318,10 @@ "floating-distance": { "label": "Dock floating distance", "description": "Adjust the floating distance from the screen edge." + }, + "colorize-icons": { + "label": "Colorize Icons", + "description": "Apply theme colors to dock app icons (non-focused apps only)." } }, "monitors": { @@ -912,6 +916,10 @@ "width": { "label": "Widget Width", "description": "Controls the horizontal size of the widget." + }, + "colorize-icons": { + "label": "Colorize Icons", + "description": "Apply theme colors to active window icon." } }, "system-monitor": { @@ -1105,6 +1113,16 @@ "only-same-output": { "label": "Only from same output", "description": "Show only apps from the output where the bar is located." + }, + "colorize-icons": { + "label": "Colorize Icons", + "description": "Apply theme colors to taskbar icons." + } + }, + "tray": { + "colorize-icons": { + "label": "Colorize Icons", + "description": "Apply theme colors to tray icons." } } } diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 6602519f..10aa1ce5 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -318,6 +318,10 @@ "floating-distance": { "label": "Distancia de flotación del dock", "description": "Ajusta la distancia de flotación desde el borde de la pantalla." + }, + "colorize-icons": { + "label": "Colorear iconos", + "description": "Aplicar colores del tema a los iconos de aplicaciones del dock (solo aplicaciones no enfocadas)." } }, "monitors": { @@ -912,6 +916,10 @@ "width": { "description": "Controla el tamaño horizontal del widget.", "label": "Ancho del widget" + }, + "colorize-icons": { + "label": "Colorear iconos", + "description": "Aplicar colores del tema al icono de la ventana activa." } }, "system-monitor": { @@ -1105,6 +1113,16 @@ "only-same-output": { "description": "Muestra solo las aplicaciones del resultado donde se encuentra la barra.", "label": "Solo de la misma salida" + }, + "colorize-icons": { + "label": "Colorear iconos", + "description": "Aplicar colores del tema a los iconos de la barra de tareas." + } + }, + "tray": { + "colorize-icons": { + "label": "Colorear iconos", + "description": "Aplicar colores del tema a los iconos de la bandeja del sistema." } } } diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index d62cace9..004a1224 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -318,6 +318,10 @@ "floating-distance": { "label": "Distance de flottaison du dock", "description": "Ajustez la distance de flottaison par rapport au bord de l'écran." + }, + "colorize-icons": { + "label": "Coloriser les icônes", + "description": "Appliquer les couleurs du thème aux icônes d'applications du dock (applications non focalisées uniquement)." } }, "monitors": { @@ -912,6 +916,10 @@ "width": { "description": "Contrôle la taille horizontale du widget.", "label": "Largeur du widget" + }, + "colorize-icons": { + "label": "Coloriser les icônes", + "description": "Appliquer les couleurs du thème à l'icône de la fenêtre active." } }, "system-monitor": { @@ -1105,6 +1113,16 @@ "only-same-output": { "description": "Afficher uniquement les applications de la sortie où la barre est située.", "label": "Seulement à partir de la même sortie" + }, + "colorize-icons": { + "label": "Coloriser les icônes", + "description": "Appliquer les couleurs du thème aux icônes de la barre des tâches." + } + }, + "tray": { + "colorize-icons": { + "label": "Coloriser les icônes", + "description": "Appliquer les couleurs du thème aux icônes de la barre système." } } } diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 25522957..03b3d37a 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -318,6 +318,10 @@ "floating-distance": { "label": "Distância de flutuação da dock", "description": "Ajuste a distância de flutuação da borda da tela." + }, + "colorize-icons": { + "label": "Colorir ícones", + "description": "Aplicar cores do tema aos ícones de aplicativos da dock (apenas aplicativos não focados)." } }, "monitors": { @@ -912,6 +916,10 @@ "width": { "description": "Controla o tamanho horizontal do widget.", "label": "Largura do Widget" + }, + "colorize-icons": { + "label": "Colorir ícones", + "description": "Aplicar cores do tema ao ícone da janela ativa." } }, "system-monitor": { @@ -1105,6 +1113,16 @@ "only-same-output": { "description": "Mostrar apenas os aplicativos da saída onde a barra está localizada.", "label": "Apenas da mesma saída" + }, + "colorize-icons": { + "label": "Colorir ícones", + "description": "Aplicar cores do tema aos ícones da barra de tarefas." + } + }, + "tray": { + "colorize-icons": { + "label": "Colorir ícones", + "description": "Aplicar cores do tema aos ícones da bandeja do sistema." } } } diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 3bbe1d89..609bdb31 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -318,6 +318,10 @@ "floating-distance": { "label": "Dock 浮动距离", "description": "调整距离屏幕边缘的浮动距离。" + }, + "colorize-icons": { + "label": "着色图标", + "description": "将主题颜色应用到 Dock 应用图标(仅限非聚焦应用)。" } }, "monitors": { @@ -912,6 +916,10 @@ "width": { "description": "控制小部件的水平尺寸。", "label": "小部件宽度" + }, + "colorize-icons": { + "label": "着色图标", + "description": "将主题颜色应用到活动窗口图标。" } }, "system-monitor": { @@ -1105,6 +1113,16 @@ "only-same-output": { "label": "仅显示同屏幕", "description": "仅显示任务栏所在屏幕上的应用程序" + }, + "colorize-icons": { + "label": "着色图标", + "description": "将主题颜色应用到任务栏图标。" + } + }, + "tray": { + "colorize-icons": { + "label": "着色图标", + "description": "将主题颜色应用到系统托盘图标。" } } } diff --git a/Assets/settings-default.json b/Assets/settings-default.json index 9b63d3ae..55d8bf07 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -138,7 +138,8 @@ "floatingRatio": 1, "onlySameOutput": true, "monitors": [], - "pinnedApps": [] + "pinnedApps": [], + "colorizeIcons": false }, "network": { "wifiEnabled": true diff --git a/Commons/Settings.qml b/Commons/Settings.qml index af6c0598..676c4575 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -272,6 +272,7 @@ Singleton { property list monitors: [] // Desktop entry IDs pinned to the dock (e.g., "org.kde.konsole", "firefox.desktop") property list pinnedApps: [] + property bool colorizeIcons: false } // network diff --git a/Modules/Bar/Widgets/ActiveWindow.qml b/Modules/Bar/Widgets/ActiveWindow.qml index de10760d..817d7cc4 100644 --- a/Modules/Bar/Widgets/ActiveWindow.qml +++ b/Modules/Bar/Widgets/ActiveWindow.qml @@ -149,6 +149,15 @@ Item { asynchronous: true smooth: true visible: source !== "" + + // Apply dock shader to active window icon (always themed) + layer.enabled: widgetSettings.colorizeIcons !== false + layer.effect: ShaderEffect { + property color targetColor: Color.mOnSurface + property real colorizeMode: 0.0 // Dock mode (grayscale) + + fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") + } } } @@ -315,6 +324,15 @@ Item { asynchronous: true smooth: true visible: source !== "" + + // Apply dock shader to active window icon (always themed) + layer.enabled: widgetSettings.colorizeIcons !== false + layer.effect: ShaderEffect { + property color targetColor: Color.mOnSurface + property real colorizeMode: 0.0 // Dock mode (grayscale) + + fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") + } } } } diff --git a/Modules/Bar/Widgets/Taskbar.qml b/Modules/Bar/Widgets/Taskbar.qml index e9035002..6f1782f3 100644 --- a/Modules/Bar/Widgets/Taskbar.qml +++ b/Modules/Bar/Widgets/Taskbar.qml @@ -81,6 +81,15 @@ Rectangle { asynchronous: true opacity: modelData.isFocused ? Style.opacityFull : 0.6 + // Apply dock shader to all taskbar icons + layer.enabled: widgetSettings.colorizeIcons !== false + layer.effect: ShaderEffect { + property color targetColor: Color.mOnSurface + property real colorizeMode: 0.0 // Dock mode (grayscale) + + fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") + } + Rectangle { anchors.bottomMargin: -2 * scaling anchors.bottom: parent.bottom diff --git a/Modules/Bar/Widgets/Tray.qml b/Modules/Bar/Widgets/Tray.qml index 0365cc2e..5237a82e 100644 --- a/Modules/Bar/Widgets/Tray.qml +++ b/Modules/Bar/Widgets/Tray.qml @@ -193,6 +193,14 @@ Rectangle { } opacity: status === Image.Ready ? 1 : 0 + layer.enabled: widgetSettings.colorizeIcons !== false + layer.effect: ShaderEffect { + property color targetColor: Color.mOnSurface + property real colorizeMode: 1.0 // Tray mode (intensity-based) + + fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") + } + MouseArea { anchors.fill: parent hoverEnabled: true diff --git a/Modules/Dock/Dock.qml b/Modules/Dock/Dock.qml index b23c90bc..c0dd0a5a 100644 --- a/Modules/Dock/Dock.qml +++ b/Modules/Dock/Dock.qml @@ -401,6 +401,15 @@ Variants { scale: appButton.hovered ? 1.15 : 1.0 + // Apply dock-specific colorization shader only to non-focused apps + layer.enabled: !appButton.isActive && Settings.data.dock.colorizeIcons + layer.effect: ShaderEffect { + property color targetColor: Color.mOnSurface + property real colorizeMode: 0.0 // Dock mode (grayscale) + + fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb") + } + Behavior on scale { NumberAnimation { duration: Style.animationNormal diff --git a/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml b/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml index 3d1be163..81184595 100644 --- a/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml @@ -18,6 +18,7 @@ ColumnLayout { property bool valueAutoHide: widgetData.autoHide !== undefined ? widgetData.autoHide : widgetMetadata.autoHide property string valueScrollingMode: widgetData.scrollingMode || widgetMetadata.scrollingMode property int valueWidth: widgetData.width !== undefined ? widgetData.width : widgetMetadata.width + property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons function saveSettings() { var settings = Object.assign({}, widgetData || {}) @@ -25,6 +26,7 @@ ColumnLayout { settings.showIcon = valueShowIcon settings.scrollingMode = valueScrollingMode settings.width = parseInt(widthInput.text) || widgetMetadata.width + settings.colorizeIcons = valueColorizeIcons return settings } @@ -44,6 +46,14 @@ ColumnLayout { onToggled: checked => root.valueShowIcon = checked } + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.widget-settings.active-window.colorize-icons.label") + description: I18n.tr("bar.widget-settings.active-window.colorize-icons.description") + checked: root.valueColorizeIcons + onToggled: checked => root.valueColorizeIcons = checked + } + NTextInput { id: widthInput Layout.fillWidth: true diff --git a/Modules/Settings/Bar/WidgetSettings/TaskbarSettings.qml b/Modules/Settings/Bar/WidgetSettings/TaskbarSettings.qml index c80dd09f..5ff3b418 100644 --- a/Modules/Settings/Bar/WidgetSettings/TaskbarSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/TaskbarSettings.qml @@ -16,11 +16,13 @@ ColumnLayout { // Local state property bool valueOnlyActiveWorkspaces: widgetData.onlyActiveWorkspaces !== undefined ? widgetData.onlyActiveWorkspaces : widgetMetadata.onlyActiveWorkspaces property bool valueOnlySameOutput: widgetData.onlySameOutput !== undefined ? widgetData.onlySameOutput : widgetMetadata.onlySameOutput + property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons function saveSettings() { var settings = Object.assign({}, widgetData || {}) settings.onlySameOutput = valueOnlySameOutput settings.onlyActiveWorkspaces = valueOnlyActiveWorkspaces + settings.colorizeIcons = valueColorizeIcons return settings } @@ -39,4 +41,12 @@ ColumnLayout { checked: root.valueOnlyActiveWorkspaces onToggled: checked => root.valueOnlyActiveWorkspaces = checked } + + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.widget-settings.taskbar.colorize-icons.label") + description: I18n.tr("bar.widget-settings.taskbar.colorize-icons.description") + checked: root.valueColorizeIcons + onToggled: checked => root.valueColorizeIcons = checked + } } diff --git a/Modules/Settings/Bar/WidgetSettings/TraySettings.qml b/Modules/Settings/Bar/WidgetSettings/TraySettings.qml index 25d08bce..d1f38261 100644 --- a/Modules/Settings/Bar/WidgetSettings/TraySettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/TraySettings.qml @@ -5,12 +5,14 @@ import qs.Commons import qs.Widgets ColumnLayout { + id: root // Properties to receive data from parent property var widgetData: ({}) // Expected by BarWidgetSettingsDialog property var widgetMetadata: ({}) // Expected by BarWidgetSettingsDialog - // Local state for the blacklist + // Local state property var localBlacklist: widgetData.blacklist || [] + property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons ListModel { id: blacklistModel @@ -27,6 +29,14 @@ ColumnLayout { spacing: Style.marginM * scaling + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.widget-settings.tray.colorize-icons.label") + description: I18n.tr("bar.widget-settings.tray.colorize-icons.description") + checked: root.valueColorizeIcons + onToggled: checked => root.valueColorizeIcons = checked + } + ColumnLayout { Layout.fillWidth: true spacing: Style.marginS * scaling @@ -135,6 +145,7 @@ ColumnLayout { // Return the updated settings for this widget instance var settings = Object.assign({}, widgetData || {}) settings.blacklist = newBlacklist + settings.colorizeIcons = root.valueColorizeIcons return settings } } diff --git a/Modules/Settings/Tabs/DockTab.qml b/Modules/Settings/Tabs/DockTab.qml index 5d31c074..d272aacf 100644 --- a/Modules/Settings/Tabs/DockTab.qml +++ b/Modules/Settings/Tabs/DockTab.qml @@ -93,6 +93,20 @@ ColumnLayout { Layout.bottomMargin: Style.marginXL * scaling } + NToggle { + Layout.fillWidth: true + label: I18n.tr("settings.dock.appearance.colorize-icons.label") + description: I18n.tr("settings.dock.appearance.colorize-icons.description") + checked: Settings.data.dock.colorizeIcons + onToggled: checked => Settings.data.dock.colorizeIcons = checked + } + + NDivider { + Layout.fillWidth: true + Layout.topMargin: Style.marginXL * scaling + Layout.bottomMargin: Style.marginXL * scaling + } + // Monitor Configuration ColumnLayout { spacing: Style.marginM * scaling diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index efb85537..f2809e14 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -43,7 +43,8 @@ Singleton { "showIcon": true, "autoHide": false, "scrollingMode": "hover", - "width": 145 + "width": 145, + "colorizeIcons": false }, "Battery": { "allowUserSettings": true, @@ -114,11 +115,13 @@ Singleton { "Taskbar": { "allowUserSettings": true, "onlySameOutput": true, - "onlyActiveWorkspaces": true + "onlyActiveWorkspaces": true, + "colorizeIcons": false }, "Tray": { "allowUserSettings": true, - "blacklist": [] + "blacklist": [], + "colorizeIcons": false }, "Workspace": { "allowUserSettings": true, diff --git a/Shaders/frag/appicon_colorize.frag b/Shaders/frag/appicon_colorize.frag new file mode 100644 index 00000000..ae108701 --- /dev/null +++ b/Shaders/frag/appicon_colorize.frag @@ -0,0 +1,29 @@ +#version 450 +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; +layout(binding = 1) uniform sampler2D source; +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + vec4 targetColor; + float colorizeMode; // 0.0 = dock mode (grayscale), 1.0 = tray mode (intensity) +} ubuf; + +void main() { + vec4 tex = texture(source, qt_TexCoord0); + + float intensity; + + if (ubuf.colorizeMode < 0.5) { + // Dock mode: Convert to grayscale using proper luminance weights + intensity = dot(tex.rgb, vec3(0.299, 0.587, 0.114)); + } else { + // Tray mode: Use the maximum RGB channel value as intensity + intensity = max(max(tex.r, tex.g), tex.b); + + // Normalize intensity to make all icons more uniform + intensity = smoothstep(0.1, 0.9, intensity); + } + + fragColor = vec4(ubuf.targetColor.rgb * intensity, tex.a) * ubuf.qt_Opacity; +} diff --git a/Shaders/qsb/appicon_colorize.frag.qsb b/Shaders/qsb/appicon_colorize.frag.qsb new file mode 100644 index 0000000000000000000000000000000000000000..15618b86dc21605375f53137209ccf520f623aa7 GIT binary patch literal 1957 zcmV;W2U_?502|48ob6fNbKAxdU-3hfVK+`3N4A?bIa^5zIw}M3o1#fMk?h#16*-Y6 z?F>i5KqNq;B>@IFIFvJb?pvQao#|`;iv9(8O8b^SBCmOA+L=x}d$%BukSwc7C!+`7 z3<>Pse*AWCZ*d?2;2Z#C0AK+CuEJ-)p$ofU!vr?K2Ok3Hg8=|30D%9{fMW(4xC9Oa zV8K8r4~4ok|4h|I*oO!l09b-(df!*1(99)5xCIt)2*8C20Gua@+lusy@y%sY*@iJ# z&;u7Z9FWu7F}mbf1`ZYkFaR6)kzgLG_SJC}dQ(vso`4No;6op5^7rY}{Hd9^03rAg zK>$6Ws8iZ-?gx)Wx+;myy^&6>zfi7VIlv2$ zo+7>oIT03qMwaVIeSo&eQ(EwIXah3v69BkQdNF;2d?Jl{uTAMRyh62i4>IB&M^@0; zDV?MBPABz5%Va*A>{6u%hH8+4ym^nL*VzhC}yJEnC2_{*K;^_b2Bz}J&+TC1=q^ly@mPIHL& zmxLF`+e8-}~a2#hH<7g4)9OVn?wh{;CXI)vR+jO5( z{M}8+ZxNmev|NT z!;)CPw}|(qvNtgPKSGx3Ny^+LtSiL(C!~Z=w7*K&F&FQU{eptsAbu=UBpFkYDG~ny z3=};_mtZFkYe0Yd~XvUG3V$R@PPQ3w>I(q4GU10-8Vzewgq~A zQcF&KxANEyLf7}0X&Bl#uzRkc9=U@@W9AHfi#Lz3U5__4E#yJe<7_{2v@bNq7#mr< z%s%7YEsF>4q$zm90y4M9R?p=JlKa^1l^M5!fz3Dkp&zKSJ!H5~>@B}H#P0C6&$$U06i7a{jNRP@cp1~;GFOF8RkRJ z6LN{ip0E~v^C+;3o4T~MI;Wjik-8qYy>J?o>o6VR71RjWEoKxdc_AQu3DH=SwOHTh zI=3f<$-$FV1X9wCLa|YA;3zj5rJ~WOm+JLu&8*idt7xrWGYrEpi={@bR;`+5saQ9Q zV#+kjIAs_{rBOA?)pEI3tCSi>wOGj$^h5D&4@3I|Oe1Te<453H#herl^78tG>?Bpf zk?-?IA-Bi6Q7{RGS#B7nSvAc@sa~#CD^&?o2G^)n%}U)Y7ma$OUM^v9Q-gD02gB~& zz#42?-0B#6tRJJTF1vQ<+>qOWzHh{Z68N8YN7irsKvr#eQWieC)ADC)Y;5&@=Q~blbGBf1 z+fEe@QCJJP#oeC7lH7vo-26VIPO|gx{>PtmHv&HlyZ60u#3|RuSYvB!_s(xNwzogt zG-N=>*w~JE!ieIQt+Aa?y1OE+WJ0t96zIE+#1+j7w_X5 znycNGDp8oLCHAAwY1<1LJFyz!d&>XohCY$&7;6e7&uhBA^xZm|Hy{q#TD1< z4I?bjk$rEnY41GMsUhBo zr#&~2JB-S}NT1dTIvt^_8~MGxV>Dgwgg(^iM4=t%L%-+E)Y0_F_7vChPLB;T*JGVd zTm^f3tE}gHA-6n{oVP^%u}()mgaj^8oT6j*WyhX2>`o^>sYtoFH_Pdr(Rhdv5?9E? zML9!~{Afz2`bs$k*1e+s*FI#u3R+Zv9#3`@RPy rrDgcCQ(&veirS%*Q{wa_|2V^O%-=YP-g2UB{KH#PM~wdh_)P1Oa0Tkw literal 0 HcmV?d00001 From 853d1d969cf0647362fa0f8ece47bee4a970a11a Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 19:12:34 +0200 Subject: [PATCH 3/9] OSD: attempting to fix layout misalignment --- Modules/OSD/OSD.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/OSD/OSD.qml b/Modules/OSD/OSD.qml index 12b261af..18986b76 100644 --- a/Modules/OSD/OSD.qml +++ b/Modules/OSD/OSD.qml @@ -231,7 +231,7 @@ Variants { opacity: 0 scale: 0.85 - anchors.horizontalCenter: verticalMode ? undefined : parent.horizontalCenter + anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: verticalMode ? parent.verticalCenter : undefined Behavior on opacity { From a60120df7a38a5df474f71609e4c214a185e0572 Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 20:32:38 +0200 Subject: [PATCH 4/9] LockScreen: add suspend button --- Modules/LockScreen/LockScreen.qml | 48 +++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 1cb4a532..9fb8824e 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -1016,6 +1016,54 @@ Loader { } } + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 * scaling : 48 * scaling + radius: Settings.data.general.compactLockScreen ? 18 * scaling : 24 * scaling + color: suspendButtonArea.containsMouse ? Color.mTertiary : "transparent" + border.color: Color.mOutline + border.width: 1 + + RowLayout { + anchors.centerIn: parent + spacing: 6 * scaling + + NIcon { + icon: "suspend" + pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM * scaling : Style.fontSizeL * scaling + color: suspendButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant + } + + NText { + text: I18n.tr("session-menu.suspend") + color: suspendButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant + pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS * scaling : Style.fontSizeM * scaling + font.weight: Font.Medium + } + } + + MouseArea { + id: suspendButtonArea + anchors.fill: parent + hoverEnabled: true + onClicked: CompositorService.suspend() + } + + Behavior on color { + ColorAnimation { + duration: 200 + easing.type: Easing.OutCubic + } + } + + Behavior on border.color { + ColorAnimation { + duration: 200 + easing.type: Easing.OutCubic + } + } + } + Rectangle { Layout.fillWidth: true Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 * scaling : 48 * scaling From 427f87b320a8eff58a8d2d22a7274136a660381f Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 20:41:38 +0200 Subject: [PATCH 5/9] LockScreen: weather respects location settings (celsius/fahrenheit) LockScreen: battery/keyboard layout below eachother --- Modules/LockScreen/LockScreen.qml | 43 +++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 9fb8824e..631fd56b 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -526,6 +526,7 @@ Loader { color: Color.mOnSurfaceVariant pointSize: Style.fontSizeM * scaling font.weight: Font.Medium + elide: Text.ElideRight } } } @@ -683,14 +684,32 @@ Loader { spacing: 12 * scaling NText { - text: Math.round(LocationService.data.weather.current_weather.temperature) + "°" + text: { + var temp = LocationService.data.weather.current_weather.temperature + var suffix = "C" + if (Settings.data.location.useFahrenheit) { + temp = LocationService.celsiusToFahrenheit(temp) + suffix = "F" + } + temp = Math.round(temp) + return temp + "°" + suffix + } pointSize: Style.fontSizeXL * scaling font.weight: Style.fontWeightBold color: Color.mOnSurface } NText { - text: LocationService.data.weather.current_weather.windspeed + " km/h" + text: { + var wind = LocationService.data.weather.current_weather.windspeed + var unit = "km/h" + if (Settings.data.location.useFahrenheit) { + wind = wind * 0.621371 // Convert km/h to mph + unit = "mph" + } + wind = Math.round(wind) + return wind + " " + unit + } pointSize: Style.fontSizeM * scaling color: Color.mOnSurfaceVariant font.weight: Font.Normal @@ -744,7 +763,17 @@ Loader { } NText { - text: Math.round(LocationService.data.weather.daily.temperature_2m_max[index]) + "°/" + Math.round(LocationService.data.weather.daily.temperature_2m_min[index]) + "°" + text: { + var max = LocationService.data.weather.daily.temperature_2m_max[index] + var min = LocationService.data.weather.daily.temperature_2m_min[index] + if (Settings.data.location.useFahrenheit) { + max = LocationService.celsiusToFahrenheit(max) + min = LocationService.celsiusToFahrenheit(min) + } + max = Math.round(max) + min = Math.round(min) + return max + "°/" + min + "°" + } pointSize: Style.fontSizeM * scaling font.weight: Style.fontWeightMedium color: Color.mOnSurfaceVariant @@ -756,9 +785,9 @@ Loader { } // Battery and Keyboard Layout (full mode only) - RowLayout { + ColumnLayout { Layout.preferredWidth: 60 * scaling - spacing: 4 * scaling + spacing: 8 * scaling // Battery RowLayout { @@ -776,6 +805,8 @@ Loader { color: Color.mOnSurfaceVariant pointSize: Style.fontSizeM * scaling font.weight: Font.Medium + elide: Text.ElideRight + Layout.fillWidth: true } } @@ -795,6 +826,8 @@ Loader { color: Color.mOnSurfaceVariant pointSize: Style.fontSizeM * scaling font.weight: Font.Medium + elide: Text.ElideRight + Layout.fillWidth: true } } } From d442f306c2ad319c633dc1c98b988aeee0ac984e Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 21:13:52 +0200 Subject: [PATCH 6/9] SettingsWindow: allow tilde usage --- Commons/Settings.qml | 17 +++++++++++++++++ Modules/ControlCenter/Cards/ProfileCard.qml | 2 +- Modules/ControlCenter/Cards/TopCard.qml | 2 +- Modules/LockScreen/LockScreen.qml | 2 +- Modules/Settings/Tabs/GeneralTab.qml | 4 ++-- Services/ScreenRecorderService.qml | 2 +- Services/WallpaperService.qml | 15 ++++++++------- 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 676c4575..6979aecb 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -375,6 +375,23 @@ Singleton { } } + // ----------------------------------------------------- + // Function to preprocess paths by expanding "~" to user's home directory + function preprocessPath(path) { + if (typeof path !== "string" || path === "") { + return path + } + + // Expand "~" to user's home directory + if (path.startsWith("~/")) { + return Quickshell.env("HOME") + path.substring(1) + } else if (path === "~") { + return Quickshell.env("HOME") + } + + return path + } + // ----------------------------------------------------- // Public function to trigger immediate settings saving function saveImmediate() { diff --git a/Modules/ControlCenter/Cards/ProfileCard.qml b/Modules/ControlCenter/Cards/ProfileCard.qml index c36d57dc..79759089 100644 --- a/Modules/ControlCenter/Cards/ProfileCard.qml +++ b/Modules/ControlCenter/Cards/ProfileCard.qml @@ -28,7 +28,7 @@ NBox { NImageCircled { width: Style.baseWidgetSize * 1.25 * scaling height: Style.baseWidgetSize * 1.25 * scaling - imagePath: Settings.data.general.avatarImage + imagePath: Settings.preprocessPath(Settings.data.general.avatarImage) fallbackIcon: "person" borderColor: Color.mPrimary borderWidth: Math.max(1, Style.borderM * scaling) diff --git a/Modules/ControlCenter/Cards/TopCard.qml b/Modules/ControlCenter/Cards/TopCard.qml index 21b68eca..abda1cd7 100644 --- a/Modules/ControlCenter/Cards/TopCard.qml +++ b/Modules/ControlCenter/Cards/TopCard.qml @@ -32,7 +32,7 @@ NBox { NImageCircled { width: Style.baseWidgetSize * 1.25 * scaling height: width - imagePath: Settings.data.general.avatarImage + imagePath: Settings.preprocessPath(Settings.data.general.avatarImage) fallbackIcon: "person" borderColor: Color.mPrimary borderWidth: Math.max(1, Style.borderM * scaling) diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 631fd56b..225c1529 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -299,7 +299,7 @@ Loader { anchors.centerIn: parent width: 66 * scaling height: 66 * scaling - imagePath: Settings.data.general.avatarImage + imagePath: Settings.preprocessPath(Settings.data.general.avatarImage) fallbackIcon: "person" SequentialAnimation on scale { diff --git a/Modules/Settings/Tabs/GeneralTab.qml b/Modules/Settings/Tabs/GeneralTab.qml index 558a8860..b665c58e 100644 --- a/Modules/Settings/Tabs/GeneralTab.qml +++ b/Modules/Settings/Tabs/GeneralTab.qml @@ -23,7 +23,7 @@ ColumnLayout { NImageCircled { width: 108 * scaling height: 108 * scaling - imagePath: Settings.data.general.avatarImage + imagePath: Settings.preprocessPath(Settings.data.general.avatarImage) fallbackIcon: "person" borderColor: Color.mPrimary borderWidth: Math.max(1, Style.borderM * scaling) @@ -50,7 +50,7 @@ ColumnLayout { id: avatarPicker title: I18n.tr("settings.general.profile.select-avatar") selectionMode: "files" - initialPath: Settings.data.general.avatarImage.substr(0, Settings.data.general.avatarImage.lastIndexOf("/")) || Quickshell.env("HOME") + initialPath: Settings.preprocessPath(Settings.data.general.avatarImage).substr(0, Settings.preprocessPath(Settings.data.general.avatarImage).lastIndexOf("/")) || Quickshell.env("HOME") nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.pnm", "*.bmp"] onAccepted: paths => { if (paths.length > 0) { diff --git a/Services/ScreenRecorderService.qml b/Services/ScreenRecorderService.qml index 7e57ce75..57fc578a 100644 --- a/Services/ScreenRecorderService.qml +++ b/Services/ScreenRecorderService.qml @@ -49,7 +49,7 @@ Singleton { function launchRecorder() { var filename = Time.getFormattedTimestamp() + ".mp4" - var videoDir = settings.directory + var videoDir = Settings.preprocessPath(settings.directory) if (videoDir && !videoDir.endsWith("/")) { videoDir += "/" } diff --git a/Services/WallpaperService.qml b/Services/WallpaperService.qml index c60f2eba..2046f6cc 100644 --- a/Services/WallpaperService.qml +++ b/Services/WallpaperService.qml @@ -10,6 +10,7 @@ Singleton { id: root readonly property ListModel fillModeModel: ListModel {} + readonly property string defaultDirectory: Settings.preprocessPath(Settings.data.wallpaper.directory) // All available wallpaper transitions readonly property ListModel transitionsModel: ListModel {} @@ -44,7 +45,7 @@ Singleton { if (!Settings.data.wallpaper.enableMultiMonitorDirectories) { // All monitors use the main directory for (var i = 0; i < Quickshell.screens.length; i++) { - root.wallpaperDirectoryChanged(Quickshell.screens[i].name, Settings.data.wallpaper.directory) + root.wallpaperDirectoryChanged(Quickshell.screens[i].name, root.defaultDirectory) } } else { // Only monitors without custom directories are affected @@ -52,7 +53,7 @@ Singleton { var screenName = Quickshell.screens[i].name var monitor = root.getMonitorConfig(screenName) if (!monitor || !monitor.directory) { - root.wallpaperDirectoryChanged(screenName, Settings.data.wallpaper.directory) + root.wallpaperDirectoryChanged(screenName, root.defaultDirectory) } } } @@ -177,16 +178,16 @@ Singleton { // Get specific monitor directory function getMonitorDirectory(screenName) { if (!Settings.data.wallpaper.enableMultiMonitorDirectories) { - return Settings.data.wallpaper.directory + return root.defaultDirectory } var monitor = getMonitorConfig(screenName) if (monitor !== undefined && monitor.directory !== undefined) { - return monitor.directory + return Settings.preprocessPath(monitor.directory) } // Fall back to the main/single directory - return Settings.data.wallpaper.directory + return root.defaultDirectory } // ------------------------------------------------------------------- @@ -218,7 +219,7 @@ Singleton { // Update Settings with new array to ensure proper persistence Settings.data.wallpaper.monitors = newMonitors.slice() - root.wallpaperDirectoryChanged(screenName, directory) + root.wallpaperDirectoryChanged(screenName, Settings.preprocessPath(directory)) } // ------------------------------------------------------------------- @@ -274,7 +275,7 @@ Singleton { found = true return { "name": screenName, - "directory": monitor.directory || getMonitorDirectory(screenName), + "directory": Settings.preprocessPath(monitor.directory) || getMonitorDirectory(screenName), "wallpaper": path } } From 760157729332910fc3a3fbe705149f1fd40c0650 Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 21:53:57 +0200 Subject: [PATCH 7/9] OSD: another possible layout fix --- Modules/OSD/OSD.qml | 143 +++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 68 deletions(-) diff --git a/Modules/OSD/OSD.qml b/Modules/OSD/OSD.qml index 18986b76..54d3de27 100644 --- a/Modules/OSD/OSD.qml +++ b/Modules/OSD/OSD.qml @@ -231,8 +231,10 @@ Variants { opacity: 0 scale: 0.85 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: verticalMode ? parent.verticalCenter : undefined + // Only horizontally center when the window itself is centered (top/bottom positions) + // For left/right vertical mode, fill the parent width + anchors.horizontalCenter: (!panel.verticalMode && panel.isCentered) ? parent.horizontalCenter : undefined + anchors.verticalCenter: panel.verticalMode ? parent.verticalCenter : undefined Behavior on opacity { NumberAnimation { @@ -349,85 +351,90 @@ Variants { Component { id: verticalContent - ColumnLayout { - // Ensure inner padding respects the rounded corners; avoid clipping the icon/text - property int vMargin: (function () { - const styleMargin = Math.round(Style.marginL * scaling) - const cornerGuard = Math.round(osdItem.radius) - return Math.max(styleMargin, cornerGuard) - })() - property int vMarginTop: Math.max(Math.round(osdItem.radius), Math.round(Style.marginS * scaling)) - property int balanceDelta: Math.round(Style.marginS * scaling) + Item { anchors.fill: parent - anchors.topMargin: vMargin - anchors.leftMargin: vMargin - anchors.rightMargin: vMargin - anchors.bottomMargin: vMargin - spacing: Math.round(Style.marginS * scaling) - // Percentage text at top - Item { - Layout.fillWidth: true - Layout.preferredHeight: percentText.implicitHeight - NText { - id: percentText - text: root.getDisplayPercentage() - color: Color.mOnSurface - pointSize: Style.fontSizeS * scaling - family: Settings.data.ui.fontFixed - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter + ColumnLayout { + // Ensure inner padding respects the rounded corners; avoid clipping the icon/text + property int vMargin: (function () { + const styleMargin = Math.round(Style.marginL * scaling) + const cornerGuard = Math.round(osdItem.radius) + return Math.max(styleMargin, cornerGuard) + })() + property int vMarginTop: Math.max(Math.round(osdItem.radius), Math.round(Style.marginS * scaling)) + property int balanceDelta: Math.round(Style.marginS * scaling) + anchors.fill: parent + anchors.topMargin: vMargin + anchors.leftMargin: vMargin + anchors.rightMargin: vMargin + anchors.bottomMargin: vMargin + spacing: Math.round(Style.marginS * scaling) + + // Percentage text at top + Item { + Layout.fillWidth: true + Layout.preferredHeight: Math.round(20 * scaling) + NText { + id: percentText + text: root.getDisplayPercentage() + color: Color.mOnSurface + pointSize: Style.fontSizeS * scaling + family: Settings.data.ui.fontFixed + width: Math.round(50 * scaling) + height: parent.height + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } } - } - - // Progress bar - Item { - Layout.fillWidth: true - Layout.fillHeight: true // Fill remaining space between text and icon - Rectangle { - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - anchors.bottom: parent.bottom - width: panel.barThickness - radius: Math.round(panel.barThickness / 2) - color: Color.mSurfaceVariant + // Progress bar + Item { + Layout.fillWidth: true + Layout.fillHeight: true // Fill remaining space between text and icon Rectangle { - anchors.left: parent.left - anchors.right: parent.right + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top anchors.bottom: parent.bottom - height: parent.height * Math.min(1.0, root.getCurrentValue()) - radius: parent.radius - color: root.getProgressColor() + width: panel.barThickness + radius: Math.round(panel.barThickness / 2) + color: Color.mSurfaceVariant - Behavior on height { - NumberAnimation { - duration: Style.animationNormal - easing.type: Easing.InOutQuad + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: parent.height * Math.min(1.0, root.getCurrentValue()) + radius: parent.radius + color: root.getProgressColor() + + Behavior on height { + NumberAnimation { + duration: Style.animationNormal + easing.type: Easing.InOutQuad + } } - } - Behavior on color { - ColorAnimation { - duration: Style.animationNormal - easing.type: Easing.InOutQuad + Behavior on color { + ColorAnimation { + duration: Style.animationNormal + easing.type: Easing.InOutQuad + } } } } } - } - // Icon at bottom - NIcon { - icon: root.getIcon() - color: root.getIconColor() - pointSize: Style.fontSizeXL * scaling - Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom - Behavior on color { - ColorAnimation { - duration: Style.animationNormal - easing.type: Easing.InOutQuad + // Icon at bottom + NIcon { + icon: root.getIcon() + color: root.getIconColor() + pointSize: Style.fontSizeXL * scaling + Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom + Behavior on color { + ColorAnimation { + duration: Style.animationNormal + easing.type: Easing.InOutQuad + } } } } From d749cbf91d5754a6cc47c1a4085af76af9cd8a0c Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 22:24:29 +0200 Subject: [PATCH 8/9] Settings: update settings-default.json --- Assets/settings-default.json | 14 +++++++++++--- Commons/Settings.qml | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Assets/settings-default.json b/Assets/settings-default.json index 55d8bf07..309ffad7 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -9,7 +9,6 @@ "floating": false, "marginVertical": 0.25, "marginHorizontal": 0.25, - "widgets": { "left": [ { @@ -37,6 +36,12 @@ { "id": "NotificationHistory" }, + { + "id": "WiFi" + }, + { + "id": "Bluetooth" + }, { "id": "Battery" }, @@ -63,7 +68,8 @@ "radiusRatio": 1, "screenRadiusRatio": 1, "animationSpeed": 1, - "animationDisabled": false + "animationDisabled": false, + "compactLockScreen": false }, "location": { "name": "Tokyo", @@ -159,7 +165,8 @@ "enabled": true, "location": "top_right", "monitors": [], - "autoHideMs": 2000 + "autoHideMs": 2000, + "alwaysOnTop": false }, "audio": { "volumeStep": 5, @@ -191,6 +198,7 @@ "templates": { "gtk": false, "qt": false, + "kcolorscheme": false, "kitty": false, "ghostty": false, "foot": false, diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 6979aecb..930bffd4 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -53,7 +53,7 @@ Singleton { // Then it should be commented out again, regular users don't need to generate // default settings on every start // TODO: automate this someday! - // generateDefaultSettings() + generateDefaultSettings() // Patch-in the local default, resolved to user's home adapter.general.avatarImage = defaultAvatar From f0f95343f32894072abf5f5c39b4f5c3c3754015 Mon Sep 17 00:00:00 2001 From: lysec Date: Sun, 12 Oct 2025 22:24:46 +0200 Subject: [PATCH 9/9] Settings: disable -default generation --- Commons/Settings.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 930bffd4..6979aecb 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -53,7 +53,7 @@ Singleton { // Then it should be commented out again, regular users don't need to generate // default settings on every start // TODO: automate this someday! - generateDefaultSettings() + // generateDefaultSettings() // Patch-in the local default, resolved to user's home adapter.general.avatarImage = defaultAvatar