Files
dotfiles/dot_config/quickshell/notifications/NotificationPopup.qml
T
mpuchstein 873801262e quickshell: apex-neon v2 colour discipline pass
Kill pure-black crust (->Void #070709) and add the figure/ground tokens
focusActive/focusField/emberField. Move active/selection states to violet
(calendar Today, keybinds active tab, battery + power profiles); stop spending
danger-red on non-danger states (mic + audio-default -> cyan); make the notif
bell state-driven (neutral/focus/danger); give critical notifications an ember
ground; bluetooth scanning -> cyan; k8s MEM -> blue (free the special violet).
2026-06-04 04:31:03 +02:00

164 lines
5.0 KiB
QML

import Quickshell
import Quickshell.Services.Notifications
import Quickshell.Widgets
import QtQuick
import QtQuick.Layouts
import "../shared" as Shared
// Single notification card
Rectangle {
id: root
required property var notification
implicitWidth: 360
implicitHeight: content.implicitHeight + 20
radius: Shared.Theme.radiusNormal
color: notification.urgency === NotificationUrgency.Critical ? Shared.Theme.emberField : Shared.Theme.popoutBackground
border.width: 1
border.color: notification.urgency === NotificationUrgency.Critical ? Qt.alpha(Shared.Theme.danger, Shared.Theme.opacityMedium) : Shared.Theme.borderSubtle
// Entrance animation
opacity: 0
scale: 0.95
Component.onCompleted: { opacity = 1; scale = 1; }
Behavior on opacity { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }
Behavior on scale { NumberAnimation { duration: 180; easing.type: Easing.OutCubic } }
// Dismiss on click
MouseArea {
anchors.fill: parent
onClicked: root.notification.dismiss()
}
ColumnLayout {
id: content
anchors.fill: parent
anchors.margins: 10
spacing: 6
// Header: icon + app name + close
RowLayout {
Layout.fillWidth: true
spacing: 8
IconImage {
source: root.notification.appIcon
implicitSize: 18
visible: root.notification.appIcon !== ""
}
Text {
text: root.notification.appName || "Notification"
color: Shared.Theme.overlay0
font.pixelSize: Shared.Theme.fontSmall
font.family: Shared.Theme.fontFamily
Layout.fillWidth: true
elide: Text.ElideRight
}
Text {
text: "\u{f0156}"
color: closeMouse.containsMouse ? Shared.Theme.danger : Shared.Theme.overlay0
font.pixelSize: 14
font.family: Shared.Theme.iconFont
MouseArea {
id: closeMouse
anchors.fill: parent
hoverEnabled: true
onClicked: root.notification.dismiss()
}
}
}
// Summary (title)
Text {
visible: text !== ""
text: root.notification.summary
color: Shared.Theme.text
font.pixelSize: Shared.Theme.fontSize
font.family: Shared.Theme.fontFamily
font.bold: true
Layout.fillWidth: true
wrapMode: Text.WordWrap
maximumLineCount: 2
elide: Text.ElideRight
}
// Body
Text {
visible: text !== ""
text: root.notification.body
textFormat: Text.PlainText
color: Shared.Theme.subtext0
font.pixelSize: Shared.Theme.fontSmall
font.family: Shared.Theme.fontFamily
Layout.fillWidth: true
wrapMode: Text.WordWrap
maximumLineCount: 4
elide: Text.ElideRight
}
// Image
Image {
visible: root.notification.image !== ""
source: root.notification.image
Layout.fillWidth: true
Layout.preferredHeight: 120
fillMode: Image.PreserveAspectCrop
Layout.topMargin: 2
}
// Actions
RowLayout {
visible: root.notification.actions.length > 0
Layout.fillWidth: true
Layout.topMargin: 2
spacing: 6
Repeater {
model: root.notification.actions
Rectangle {
required property var modelData
Layout.fillWidth: true
implicitHeight: 28
radius: 6
color: actMouse.containsMouse ? Shared.Theme.surface1 : Shared.Theme.surface0
Behavior on color { ColorAnimation { duration: 100 } }
Text {
anchors.centerIn: parent
text: modelData.text
color: Shared.Theme.text
font.pixelSize: Shared.Theme.fontSmall
font.family: Shared.Theme.fontFamily
}
MouseArea {
id: actMouse
anchors.fill: parent
hoverEnabled: true
onClicked: modelData.invoke()
}
}
}
}
}
// Urgency accent bar on left edge
Rectangle {
visible: root.notification.urgency === NotificationUrgency.Critical
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.leftMargin: 1
anchors.topMargin: root.radius
anchors.bottomMargin: root.radius
width: 3
color: Shared.Theme.danger
}
}