Notifications WIP
This commit is contained in:
@@ -10,8 +10,8 @@ Rectangle {
|
||||
property string monitor: ""
|
||||
property string icon: " "
|
||||
property bool audioPipewireActive: Pipewire.defaultAudioSink ? true : false
|
||||
property int volume: audioPipewireActive? Math.round(Pipewire.defaultAudioSink.audio.volume * 100): 30
|
||||
property var sink: audioPipewireActive ? Pipewire.defaultAudioSink : null
|
||||
property int volume: audioPipewireActive ? Math.round(sink.audio.volume * 100) : 30
|
||||
|
||||
implicitWidth: audioText.implicitWidth * 1.6
|
||||
implicitHeight: Theme.heightGaps
|
||||
@@ -20,12 +20,11 @@ Rectangle {
|
||||
states: [
|
||||
State {
|
||||
name: "Mute"
|
||||
when: audioWidget.volume == 0
|
||||
when: audioWidget.volume == 0 || audioWidget.sink.audio.muted
|
||||
|
||||
PropertyChanges {
|
||||
audioWidget.icon: " "
|
||||
}
|
||||
|
||||
},
|
||||
State {
|
||||
name: "low volume"
|
||||
@@ -34,7 +33,6 @@ Rectangle {
|
||||
PropertyChanges {
|
||||
audioWidget.icon: " "
|
||||
}
|
||||
|
||||
},
|
||||
State {
|
||||
name: "high volume"
|
||||
@@ -43,7 +41,6 @@ Rectangle {
|
||||
PropertyChanges {
|
||||
audioWidget.icon: " "
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
@@ -81,18 +78,23 @@ Rectangle {
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
PopUpHover.start(audioWidget,"audio")
|
||||
PopUpHover.start(audioWidget, "audio");
|
||||
}
|
||||
onExited: {
|
||||
// PopUpHover.exit()
|
||||
PopUpHover.exit()
|
||||
PopUpHover.exit();
|
||||
}
|
||||
onClicked: {
|
||||
onClicked: mouse => {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
parent.sink.audio.muted = !parent.sink.audio.muted;
|
||||
} else if (mouse.button === Qt.LeftButton) {
|
||||
audioWidgetProcess.startDetached();
|
||||
}
|
||||
onWheel: (wheel) => {
|
||||
}
|
||||
onWheel: wheel => {
|
||||
if (wheel.angleDelta.y > 0) {
|
||||
if (0)
|
||||
return;
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import qs.Services
|
||||
import qs.Common
|
||||
import qs.Widgets
|
||||
import Quickshell.Services.Notifications
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property var monitor: ""
|
||||
property bool createWindow: false
|
||||
|
||||
MarginWrapperManager {
|
||||
rightMargin: Theme.gaps
|
||||
@@ -22,19 +27,30 @@ Item {
|
||||
id: clockText
|
||||
|
||||
anchors.centerIn: parent
|
||||
text: "OPA!"
|
||||
text: {
|
||||
NotificationService.notificationsNumber > 0 ? "\udb80\udc9a "+NotificationService.notificationsNumber : "\ueaa2";
|
||||
}
|
||||
font.bold: true
|
||||
font.pixelSize: Theme.pixelSize
|
||||
font.family: Theme.fontFamily
|
||||
color: Theme.textColor
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
console.log(Notifications.tracked)
|
||||
console.log(NotificationService.currentNotification.image);
|
||||
root.createWindow = true
|
||||
}
|
||||
}
|
||||
}
|
||||
LazyLoader {
|
||||
id: windowLoader
|
||||
|
||||
}
|
||||
active: root.createWindow
|
||||
|
||||
component: NotificationWindow {
|
||||
anchor.item:root
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
Services/NotificationService.qml
Normal file
66
Services/NotificationService.qml
Normal file
@@ -0,0 +1,66 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Notifications
|
||||
import Quickshell.Widgets
|
||||
import qs.Widgets
|
||||
|
||||
Singleton {
|
||||
id: notificationRoot
|
||||
|
||||
|
||||
readonly property var notificationServer: notificationServer
|
||||
readonly property var trackedNotifications: notificationServer.trackedNotifications
|
||||
readonly property var notificationsNumber: notificationServer.trackedNotifications.values.length
|
||||
property bool shouldShowOsd: false
|
||||
property var currentNotification: null
|
||||
|
||||
NotificationServer {
|
||||
id: notificationServer
|
||||
imageSupported: true
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onNotification(notif) {
|
||||
if (notif.body == "MediaOngoingActivity") {
|
||||
notif.dismiss();
|
||||
return;
|
||||
}
|
||||
notif.tracked = true;
|
||||
notificationRoot.currentNotification = notif;
|
||||
notificationRoot.shouldShowOsd = true;
|
||||
notificationTimer.start();
|
||||
}
|
||||
|
||||
target: notificationServer
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: notificationTimer
|
||||
|
||||
interval: 5000
|
||||
onTriggered: parent.shouldShowOsd = false
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: popupLoader
|
||||
active: currentNotification && shouldShowOsd
|
||||
|
||||
component: NotificationPopup {
|
||||
notification: currentNotification
|
||||
// No signal handler here!
|
||||
}
|
||||
|
||||
onItemChanged: {
|
||||
if (item) {
|
||||
item.dismissed.connect(function() {
|
||||
notificationRoot.shouldShowOsd = false
|
||||
currentNotification.dismiss()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Services.Notifications
|
||||
|
||||
Singleton {
|
||||
id: notificationsRoot
|
||||
|
||||
NotificationServer {
|
||||
id: nServer
|
||||
imageSupported: true
|
||||
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onNotification(rapazinho) {
|
||||
console.log(rapazinho.id)
|
||||
console.log(nServer.trackedNotifications)
|
||||
}
|
||||
|
||||
target: nServer
|
||||
}
|
||||
|
||||
property var tracked: nServer.trackedNotifications
|
||||
|
||||
|
||||
}
|
||||
149
Widgets/NotificationPopup.qml
Normal file
149
Widgets/NotificationPopup.qml
Normal file
@@ -0,0 +1,149 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Notifications
|
||||
import Quickshell.Widgets
|
||||
|
||||
PanelWindow {
|
||||
id: notificationRoot
|
||||
|
||||
// Since the panel's screen is unset, it will be picked by the compositor
|
||||
// when the window is created. Most compositors pick the current active monitor.
|
||||
|
||||
property bool hasImage: notification?.image ? true : false
|
||||
|
||||
property string image: {
|
||||
if (hasImage) {
|
||||
return notification.image;
|
||||
}
|
||||
if (notification?.appIcon === "") {
|
||||
return "";
|
||||
}
|
||||
return Quickshell.iconPath(notification?.appIcon);
|
||||
}
|
||||
property var notification: null
|
||||
|
||||
signal dismissed()
|
||||
|
||||
anchors.top: true
|
||||
margins.top: screen.height / 100
|
||||
exclusiveZone: 0
|
||||
|
||||
implicitWidth: 400
|
||||
implicitHeight: 100
|
||||
color: "transparent"
|
||||
|
||||
// An empty click mask prevents the window from blocking mouse events.
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
topLeftRadius: 100
|
||||
bottomLeftRadius: 100
|
||||
topRightRadius: 20
|
||||
bottomRightRadius: 20
|
||||
color: "#80000000"
|
||||
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
notificationRoot.dismissed()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
}
|
||||
|
||||
ClippingRectangle {
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
|
||||
implicitWidth: 100
|
||||
implicitHeight: 100
|
||||
visible: image? true : false
|
||||
|
||||
color: "grey"
|
||||
|
||||
radius: 100
|
||||
|
||||
IconImage {
|
||||
anchors.centerIn: parent
|
||||
implicitSize: 100
|
||||
source: notificationRoot.image
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
Layout.leftMargin: 10
|
||||
Layout.rightMargin: 10
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
|
||||
implicitHeight: 30
|
||||
radius: 20
|
||||
color: "#50ffffff"
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
implicitWidth: parent.width
|
||||
radius: parent.radius
|
||||
color: "white"
|
||||
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.WordWrap
|
||||
fontSizeMode: Text.Fit
|
||||
|
||||
text: notificationRoot.notification.summary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
|
||||
implicitHeight: 55
|
||||
radius: 20
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
implicitWidth: parent.width
|
||||
radius: parent.radius
|
||||
color: "white"
|
||||
|
||||
Text {
|
||||
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 24
|
||||
wrapMode: Text.WordWrap
|
||||
fontSizeMode: Text.Fit
|
||||
minimumPixelSize: 10
|
||||
elide: Text.ElideRight
|
||||
|
||||
text: notificationRoot.notification.body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Widgets/NotificationWindow.qml
Normal file
42
Widgets/NotificationWindow.qml
Normal file
@@ -0,0 +1,42 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Notifications
|
||||
import Quickshell.Widgets
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
PopupWindow {
|
||||
|
||||
anchor.item:root
|
||||
anchor.rect.y: parentWindow.height
|
||||
implicitWidth: 400
|
||||
implicitHeight: 1000
|
||||
color: "white"
|
||||
visible:true
|
||||
|
||||
id: notificationRoot
|
||||
|
||||
// Since the panel's screen is unset, it will be picked by the compositor
|
||||
// when the window is created. Most compositors pick the current active monitor.
|
||||
|
||||
|
||||
// An empty click mask prevents the window from blocking mouse events.
|
||||
Component {
|
||||
id: contactDelegate
|
||||
NotificationPopup {
|
||||
id: myItem
|
||||
required property string notification
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
model: NotificationService.trackedNotifications.values
|
||||
delegate: contactDelegate
|
||||
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ WrapperMouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
if (parent.hasTopLevel) {
|
||||
if (parent.hasTopLevel && !parent.workspaceActive) {
|
||||
PopUpHover.start(workspacesRectangle, "workspace")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user