quickshell: add notification toast popup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2ec4f400c6
commit
18ccb266c3
1 changed files with 155 additions and 0 deletions
|
|
@ -467,6 +467,7 @@ in
|
|||
keepOnReload: true
|
||||
onNotification: (notification) => {
|
||||
notification.tracked = true;
|
||||
notifToast.show(notification);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1659,6 +1660,160 @@ in
|
|||
}
|
||||
}
|
||||
}
|
||||
// Notification toast popup
|
||||
PopupWindow {
|
||||
id: notifToast
|
||||
property var currentNotif: null
|
||||
property bool open: false
|
||||
|
||||
function show(notification) {
|
||||
currentNotif = notification;
|
||||
visible = true;
|
||||
open = true;
|
||||
_toastTimer.restart();
|
||||
}
|
||||
|
||||
function dismiss() {
|
||||
open = false;
|
||||
_toastCloseDelay.start();
|
||||
}
|
||||
|
||||
anchor.window: bar
|
||||
anchor.rect.x: bar.width / 2 - 160
|
||||
anchor.rect.y: bar.height
|
||||
anchor.edges: Edges.Top | Edges.Left
|
||||
anchor.gravity: Edges.Bottom | Edges.Right
|
||||
visible: false
|
||||
width: 320
|
||||
height: toastContent.height + 2
|
||||
color: "transparent"
|
||||
|
||||
Timer {
|
||||
id: _toastTimer
|
||||
interval: 5000
|
||||
onTriggered: notifToast.dismiss()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: _toastCloseDelay
|
||||
interval: 230
|
||||
onTriggered: { notifToast.visible = false; notifToast.open = false; }
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
onHoveredChanged: {
|
||||
if (hovered) _toastTimer.stop();
|
||||
else _toastTimer.restart();
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: toastContent
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 2
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 316
|
||||
height: toastCol.height + 16
|
||||
radius: 8
|
||||
color: "#E6${c.base00}"
|
||||
clip: true
|
||||
|
||||
transform: Translate {
|
||||
y: notifToast.open ? 0 : -(toastContent.height + 10)
|
||||
Behavior on y {
|
||||
NumberAnimation { duration: 220; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
|
||||
opacity: notifToast.open ? 1.0 : 0.0
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 200; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
Column {
|
||||
id: toastCol
|
||||
anchors.left: parent.left
|
||||
anchors.right: toastDismiss.left
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 8
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
text: notifToast.currentNotif ? (notifToast.currentNotif.summary || notifToast.currentNotif.appName) : ""
|
||||
color: "#${c.base05}"
|
||||
font.family: "FiraMono Nerd Font"
|
||||
font.pixelSize: 12
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
text: notifToast.currentNotif ? (notifToast.currentNotif.body || "") : ""
|
||||
color: "#${c.base04}"
|
||||
font.family: "FiraMono Nerd Font"
|
||||
font.pixelSize: 11
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 3
|
||||
wrapMode: Text.Wrap
|
||||
visible: text !== ""
|
||||
}
|
||||
|
||||
// Action buttons
|
||||
Row {
|
||||
spacing: 4
|
||||
visible: notifToast.currentNotif && notifToast.currentNotif.actions.length > 0
|
||||
Repeater {
|
||||
model: notifToast.currentNotif ? notifToast.currentNotif.actions : []
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
width: toastActionText.width + 12
|
||||
height: toastActionText.height + 6
|
||||
radius: 4
|
||||
color: toastActionMa.containsMouse ? "#${c.base02}" : "#${c.base01}"
|
||||
border.width: 1
|
||||
border.color: "#${c.base02}"
|
||||
Text {
|
||||
id: toastActionText
|
||||
anchors.centerIn: parent
|
||||
text: modelData.text
|
||||
color: "#${c.base05}"
|
||||
font.family: "FiraMono Nerd Font"
|
||||
font.pixelSize: 10
|
||||
}
|
||||
MouseArea {
|
||||
id: toastActionMa
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: { modelData.invoke(); notifToast.dismiss(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dismiss X
|
||||
Text {
|
||||
id: toastDismiss
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 8
|
||||
text: "\u{f0156}"
|
||||
color: toastDismissMa.containsMouse ? "#${c.base05}" : "#${c.base03}"
|
||||
font.family: "FiraMono Nerd Font"
|
||||
font.pixelSize: 13
|
||||
MouseArea {
|
||||
id: toastDismissMa
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: { notifToast.currentNotif.dismiss(); notifToast.dismiss(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
'';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue