From ae9a80c1f012686c1f65fce7ce76fdd1b77b0b71 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Wed, 23 Sep 2026 21:08:35 +0200 Subject: ... --- .../quickshell/NotificationInhibitorWidget.qml | 266 +++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 accounts/gkleen@skadhi/shell/quickshell/NotificationInhibitorWidget.qml (limited to 'accounts/gkleen@skadhi/shell/quickshell/NotificationInhibitorWidget.qml') diff --git a/accounts/gkleen@skadhi/shell/quickshell/NotificationInhibitorWidget.qml b/accounts/gkleen@skadhi/shell/quickshell/NotificationInhibitorWidget.qml new file mode 100644 index 00000000..80cbba19 --- /dev/null +++ b/accounts/gkleen@skadhi/shell/quickshell/NotificationInhibitorWidget.qml @@ -0,0 +1,266 @@ +import Quickshell +import QtQuick +import Quickshell.Widgets +import qs.Services +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Shapes + +Item { + id: root + + width: icon.width + 8 + height: parent.height + anchors.verticalCenter: parent.verticalCenter + + WrapperMouseArea { + id: widgetMouseArea + + anchors.fill: parent + + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + + onClicked: NotificationManager.displayInhibited = !NotificationManager.displayInhibited + + Rectangle { + anchors.fill: parent + color: { + if (widgetMouseArea.containsMouse) { + return "#33808080"; + } + return "transparent"; + } + + Item { + anchors.fill: parent + + MaterialDesignIcon { + id: icon + + implicitSize: 14 + anchors.centerIn: parent + + icon: NotificationManager.active ? "message" : "message-off" + color: { + if (!NotificationManager.active && !NotificationManager.displayInhibited) + return "#f28a21"; + if (NotificationManager.displayInhibited) + return "white"; + return "#555"; + } + } + } + } + } + + Loader { + id: tooltipLoader + + active: false + + Connections { + target: widgetMouseArea + function onContainsMouseChanged() { + if (widgetMouseArea.containsMouse) + tooltipLoader.active = true; + } + } + + sourceComponent: PopupWindow { + id: tooltip + + property bool nextVisible: NotificationManager.active && NotificationManager.history.length > 0 && (widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse) + + anchor { + item: widgetMouseArea + edges: Edges.Bottom | Edges.Left + } + visible: false + + onNextVisibleChanged: hangTimer.restart() + + Timer { + id: hangTimer + interval: tooltip.visible ? 100 : 500 + onTriggered: { + tooltip.visible = tooltip.nextVisible; + if (!tooltip.visible) + tooltipLoader.active = false; + } + } + + implicitWidth: 400 + implicitHeight: Math.min(tooltip.screen.height * 0.66, Math.max(100, scroll.contentHeight + 16)) + color: "black" + + WrapperMouseArea { + id: tooltipMouseArea + + hoverEnabled: true + enabled: true + + anchors.fill: parent + + WrapperItem { + margin: 8 + + ScrollView { + id: scroll + + contentWidth: availableWidth + // ScrollBar.vertical.policy: ScrollBar.AlwaysOn + + ColumnLayout { + id: historyLayout + anchors { + left: parent.left + right: parent.right + } + + spacing: 8 + + Repeater { + model: ScriptModel { + values: [...NotificationManager.history].reverse().map(o => o.notification) + } + + delegate: GridLayout { + id: notif + + Layout.fillWidth: true + Layout.preferredHeight: notifSummary.contentHeight + (notifBody.visible ? notifBody.contentHeight + 8 : 0) + (notifSep.visible ? notifSep.height + 8 : 0) + notifTime.contentHeight + 8 + + required property var modelData + required property int index + + columnSpacing: 8 + rowSpacing: 8 + + columns: notifImage.visible ? 2 : 1 + rows: { + var res = 2; + if (notifBody.visible) + res += 1; + if (notifSep.visible) + res += 1; + return res; + } + + Shape { + id: notifSep + + visible: notif.index != 0 + + height: 2 + width: 400 - 32 + + ShapePath { + strokeWidth: 2 + strokeColor: "#20ffffff" + startX: 0; startY: 0; + PathLine { x: 400 - 32; y: 0; } + } + + Layout.row: 0 + Layout.column: 0 + Layout.columnSpan: notifImage.visible ? 2 : 1 + Layout.alignment: Qt.AlignHCenter + } + + Text { + id: notifSummary + + text: notif.modelData?.summary ?? "" + + font.pointSize: 10 + font.family: "Fira Sans" + font.italic: true + color: "white" + maximumLineCount: 1 + elide: Text.ElideRight + + Layout.fillWidth: true + Layout.row: notifSep.visible ? 1 : 0 + Layout.column: notifImage.visible ? 1 : 0 + } + + Image { + id: notifImage + + visible: (notif.modelData?.image || notif.modelData?.appIcon) ?? false + + onStatusChanged: { + if (notifImage.status == Image.Error) + notifImage.visible = false; + } + + source: (notif.modelData?.image || notif.modelData?.appIcon) ?? "" + fillMode: Image.PreserveAspectFit + asynchronous: true + smooth: true + mipmap: true + + Layout.maximumWidth: 50 + Layout.column: 0 + Layout.row: notifSep.visible ? 1 : 0 + Layout.fillHeight: true + Layout.rowSpan: notifBody.visible ? 3 : 2 + } + + Text { + id: notifBody + + visible: notif.modelData?.body ?? false + text: notif.modelData?.body ?? "" + textFormat: Text.RichText + wrapMode: Text.Wrap + + font.pointSize: 10 + font.family: "Fira Sans" + color: "white" + + Layout.fillWidth: true + Layout.row: notifSep.visible ? 2 : 1 + Layout.column: notifImage.visible ? 1 : 0 + } + + Text { + id: notifTime + + Connections { + target: NotificationManager.clock + function onDateChanged() { + notifTime.text = NotificationManager.formatTime(notif.modelData?.receivedTime); + } + } + + text: NotificationManager.formatTime(notif.modelData?.receivedTime) + + font.pointSize: 8 + font.family: "Fira Sans" + font.italic: true + color: "#555" + maximumLineCount: 1 + horizontalAlignment: Text.AlignRight + + Layout.fillWidth: true + Layout.row: { + var res = 1; + if (notifSep.visible) + res += 1; + if (notifBody.visible) + res += 1; + return res; + } + Layout.column: notifImage.visible ? 1 : 0 + } + } + } + } + } + } + } + } + } +} -- cgit v1.2.3