From 5d7e168a57a09db4e1b2cf30a2304b7b7fe4a410 Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Fri, 5 Sep 2025 18:33:51 -0400 Subject: [PATCH 1/9] NCircleStat + KeyboardLayout: converted to Layout --- Modules/Bar/Widgets/KeyboardLayout.qml | 15 ++++++++----- Widgets/NCircleStat.qml | 29 +++++++++++++------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Modules/Bar/Widgets/KeyboardLayout.qml b/Modules/Bar/Widgets/KeyboardLayout.qml index 24f0c26..db9dc0a 100644 --- a/Modules/Bar/Widgets/KeyboardLayout.qml +++ b/Modules/Bar/Widgets/KeyboardLayout.qml @@ -1,4 +1,5 @@ import QtQuick +import QtQuick.Layouts import Quickshell import Quickshell.Wayland import Quickshell.Io @@ -6,7 +7,7 @@ import qs.Commons import qs.Services import qs.Widgets -Row { +RowLayout { id: root property ShellScreen screen @@ -18,12 +19,17 @@ Row { // Use the shared service for keyboard layout property string currentLayout: KeyboardLayoutService.currentLayout - width: pill.width - height: pill.height + Layout.preferredWidth: pill.implicitWidth + Layout.preferredHeight: pill.implicitHeight + spacing: 0 NPill { id: pill + Layout.alignment: Qt.AlignCenter + Layout.fillWidth: false + Layout.fillHeight: false + rightOpen: BarWidgetRegistry.getNPillDirection(root) icon: "keyboard_alt" iconCircleColor: Color.mPrimary @@ -33,9 +39,8 @@ Row { tooltipText: "Keyboard layout: " + currentLayout onClicked: { - // You could open keyboard settings here if needed // For now, just show the current layout } } -} +} \ No newline at end of file diff --git a/Widgets/NCircleStat.qml b/Widgets/NCircleStat.qml index 1bd9e67..f6c1b40 100644 --- a/Widgets/NCircleStat.qml +++ b/Widgets/NCircleStat.qml @@ -1,9 +1,10 @@ import QtQuick +import QtQuick.Layouts import qs.Commons import qs.Services import qs.Widgets -// Compact circular statistic display used in the SidePanel +// Compact circular statistic display using Layout management Rectangle { id: root @@ -28,20 +29,20 @@ Rectangle { // Repaint gauge when the bound value changes onValueChanged: gauge.requestPaint() - Row { - id: innerRow + ColumnLayout { + id: mainLayout anchors.fill: parent anchors.margins: Style.marginS * scaling * contentScale - spacing: Style.marginS * scaling * contentScale - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter + spacing: 0 - // Gauge with percentage label placed inside the open gap (right side) + // Main gauge container Item { - id: gaugeWrap - anchors.verticalCenter: innerRow.verticalCenter - width: 68 * scaling * contentScale - height: 68 * scaling * contentScale + id: gaugeContainer + Layout.fillWidth: true + Layout.fillHeight: true + Layout.alignment: Qt.AlignCenter + Layout.preferredWidth: 68 * scaling * contentScale + Layout.preferredHeight: 68 * scaling * contentScale Canvas { id: gauge @@ -84,15 +85,13 @@ Rectangle { horizontalAlignment: Text.AlignHCenter } - // Tiny circular badge for the icon, inside the right-side gap + // Tiny circular badge for the icon, positioned using anchors within the gauge Rectangle { id: iconBadge width: 28 * scaling * contentScale height: width radius: width / 2 color: Color.mSurface - // border.color: Color.mPrimary - // border.width: Math.max(1, Style.borderS * scaling) anchors.right: parent.right anchors.top: parent.top anchors.rightMargin: -6 * scaling * contentScale @@ -109,4 +108,4 @@ Rectangle { } } } -} +} \ No newline at end of file From 7b5c97f38ab6e78c88c1ca8cf18efe488da8406a Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Fri, 5 Sep 2025 18:49:34 -0400 Subject: [PATCH 2/9] Tray: converted to Layout --- Modules/Bar/Widgets/KeyboardLayout.qml | 3 ++- Modules/Bar/Widgets/Tray.qml | 21 +++++++++++---------- Modules/Notification/Notification.qml | 1 - Widgets/NCircleStat.qml | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Modules/Bar/Widgets/KeyboardLayout.qml b/Modules/Bar/Widgets/KeyboardLayout.qml index db9dc0a..e304b7e 100644 --- a/Modules/Bar/Widgets/KeyboardLayout.qml +++ b/Modules/Bar/Widgets/KeyboardLayout.qml @@ -39,8 +39,9 @@ RowLayout { tooltipText: "Keyboard layout: " + currentLayout onClicked: { + // You could open keyboard settings here if needed // For now, just show the current layout } } -} \ No newline at end of file +} diff --git a/Modules/Bar/Widgets/Tray.qml b/Modules/Bar/Widgets/Tray.qml index f29d7b7..06de40f 100644 --- a/Modules/Bar/Widgets/Tray.qml +++ b/Modules/Bar/Widgets/Tray.qml @@ -26,26 +26,26 @@ Rectangle { } visible: SystemTray.items.values.length > 0 - implicitWidth: tray.width + Style.marginM * scaling * 2 + implicitWidth: trayLayout.implicitWidth + Style.marginM * scaling * 2 implicitHeight: Math.round(Style.capsuleHeight * scaling) radius: Math.round(Style.radiusM * scaling) color: Color.mSurfaceVariant Layout.alignment: Qt.AlignVCenter - Row { - id: tray - - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter + RowLayout { + id: trayLayout + anchors.centerIn: parent spacing: Style.marginS * scaling Repeater { id: repeater model: SystemTray.items + delegate: Item { - width: itemSize - height: itemSize + Layout.preferredWidth: itemSize + Layout.preferredHeight: itemSize + Layout.alignment: Qt.AlignCenter visible: modelData IconImage { @@ -146,13 +146,14 @@ Rectangle { function open() { visible = true - PanelService.willOpenPanel(trayPanel) } function close() { visible = false - trayMenu.item.hideMenu() + if (trayMenu.item) { + trayMenu.item.hideMenu() + } } // Clicking outside of the rectangle to close diff --git a/Modules/Notification/Notification.qml b/Modules/Notification/Notification.qml index 757549c..fdbe0d2 100644 --- a/Modules/Notification/Notification.qml +++ b/Modules/Notification/Notification.qml @@ -185,7 +185,6 @@ Variants { || "Unknown App"} ยท ${NotificationService.formatTimestamp(model.timestamp)}` color: Color.mSecondary font.pointSize: Style.fontSizeXS * scaling - } Rectangle { diff --git a/Widgets/NCircleStat.qml b/Widgets/NCircleStat.qml index f6c1b40..e16cb12 100644 --- a/Widgets/NCircleStat.qml +++ b/Widgets/NCircleStat.qml @@ -108,4 +108,4 @@ Rectangle { } } } -} \ No newline at end of file +} From 78cb7d4c1505a84092127d4a5555b9984a86ab61 Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Fri, 5 Sep 2025 18:49:59 -0400 Subject: [PATCH 3/9] MediaMini: fix visualizer not showing when track length is unknown (twitch) --- Modules/Bar/Widgets/MediaMini.qml | 283 +++++++++++++++++------------- 1 file changed, 159 insertions(+), 124 deletions(-) diff --git a/Modules/Bar/Widgets/MediaMini.qml b/Modules/Bar/Widgets/MediaMini.qml index 6ce7a59..2483dbc 100644 --- a/Modules/Bar/Widgets/MediaMini.qml +++ b/Modules/Bar/Widgets/MediaMini.qml @@ -18,12 +18,13 @@ RowLayout { Layout.alignment: Qt.AlignVCenter spacing: Style.marginS * scaling visible: MediaService.currentPlayer !== null && MediaService.canPlay - width: MediaService.currentPlayer !== null && MediaService.canPlay ? implicitWidth : 0 + Layout.preferredWidth: MediaService.currentPlayer !== null && MediaService.canPlay ? implicitWidth : 0 function getTitle() { return MediaService.trackTitle + (MediaService.trackArtist !== "" ? ` - ${MediaService.trackArtist}` : "") } + // A hidden text element to safely measure the full title width NText { id: fullTitleMetrics visible: false @@ -33,133 +34,167 @@ RowLayout { Rectangle { id: mediaMini - width: contentLayout.implicitWidth + Style.marginS * 2 * scaling - height: Math.round(Style.capsuleHeight * scaling) - radius: Math.round(Style.radiusM * scaling) - color: Color.mSurfaceVariant + + Layout.preferredWidth: rowLayout.implicitWidth + Style.marginM * 2 * scaling + Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling) Layout.alignment: Qt.AlignVCenter - // --- Visualizer Loaders --- - Loader { - anchors.centerIn: parent - active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "linear" - && MediaService.isPlaying && MediaService.trackLength > 0 - z: 0 - sourceComponent: LinearSpectrum { - width: mediaMini.width - Style.marginS * scaling - height: 20 * scaling - values: CavaService.values - fillColor: Color.mOnSurfaceVariant - opacity: 0.4 - } + radius: Math.round(Style.radiusM * scaling) + color: Color.mSurfaceVariant + + // Used to anchor the tooltip, so the tooltip does not move when the content expands + Item { + id: anchor + height: parent.height + width: 200 * scaling } - Loader { - anchors.centerIn: parent - active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "mirrored" - && MediaService.isPlaying && MediaService.trackLength > 0 - z: 0 - sourceComponent: MirroredSpectrum { - width: mediaMini.width - Style.marginS * scaling - height: mediaMini.height - Style.marginS * scaling - values: CavaService.values - fillColor: Color.mOnSurfaceVariant - opacity: 0.4 - } - } - - Loader { - anchors.centerIn: parent - active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "wave" - && MediaService.isPlaying && MediaService.trackLength > 0 - z: 0 - sourceComponent: WaveSpectrum { - width: mediaMini.width - Style.marginS * scaling - height: mediaMini.height - Style.marginS * scaling - values: CavaService.values - fillColor: Color.mOnSurfaceVariant - opacity: 0.4 - } - } - - // --- Main Content Layout --- - RowLayout { - id: contentLayout - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Style.marginS * scaling - spacing: Style.marginS * scaling - z: 1 - - NIcon { - id: windowIcon - text: MediaService.isPlaying ? "pause" : "play_arrow" - font.pointSize: Style.fontSizeL * scaling - Layout.alignment: Qt.AlignVCenter - visible: !Settings.data.audio.showMiniplayerAlbumArt && getTitle() !== "" && !trackArt.visible - } - - NImageCircled { - id: trackArt - imagePath: MediaService.trackArtUrl - fallbackIcon: MediaService.isPlaying ? "pause" : "play_arrow" - borderWidth: 0 - border.color: Color.transparent - Layout.preferredWidth: Math.round(18 * scaling) - Layout.preferredHeight: Math.round(18 * scaling) - Layout.alignment: Qt.AlignVCenter - visible: Settings.data.audio.showMiniplayerAlbumArt - } - - NText { - id: titleText - Layout.preferredWidth: { - if (mouseArea.containsMouse) { - return Math.round(Math.min(fullTitleMetrics.contentWidth, root.maxWidth * scaling)) - } else { - return Math.round(Math.min(fullTitleMetrics.contentWidth, root.minWidth * scaling)) - } - } - text: getTitle() - font.pointSize: Style.fontSizeS * scaling - font.weight: Style.fontWeightMedium - elide: Text.ElideRight - color: Color.mTertiary - Layout.alignment: Qt.AlignVCenter - - Behavior on Layout.preferredWidth { - NumberAnimation { - duration: Style.animationSlow - easing.type: Easing.InOutCubic - } - } - } - } - - MouseArea { - id: mouseArea + Item { + id: mainContainer anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton - onClicked: mouse => { - if (mouse.button === Qt.LeftButton) { - MediaService.playPause() - } else if (mouse.button == Qt.RightButton) { - MediaService.next() - tooltip.visible = false - } else if (mouse.button == Qt.MiddleButton) { - MediaService.previous() - tooltip.visible = false - } - } - onEntered: { - if (tooltip.text !== "") { - tooltip.show() + anchors.leftMargin: Style.marginS * scaling + anchors.rightMargin: Style.marginS * scaling + + Loader { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "linear" + && MediaService.isPlaying + z: 0 + + sourceComponent: LinearSpectrum { + width: mainContainer.width - Style.marginS * scaling + height: 20 * scaling + values: CavaService.values + fillColor: Color.mOnSurfaceVariant + opacity: 0.4 } } - onExited: { - tooltip.hide() + + Loader { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "mirrored" + && MediaService.isPlaying + z: 0 + + sourceComponent: MirroredSpectrum { + width: mainContainer.width - Style.marginS * scaling + height: mainContainer.height - Style.marginS * scaling + values: CavaService.values + fillColor: Color.mOnSurfaceVariant + opacity: 0.4 + } + } + + Loader { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "wave" + && MediaService.isPlaying + z: 0 + + sourceComponent: WaveSpectrum { + width: mainContainer.width - Style.marginS * scaling + height: mainContainer.height - Style.marginS * scaling + values: CavaService.values + fillColor: Color.mOnSurfaceVariant + opacity: 0.4 + } + } + + RowLayout { + id: rowLayout + anchors.verticalCenter: parent.verticalCenter + spacing: Style.marginS * scaling + z: 1 // Above the visualizer + + NIcon { + id: windowIcon + text: MediaService.isPlaying ? "pause" : "play_arrow" + font.pointSize: Style.fontSizeL * scaling + verticalAlignment: Text.AlignVCenter + Layout.alignment: Qt.AlignVCenter + visible: !Settings.data.audio.showMiniplayerAlbumArt && getTitle() !== "" && !trackArt.visible + } + + ColumnLayout { + Layout.alignment: Qt.AlignVCenter + visible: Settings.data.audio.showMiniplayerAlbumArt + spacing: 0 + + Item { + Layout.preferredWidth: Math.round(18 * scaling) + Layout.preferredHeight: Math.round(18 * scaling) + + NImageCircled { + id: trackArt + anchors.fill: parent + imagePath: MediaService.trackArtUrl + fallbackIcon: MediaService.isPlaying ? "pause" : "play_arrow" + borderWidth: 0 + border.color: Color.transparent + } + } + } + + NText { + id: titleText + + Layout.preferredWidth: { + if (mouseArea.containsMouse) { + return Math.round(Math.min(fullTitleMetrics.contentWidth, root.maxWidth * scaling)) + } else { + return Math.round(Math.min(fullTitleMetrics.contentWidth, root.minWidth * scaling)) + } + } + Layout.alignment: Qt.AlignVCenter + + text: getTitle() + font.pointSize: Style.fontSizeS * scaling + font.weight: Style.fontWeightMedium + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + color: Color.mTertiary + + Behavior on Layout.preferredWidth { + NumberAnimation { + duration: Style.animationSlow + easing.type: Easing.InOutCubic + } + } + } + } + + // Mouse area for hover detection + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton + onClicked: mouse => { + if (mouse.button === Qt.LeftButton) { + MediaService.playPause() + } else if (mouse.button == Qt.RightButton) { + MediaService.next() + // Need to hide the tooltip instantly + tooltip.visible = false + } else if (mouse.button == Qt.MiddleButton) { + MediaService.previous() + // Need to hide the tooltip instantly + tooltip.visible = false + } + } + + onEntered: { + if (tooltip.text !== "") { + tooltip.show() + } + } + onExited: { + tooltip.hide() + } } } } @@ -169,14 +204,14 @@ RowLayout { text: { var str = "" if (MediaService.canGoNext) { - str += "Right click for next\n" + str += "Right click for next.\n" } if (MediaService.canGoPrevious) { - str += "Middle click for previous\n" + str += "Middle click for previous." } return str } - target: mediaMini + target: anchor positionAbove: Settings.data.bar.position === "bottom" } } From ad305b3754deac4f70e0cf7fc51626894398666f Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Fri, 5 Sep 2025 18:53:24 -0400 Subject: [PATCH 4/9] Dock: converted to Layout --- Modules/Dock/Dock.qml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Modules/Dock/Dock.qml b/Modules/Dock/Dock.qml index 2fa9e98..9a71bba 100644 --- a/Modules/Dock/Dock.qml +++ b/Modules/Dock/Dock.qml @@ -130,7 +130,7 @@ Variants { Rectangle { id: dockContainer - width: dock.width + 48 * scaling + width: dockLayout.implicitWidth + 48 * scaling height: iconSize * 1.4 * scaling color: Qt.alpha(Color.mSurface, Settings.data.dock.backgroundOpacity) anchors.horizontalCenter: parent.horizontalCenter @@ -178,7 +178,7 @@ Variants { Item { id: dock - width: runningAppsRow.width + width: dockLayout.implicitWidth height: parent.height - (20 * scaling) anchors.centerIn: parent @@ -194,10 +194,10 @@ Variants { return Icons.iconForAppId(toplevel.appId?.toLowerCase()) } - Row { - id: runningAppsRow + RowLayout { + id: dockLayout spacing: Style.marginL * scaling - height: parent.height + Layout.preferredHeight: parent.height anchors.centerIn: parent Repeater { @@ -205,8 +205,10 @@ Variants { delegate: Rectangle { id: appButton - width: iconSize * scaling - height: iconSize * scaling + Layout.preferredWidth: iconSize * scaling + Layout.preferredHeight: iconSize * scaling + Layout.alignment: Qt.AlignCenter + color: Color.transparent radius: Style.radiusM * scaling From 0a48e5f34f8902502121cf6a72a1c4c62c8cec40 Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Fri, 5 Sep 2025 18:59:53 -0400 Subject: [PATCH 5/9] Clock: text was too big --- Widgets/NClock.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/Widgets/NClock.qml b/Widgets/NClock.qml index f1c0a9b..aa8ce33 100644 --- a/Widgets/NClock.qml +++ b/Widgets/NClock.qml @@ -18,6 +18,7 @@ Rectangle { id: textItem text: Time.time anchors.centerIn: parent + font.pointSize: Style.fontSizeS * scaling font.weight: Style.fontWeightBold } From 1efa1f4aa3658b35e71b79b5d5b1ec0db226add2 Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Fri, 5 Sep 2025 19:06:15 -0400 Subject: [PATCH 6/9] ActiveWindow: Converted to Layout --- Modules/Bar/Widgets/ActiveWindow.qml | 33 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Modules/Bar/Widgets/ActiveWindow.qml b/Modules/Bar/Widgets/ActiveWindow.qml index c7387d1..3a7dd36 100644 --- a/Modules/Bar/Widgets/ActiveWindow.qml +++ b/Modules/Bar/Widgets/ActiveWindow.qml @@ -7,7 +7,7 @@ import qs.Commons import qs.Services import qs.Widgets -Row { +RowLayout { id: root property ShellScreen screen @@ -15,7 +15,7 @@ Row { readonly property real minWidth: 160 readonly property real maxWidth: 400 - anchors.verticalCenter: parent.verticalCenter + Layout.alignment: Qt.AlignVCenter spacing: Style.marginS * scaling visible: getTitle() !== "" @@ -33,7 +33,7 @@ Row { return Icons.iconForAppId(focusedWindow.appId) } - // A hidden text element to safely measure the full title width + // A hidden text element to safely measure the full title width NText { id: fullTitleMetrics visible: false @@ -43,15 +43,13 @@ Row { } Rectangle { - // Let the Rectangle size itself based on its content (the Row) + id: windowTitleRect visible: root.visible - width: row.width + Style.marginM * 2 * scaling - height: Math.round(Style.capsuleHeight * scaling) + Layout.preferredWidth: contentLayout.implicitWidth + Style.marginM * 2 * scaling + Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling) radius: Math.round(Style.radiusM * scaling) color: Color.mSurfaceVariant - anchors.verticalCenter: parent.verticalCenter - Item { id: mainContainer anchors.fill: parent @@ -59,16 +57,16 @@ Row { anchors.rightMargin: Style.marginS * scaling clip: true - Row { - id: row - anchors.verticalCenter: parent.verticalCenter + RowLayout { + id: contentLayout + anchors.centerIn: parent spacing: Style.marginS * scaling // Window icon Item { - width: Style.fontSizeL * scaling * 1.2 - height: Style.fontSizeL * scaling * 1.2 - anchors.verticalCenter: parent.verticalCenter + Layout.preferredWidth: Style.fontSizeL * scaling * 1.2 + Layout.preferredHeight: Style.fontSizeL * scaling * 1.2 + Layout.alignment: Qt.AlignVCenter visible: getTitle() !== "" && Settings.data.bar.showActiveWindowIcon IconImage { @@ -85,24 +83,25 @@ Row { id: titleText // For short titles, show full. For long titles, truncate and expand on hover - width: { + Layout.preferredWidth: { if (mouseArea.containsMouse) { return Math.round(Math.min(fullTitleMetrics.contentWidth, root.maxWidth * scaling)) } else { return Math.round(Math.min(fullTitleMetrics.contentWidth, root.minWidth * scaling)) } } + Layout.alignment: Qt.AlignVCenter + horizontalAlignment: Text.AlignLeft text: getTitle() font.pointSize: Style.fontSizeS * scaling font.weight: Style.fontWeightMedium elide: mouseArea.containsMouse ? Text.ElideNone : Text.ElideRight - anchors.verticalCenter: parent.verticalCenter verticalAlignment: Text.AlignVCenter color: Color.mSecondary clip: true - Behavior on width { + Behavior on Layout.preferredWidth { NumberAnimation { duration: Style.animationSlow easing.type: Easing.InOutCubic From 8ec1ad7255a6a67002554e2a5c665f1ee96bc2e7 Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Fri, 5 Sep 2025 19:12:32 -0400 Subject: [PATCH 7/9] TaskBar converted to Layout --- Modules/Bar/Widgets/Taskbar.qml | 16 +++++++++------- Modules/Bar/Widgets/Workspace.qml | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Modules/Bar/Widgets/Taskbar.qml b/Modules/Bar/Widgets/Taskbar.qml index 623d7e7..0eef32c 100644 --- a/Modules/Bar/Widgets/Taskbar.qml +++ b/Modules/Bar/Widgets/Taskbar.qml @@ -2,6 +2,7 @@ pragma ComponentBehavior import QtQuick import QtQuick.Controls +import QtQuick.Layouts import Quickshell import Quickshell.Widgets import Quickshell.Wayland @@ -17,15 +18,14 @@ Rectangle { readonly property real itemSize: Style.baseWidgetSize * 0.8 * scaling // Always visible when there are toplevels - implicitWidth: taskbarRow.width + Style.marginM * scaling * 2 + implicitWidth: taskbarLayout.implicitWidth + Style.marginM * scaling * 2 implicitHeight: Math.round(Style.capsuleHeight * scaling) radius: Math.round(Style.radiusM * scaling) color: Color.mSurfaceVariant - Row { - id: taskbarRow - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter + RowLayout { + id: taskbarLayout + anchors.centerIn: parent spacing: Style.marginXXS * root.scaling Repeater { @@ -35,8 +35,10 @@ Rectangle { required property Toplevel modelData property Toplevel toplevel: modelData property bool isActive: ToplevelManager.activeToplevel === modelData - width: root.itemSize - height: root.itemSize + + Layout.preferredWidth: root.itemSize + Layout.preferredHeight: root.itemSize + Layout.alignment: Qt.AlignCenter Rectangle { id: iconBackground diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 6c53e65..051bdea 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -11,7 +11,7 @@ import qs.Services Item { id: root - property ShellScreen screen: null + property ShellScreen screen property real scaling: 1.0 property bool isDestroying: false From 966b2410d3cec6b9a9efab8ce4d2480445dd04aa Mon Sep 17 00:00:00 2001 From: Lemmy Date: Fri, 5 Sep 2025 19:49:01 -0400 Subject: [PATCH 8/9] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 60414c3..dcdcd20 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,7 @@ Alternatively, you can add it to your NixOS configuration or flake: | Toggle Settings Window | `qs -c noctalia-shell ipc call settings toggle` | | Toggle Lock Screen | `qs -c noctalia-shell ipc call lockScreen toggle` | | Toggle Notification History | `qs -c noctalia-shell ipc call notifications toggleHistory` | +| Toggle Notification DND | `qs -c noctalia-shell ipc call notifications toggleDND` | | Change Wallpaper | `qs -c noctalia-shell ipc call wallpaper set $path $monitor` | | Assign a Random Wallpaper | `qs -c noctalia-shell ipc call wallpaper random` | | Toggle Dark Mode | `qs -c noctalia-shell ipc call darkMode toggle` | From 05bfb6fc37213ee8faaa3d25b6c637123a097140 Mon Sep 17 00:00:00 2001 From: LemmyCook Date: Fri, 5 Sep 2025 19:57:22 -0400 Subject: [PATCH 9/9] Do Not Disturb: factorized logic and toast in its proper service. --- Modules/Bar/Widgets/NotificationHistory.qml | 8 +------- Modules/IPC/IPCManager.qml | 4 ---- Modules/Notification/NotificationHistoryPanel.qml | 8 +------- Services/NotificationService.qml | 15 +++++++++++---- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/Modules/Bar/Widgets/NotificationHistory.qml b/Modules/Bar/Widgets/NotificationHistory.qml index cb11314..274c61f 100644 --- a/Modules/Bar/Widgets/NotificationHistory.qml +++ b/Modules/Bar/Widgets/NotificationHistory.qml @@ -23,11 +23,5 @@ NIconButton { onClicked: PanelService.getPanel("notificationHistoryPanel")?.toggle(screen, this) - onRightClicked: { - Settings.data.notifications.doNotDisturb = !Settings.data.notifications.doNotDisturb - ToastService.showNotice( - Settings.data.notifications.doNotDisturb ? "Do Not Disturb enabled" : "Do Not Disturb disabled", - Settings.data.notifications.doNotDisturb ? "Notifications will be hidden but saved to history" : "Notifications will be shown normally", - "notice", false, 2000) - } + onRightClicked: Settings.data.notifications.doNotDisturb = !Settings.data.notifications.doNotDisturb } diff --git a/Modules/IPC/IPCManager.qml b/Modules/IPC/IPCManager.qml index b1ba1d7..8c541a3 100644 --- a/Modules/IPC/IPCManager.qml +++ b/Modules/IPC/IPCManager.qml @@ -40,10 +40,6 @@ Item { } function toggleDND() { Settings.data.notifications.doNotDisturb = !Settings.data.notifications.doNotDisturb - ToastService.showNotice( - Settings.data.notifications.doNotDisturb ? "Do Not Disturb enabled" : "Do Not Disturb disabled", - Settings.data.notifications.doNotDisturb ? "Notifications will be hidden but saved to history" : "Notifications will be shown normally", - "notice", false, 2000) } } diff --git a/Modules/Notification/NotificationHistoryPanel.qml b/Modules/Notification/NotificationHistoryPanel.qml index 0d4bff9..97e0a9a 100644 --- a/Modules/Notification/NotificationHistoryPanel.qml +++ b/Modules/Notification/NotificationHistoryPanel.qml @@ -48,13 +48,7 @@ NPanel { icon: Settings.data.notifications.doNotDisturb ? "notifications_off" : "notifications_active" tooltipText: Settings.data.notifications.doNotDisturb ? "Do Not Disturb (ON)" : "Do Not Disturb (OFF)" sizeRatio: 0.8 - onClicked: { - Settings.data.notifications.doNotDisturb = !Settings.data.notifications.doNotDisturb - ToastService.showNotice( - Settings.data.notifications.doNotDisturb ? "Do Not Disturb enabled" : "Do Not Disturb disabled", - Settings.data.notifications.doNotDisturb ? "Notifications will be hidden but saved to history" : "Notifications will be shown normally", - "notice", false, 2000) - } + onClicked: Settings.data.notifications.doNotDisturb = !Settings.data.notifications.doNotDisturb } NIconButton { diff --git a/Services/NotificationService.qml b/Services/NotificationService.qml index 62d88fb..1607be8 100644 --- a/Services/NotificationService.qml +++ b/Services/NotificationService.qml @@ -28,11 +28,11 @@ Singleton { // Signal when notification is received onNotification: function (notification) { + // Always add notification to history + root.addToHistory(notification) // Check if do-not-disturb is enabled if (Settings.data.notifications && Settings.data.notifications.doNotDisturb) { - // Still add to history but don't show notification - root.addToHistory(notification) return } @@ -46,8 +46,6 @@ Singleton { // Add to our model root.addNotification(notification) - // Also add to history - root.addToHistory(notification) } } @@ -109,6 +107,15 @@ Singleton { } } + Connections { + target: Settings.data.notifications + function onDoNotDisturbChanged() { + const label = Settings.data.notifications.doNotDisturb ? "'Do Not Disturb' enabled" : "'Do Not Disturb' disabled" + const description = Settings.data.notifications.doNotDisturb ? "You'll find these notifications in your history." : "Showing all notifications." + ToastService.showNotice(label, description, "notice", false, 2000) + } + } + // Function to add notification to model function addNotification(notification) { notificationModel.insert(0, {