blob: 28ffafbcb4c960aad260dc9571bce1371fcc6c3c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
import Quickshell
import Quickshell.Wayland
import QtQuick
// The balloon stack, bottom-right of DP-1, over conky.
Scope {
id: root
// A tick drives both expiry and the end of a snooze without waiting for a
// file change. 250ms keeps ronema's -t 1 near-instant.
property double now: Date.now()
Timer {
interval: 250
running: true
repeat: true
onTriggered: root.now = Date.now()
}
// Which live notifications draw here. Suppression is deliberately here
// and not in the daemon: the drawer lists a notification DND chose not to
// pop, because a list the user opened is not an interruption.
readonly property var visible: (Notify.queue || []).filter(p => {
if (Notify.drawerOpen) return false;
if (p.expires !== 0 && root.now >= p.expires) return false;
if (Notify.snoozeUntil > root.now) return false;
if (Status.dnd && p.urgency !== "critical") return false;
return true;
})
PanelWindow {
id: win
visible: root.visible.length > 0
screen: Quickshell.screens.find(s => s.name === "DP-1") ?? Quickshell.screens[0]
anchors { bottom: true; right: true }
margins { bottom: 12; right: 12 }
implicitWidth: 340
implicitHeight: column.implicitHeight
color: "transparent"
exclusionMode: ExclusionMode.Ignore
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.namespace: "quickshell-notifications"
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
Column {
id: column
width: parent.width
anchors { bottom: parent.bottom; right: parent.right }
spacing: 8
Repeater {
model: root.visible
NotificationBalloon { notification: modelData }
}
}
}
}
|