From e6a06349e05bc4a76dca3aa1f4e9d1bb956b309a Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Sat, 15 Nov 2025 23:43:46 +0100 Subject: [PATCH] notification sizing changes, better popup layout --- Bar.qml | 12 --- Modules/AudioWidget.qml | 7 +- Modules/NotifServer.qml | 22 ++--- Modules/NotificationCenter.qml | 63 +++++++++--- Modules/Resources.qml | 38 +++++++- ...tification.qml => TrackedNotification.qml} | 97 +++++++++++-------- Modules/TrayItem.qml | 4 - Modules/Workspaces.qml | 2 +- 8 files changed, 158 insertions(+), 87 deletions(-) rename Modules/{Notification.qml => TrackedNotification.qml} (56%) diff --git a/Bar.qml b/Bar.qml index 5e8d588..c5b7c7a 100644 --- a/Bar.qml +++ b/Bar.qml @@ -50,31 +50,19 @@ Scope { Workspaces { Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.fillHeight: true - Layout.topMargin: 6 - Layout.bottomMargin: 6 bar: bar } AudioWidget { Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.fillHeight: true - Layout.topMargin: 6 - Layout.bottomMargin: 6 } Resources { Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.fillHeight: true - Layout.topMargin: 6 - Layout.bottomMargin: 6 } UpdatesWidget { Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.fillHeight: true - Layout.topMargin: 6 - Layout.bottomMargin: 6 countUpdates: Updates.availableUpdates } } diff --git a/Modules/AudioWidget.qml b/Modules/AudioWidget.qml index 9c1cc30..dd3f36a 100644 --- a/Modules/AudioWidget.qml +++ b/Modules/AudioWidget.qml @@ -9,7 +9,7 @@ import qs.Modules Item { id: root implicitWidth: expanded ? 300 : 150 - implicitHeight: 100 + implicitHeight: 34 property bool expanded: false @@ -29,7 +29,10 @@ Item { } Rectangle { - anchors.fill: parent + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + height: 22 radius: height / 2 color: "#40000000" diff --git a/Modules/NotifServer.qml b/Modules/NotifServer.qml index 5ca060c..5babbf2 100644 --- a/Modules/NotifServer.qml +++ b/Modules/NotifServer.qml @@ -1,21 +1,14 @@ pragma ComponentBehavior: Bound + import Quickshell import Quickshell.Services.Notifications import QtQuick import qs.Modules -Rectangle { +Scope { id: root - - Text { - text: "\ue7f4" - font.family: "Material Symbols Rounded" - font.pixelSize: 16 - color: "white" - anchors.centerIn: parent - } - property list notifIds: [] + property list notifications; NotificationServer { id: notificationServer imageSupported: true @@ -23,20 +16,23 @@ Rectangle { persistenceSupported: true bodyImagesSupported: true bodySupported: true - onNotification: { + onNotification: notification => { notification.tracked = true; notification.receivedTime = Date.now(); root.notifIds.push(notification.id); - notificationComponent.createObject(root, { notif: notification, visible: !notificationCenter.doNotDisturb }); + const notif = notificationComponent.createObject(root, { notif: notification, visible: !notificationCenter.doNotDisturb }); + root.notifications.push(notif); } } Component { id: notificationComponent - Notification { + TrackedNotification { centerX: notificationCenter.posX notifIndex: root.notifIds + notifList: root.notifications onNotifDestroy: { + root.notifications.shift(); root.notifIds.shift(); } } diff --git a/Modules/NotificationCenter.qml b/Modules/NotificationCenter.qml index 50875c2..328a52a 100644 --- a/Modules/NotificationCenter.qml +++ b/Modules/NotificationCenter.qml @@ -234,10 +234,41 @@ PanelWindow { property bool shouldShow: false property bool isExpanded: false + Behavior on height { + Anim {} + } + + add: Transition { + id: addTrans + SequentialAnimation { + PauseAnimation { + duration: ( addTrans.ViewTransition.index - addTrans.ViewTransition.targetIndexes[ 0 ]) * 50 + } + ParallelAnimation { + NumberAnimation { + properties: "y"; + from: addTrans.ViewTransition.destination.y - (height / 2); + to: addTrans.ViewTransition.destination.y; + duration: 100; + easing.type: Easing.OutCubic + } + NumberAnimation { + properties: "opacity"; + from: 0; + to: 1; + duration: 100; + easing.type: Easing.OutCubic + } + } + } + } + move: Transition { + id: moveTrans NumberAnimation { - properties: "y,x"; + properties: "opacity"; duration: 100; + to: 0; easing.type: Easing.OutCubic } } @@ -287,12 +318,13 @@ PanelWindow { required property var modelData required property var index width: parent.width - height: groupColumn.isExpanded ? ( modelData.actions.length > 1 ? 130 : 80 ) : ( groupColumn.notifications.length === 1 ? ( modelData.actions.length > 1 ? 130 : 80 ) : 80 ) + height: contentColumn.height + 20 color: Config.baseBgColor border.color: "#555555" border.width: 1 radius: 8 visible: groupColumn.notifications[0].id === modelData.id || groupColumn.isExpanded + opacity: groupColumn.notifications[0].id === modelData.id ? 1 : 0 Connections { target: groupColumn @@ -307,6 +339,9 @@ PanelWindow { if ( visible ) { // expandAnim.start(); } else { + if ( groupColumn.notifications[0].id !== modelData.id ) { + groupHeader.opacity = 0; + } groupColumn.isExpanded = false; } } @@ -325,10 +360,15 @@ PanelWindow { } Column { - anchors.fill: parent - anchors.margins: 10 + id: contentColumn + anchors.centerIn: parent + width: parent.width - 20 + spacing: 10 + // anchors.left: parent.left + // anchors.right: parent.right + // anchors.leftMargin: 10 + // anchors.rightMargin: 10 RowLayout { - height: 80 width: parent.width spacing: 10 @@ -338,31 +378,32 @@ PanelWindow { Layout.preferredHeight: 48 Layout.alignment: Qt.AlignTop | Qt.AlignLeft Layout.topMargin: 5 + visible: groupHeader.modelData.image !== "" } ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true - spacing: 4 + spacing: 2 Text { text: groupHeader.modelData.summary color: "white" font.bold: true - font.pointSize: 12 + font.pointSize: 16 elide: Text.ElideRight Layout.fillWidth: true } Text { text: groupHeader.modelData.body - font.pointSize: 10 + font.pointSize: 12 color: "#dddddd" elide: Text.ElideRight lineHeightMode: Text.FixedHeight - lineHeight: 14 + lineHeight: 20 wrapMode: Text.WordWrap - maximumLineCount: 3 + maximumLineCount: 5 Layout.fillWidth: true Layout.fillHeight: true } @@ -380,7 +421,7 @@ PanelWindow { RowLayout { spacing: 2 visible: groupColumn.isExpanded ? ( groupHeader.modelData.actions.length > 1 ? true : false ) : ( groupColumn.notifications.length === 1 ? ( groupHeader.modelData.actions.length > 1 ? true : false ) : false ) - height: 15 + height: 30 width: parent.width Repeater { diff --git a/Modules/Resources.qml b/Modules/Resources.qml index 93fc667..c84cdb4 100644 --- a/Modules/Resources.qml +++ b/Modules/Resources.qml @@ -6,9 +6,15 @@ import qs.Modules Item { id: root implicitWidth: rowLayout.implicitWidth + rowLayout.anchors.leftMargin + rowLayout.anchors.rightMargin + implicitHeight: 34 Rectangle { - anchors.fill: parent + anchors { + left: parent.left + right: parent.right + verticalCenter: parent.verticalCenter + } + implicitHeight: 22 color: "#40000000" radius: height / 2 RowLayout { @@ -70,4 +76,34 @@ Item { } } } + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + } + + Loader { + anchors.left: parent.left + sourceComponent: mouseArea.containsMouse ? resourcePopout : null + } + + Component { + id: resourcePopout + PanelWindow { + anchors { + left: true + top: true + right: true + bottom: true + } + color: "transparent" + Rectangle { + x: mapFromItem(root, 0, 0).x + implicitHeight: 300 + implicitWidth: root.implicitWidth + color: "#80000000" + radius: 12 + } + } + } } diff --git a/Modules/Notification.qml b/Modules/TrackedNotification.qml similarity index 56% rename from Modules/Notification.qml rename to Modules/TrackedNotification.qml index 9a0881d..6dee817 100644 --- a/Modules/Notification.qml +++ b/Modules/TrackedNotification.qml @@ -21,11 +21,15 @@ PanelWindow { required property Notification notif required property int centerX required property list notifIndex + required property list notifList property int index: notifIndex.indexOf(notif.id) + property alias y: backgroundRect.y + property alias notifHeight: backgroundRect.implicitHeight signal notifDestroy() Component.onCompleted: { openAnim.start(); + console.log(root.index); } Timer { @@ -64,9 +68,9 @@ PanelWindow { Rectangle { id: backgroundRect implicitWidth: 400 - implicitHeight: 90 + implicitHeight: contentLayout.childrenRect.height + 16 x: root.centerX - implicitWidth - 20 - y: 34 + 20 + ( root.index * ( implicitHeight + 10 )) + y: !root.notifList[ root.index - 1 ] ? 34 + 20 : root.notifList[ root.index - 1 ].y + root.notifList[ root.index - 1 ].notifHeight + 10 color: Config.baseBgColor border.color: "#555555" radius: 8 @@ -78,53 +82,60 @@ PanelWindow { } } - RowLayout { - anchors.fill: parent - anchors.margins: 8 - spacing: 12 - IconImage { - source: root.notif.image - Layout.preferredWidth: 64 - Layout.preferredHeight: 64 - Layout.alignment: Qt.AlignHCenter | Qt.AlignLeft - visible: root.notif.image !== "" - } - - ColumnLayout { - Layout.fillWidth: true - Layout.leftMargin: root.notif.image !== "" ? 0 : 16 - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - - Text { - text: root.notif.appName - color: "white" - font.bold: true - font.pointSize: 12 - elide: Text.ElideRight - wrapMode: Text.NoWrap - Layout.fillWidth: true + Column { + id: contentLayout + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: 10 + spacing: 8 + RowLayout { + spacing: 12 + IconImage { + source: root.notif.image + Layout.preferredWidth: 48 + Layout.preferredHeight: 48 + Layout.alignment: Qt.AlignHCenter | Qt.AlignLeft + visible: root.notif.image !== "" } - Text { - text: root.notif.summary - color: "white" - font.pointSize: 10 - font.bold: true - elide: Text.ElideRight - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - Text { - text: root.notif.body - color: "#dddddd" - font.pointSize: 10 - elide: Text.ElideRight - wrapMode: Text.WordWrap + ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true + Layout.leftMargin: 0 + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + + Text { + text: root.notif.appName + color: "white" + font.bold: true + font.pointSize: 14 + elide: Text.ElideRight + wrapMode: Text.NoWrap + Layout.fillWidth: true + } + + Text { + text: root.notif.summary + color: "white" + font.pointSize: 12 + font.bold: true + elide: Text.ElideRight + wrapMode: Text.WordWrap + Layout.fillWidth: true + } + } } + Text { + text: root.notif.body + color: "#dddddd" + font.pointSize: 14 + elide: Text.ElideRight + wrapMode: Text.WordWrap + maximumLineCount: 4 + width: parent.width + } } Rectangle { diff --git a/Modules/TrayItem.qml b/Modules/TrayItem.qml index 01287db..5b05237 100644 --- a/Modules/TrayItem.qml +++ b/Modules/TrayItem.qml @@ -25,10 +25,6 @@ MouseArea { Image { id: icon - Component.onCompleted: { - console.log(root.item.icon); - } - property bool batteryHDPI: root.bar.screen.x < 0 && root.item.icon.includes("battery") property bool nmHDPI: root.bar.screen.x < 0 && root.item.icon.includes("nm-") diff --git a/Modules/Workspaces.qml b/Modules/Workspaces.qml index 9eaae09..1d3a3f6 100644 --- a/Modules/Workspaces.qml +++ b/Modules/Workspaces.qml @@ -14,7 +14,7 @@ Rectangle { property HyprlandMonitor monitor: Hyprland.monitorFor( root.bar?.screen ) implicitWidth: workspacesRow.implicitWidth + 6 - implicitHeight: workspacesRow.implicitHeight + 7 + implicitHeight: 22 function shouldShow(monitor) { Hyprland.refreshWorkspaces();