Introduced Notification server, and added background thorugh quickshell
This commit is contained in:
@@ -7,4 +7,5 @@ Singleton {
|
|||||||
id: root
|
id: root
|
||||||
property bool mediaControlsOpen: false
|
property bool mediaControlsOpen: false
|
||||||
property bool osdVolumeOpen: false
|
property bool osdVolumeOpen: false
|
||||||
|
property bool notificationPanelOpen: false
|
||||||
}
|
}
|
||||||
36
background/Background.qml
Normal file
36
background/Background.qml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import qs.common
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
asynchronous: true
|
||||||
|
active: Config.background.enabled
|
||||||
|
|
||||||
|
sourceComponent: Variants {
|
||||||
|
model: Quickshell.screens
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: background
|
||||||
|
|
||||||
|
required property ShellScreen modelData
|
||||||
|
|
||||||
|
screen: modelData
|
||||||
|
WlrLayershell.namespace: "hydro-os-background"
|
||||||
|
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||||
|
WlrLayershell.layer: WlrLayer.Background
|
||||||
|
color: "black"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Wallpaper {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
background/Wallpaper.qml
Normal file
19
background/Wallpaper.qml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import qs.common
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string source: Config.options.background.wallpaperPath
|
||||||
|
property Image current: one
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: one
|
||||||
|
source: root.source
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ Scope {
|
|||||||
right: true
|
right: true
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: 45
|
implicitHeight: Config.options.bar.height
|
||||||
|
|
||||||
RowLayout { // Left Section
|
RowLayout { // Left Section
|
||||||
id: leftSection
|
id: leftSection
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Item {
|
|||||||
} else if (event.button === Qt.ForwardButton) {
|
} else if (event.button === Qt.ForwardButton) {
|
||||||
MprisController.shiftPlayer(1);
|
MprisController.shiftPlayer(1);
|
||||||
} else if (event.button === Qt.LeftButton) {
|
} else if (event.button === Qt.LeftButton) {
|
||||||
GlobalStates.mediaControlsOpen = !GlobalStates.mediaControlsOpen
|
GlobalStates.mediaControlsOpen = !GlobalStates.mediaControlsOpen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import qs
|
||||||
import qs.common
|
import qs.common
|
||||||
import qs.common.widgets
|
import qs.common.widgets
|
||||||
import QtQuick
|
import QtQuick
|
||||||
@@ -9,6 +10,14 @@ Item {
|
|||||||
height: parent.height
|
height: parent.height
|
||||||
implicitWidth: rowLayout.implicitWidth
|
implicitWidth: rowLayout.implicitWidth
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
onPressed: (event) => {
|
||||||
|
GlobalStates.notificationPanelOpen = !GlobalStates.notificationPanelOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: rowLayout
|
id: rowLayout
|
||||||
|
|
||||||
@@ -19,9 +28,9 @@ Item {
|
|||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
font.pixelSize: Appearance.font.pixelSize.larger
|
font.pixelSize: Appearance.font.pixelSize.larger
|
||||||
color: Appearance.m3colors.m3error
|
color: Appearance.m3colors.m3error
|
||||||
text: "" + NotificationServer.amountNotifications
|
text: "" + NotificationService.amountNotifications
|
||||||
visible: {
|
visible: {
|
||||||
NotificationServer.amountNotifications > 0
|
NotificationService.amountNotifications > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,9 +38,9 @@ Item {
|
|||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
visible: true
|
visible: true
|
||||||
fill: 1
|
fill: 1
|
||||||
text: NotificationServer.amountNotifications > 0 ? "notifications_unread" : "notifications"
|
text: NotificationService.amountNotifications > 0 ? "notifications_unread" : "notifications"
|
||||||
iconSize: Appearance.font.pixelSize.larger
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
color: NotificationServer.amountNotifications > 0 ? Appearance.m3colors.m3error : Appearance.m3colors.m3onSecondaryContainer
|
color: NotificationService.amountNotifications > 0 ? Appearance.m3colors.m3error : Appearance.m3colors.m3onSecondaryContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,11 +40,13 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject background: JsonObject {
|
property JsonObject background: JsonObject {
|
||||||
property string wallpaperPath: ""
|
property bool enabled: true
|
||||||
|
property string wallpaperPath: "/usr/share/hydro-os/DefaultBackground.png"
|
||||||
property string thumbnailPath: ""
|
property string thumbnailPath: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject bar: JsonObject {
|
property JsonObject bar: JsonObject {
|
||||||
|
property int height: 45
|
||||||
property bool bottom: false // Instead of top
|
property bool bottom: false // Instead of top
|
||||||
property int cornerStyle: 0 // 0: Hug | 1: Float | 2: Plain rectangle
|
property int cornerStyle: 0 // 0: Hug | 1: Float | 2: Plain rectangle
|
||||||
property bool borderless: false // true for no grouping of items
|
property bool borderless: false // true for no grouping of items
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Quickshell.Services.Mpris
|
|||||||
Singleton {
|
Singleton {
|
||||||
readonly property list<MprisPlayer> activePlayers: Mpris.players.values
|
readonly property list<MprisPlayer> activePlayers: Mpris.players.values
|
||||||
readonly property var meaningfulPlayers: filterDuplicatePlayers(activePlayers)
|
readonly property var meaningfulPlayers: filterDuplicatePlayers(activePlayers)
|
||||||
readonly property bool hasPlayers: meaningfulPlayers.length > 0
|
readonly property bool hasPlayers: activePlayers.length > 0
|
||||||
property int playerIndex: 0
|
property int playerIndex: 0
|
||||||
|
|
||||||
function activePlayer() {
|
function activePlayer() {
|
||||||
@@ -15,7 +15,7 @@ Singleton {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
assertIndex();
|
assertIndex();
|
||||||
return meaningfulPlayers[playerIndex];
|
return activePlayers[playerIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
function shiftPlayer(shift) {
|
function shiftPlayer(shift) {
|
||||||
@@ -23,7 +23,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function assertIndex() {
|
function assertIndex() {
|
||||||
if (playerIndex < 0 || playerIndex >= meaningfulPlayers.length) {
|
if (playerIndex < 0 || playerIndex >= activePlayers.length) {
|
||||||
playerIndex = (playerIndex + activePlayers.length) % activePlayers.length
|
playerIndex = (playerIndex + activePlayers.length) % activePlayers.length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ Singleton {
|
|||||||
|
|
||||||
NotificationServer {
|
NotificationServer {
|
||||||
id: server
|
id: server
|
||||||
|
actionsSupported: true
|
||||||
|
|
||||||
onNotification: notif => {
|
onNotification: notif => {
|
||||||
notif.tracked = true;
|
notif.tracked = true;
|
||||||
@@ -22,6 +22,7 @@ Button {
|
|||||||
property var releaseAction // When left clicking (release)
|
property var releaseAction // When left clicking (release)
|
||||||
property var altAction // When right clicking
|
property var altAction // When right clicking
|
||||||
property var middleClickAction // When middle clicking
|
property var middleClickAction // When middle clicking
|
||||||
|
property color buttonTextColor: Appearance?.m3colors.m3onBackground ?? "black"
|
||||||
|
|
||||||
property color colBackground: ColorUtils.transparentize(Appearance?.colors.colLayer1Hover, 1) || "transparent"
|
property color colBackground: ColorUtils.transparentize(Appearance?.colors.colLayer1Hover, 1) || "transparent"
|
||||||
property color colBackgroundHover: Appearance?.colors.colLayer1Hover ?? "#E5DFED"
|
property color colBackgroundHover: Appearance?.colors.colLayer1Hover ?? "#E5DFED"
|
||||||
@@ -197,5 +198,6 @@ Button {
|
|||||||
|
|
||||||
contentItem: StyledText {
|
contentItem: StyledText {
|
||||||
text: root.buttonText
|
text: root.buttonText
|
||||||
|
color: root.buttonTextColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
111
osd/NotificationItem.qml
Normal file
111
osd/NotificationItem.qml
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import Quickshell.Services.Notifications
|
||||||
|
import qs.common
|
||||||
|
import qs.common.widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
required property Notification notif
|
||||||
|
required property real textWidth
|
||||||
|
required property real notificationRounding
|
||||||
|
property real spacing: 8
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
Rectangle {
|
||||||
|
implicitHeight: appTitle.implicitHeight
|
||||||
|
implicitWidth: root.width
|
||||||
|
anchors.margins: Config.options.bar.cornerStyle === 1 ? (Appearance.sizes.hyprlandGapsOut) : 0
|
||||||
|
color: Appearance.m3colors.m3primaryContainer
|
||||||
|
topLeftRadius: root.notificationRounding
|
||||||
|
topRightRadius: root.notificationRounding
|
||||||
|
RowLayout {
|
||||||
|
spacing: 0 // For some reason, adding a spacing of just the value will not work properly
|
||||||
|
IconImage {
|
||||||
|
visible: root.notif.appIcon.length > 0
|
||||||
|
id: appIcon
|
||||||
|
source: Quickshell.iconPath(root.notif.appIcon)
|
||||||
|
width: appTitle.height - root.spacing
|
||||||
|
height: appTitle.height - root.spacing
|
||||||
|
Layout.leftMargin: root.spacing / 2
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
// app title
|
||||||
|
id: appTitle
|
||||||
|
text: root.notif.appName
|
||||||
|
color: Appearance.m3colors.m3onPrimaryContainer
|
||||||
|
Layout.leftMargin: root.spacing / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
visible: notifSummary.visible || notifBody.visible
|
||||||
|
implicitHeight: body.implicitHeight
|
||||||
|
implicitWidth: root.width
|
||||||
|
anchors.margins: Config.options.bar.cornerStyle === 1 ? (Appearance.sizes.hyprlandGapsOut) : 0
|
||||||
|
color: Appearance.colors.colLayer2
|
||||||
|
bottomLeftRadius: root.notificationRounding
|
||||||
|
bottomRightRadius: root.notificationRounding
|
||||||
|
ColumnLayout {
|
||||||
|
id: body
|
||||||
|
spacing: root.spacing
|
||||||
|
Text {
|
||||||
|
visible: root.notif.summary.length > 0
|
||||||
|
Layout.leftMargin: root.spacing
|
||||||
|
Layout.rightMargin: root.spacing
|
||||||
|
id: notifSummary
|
||||||
|
text: root.notif.summary
|
||||||
|
color: Appearance.colors.colOnLayer2
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
visible: root.notif.body.length > 0
|
||||||
|
Layout.leftMargin: root.spacing
|
||||||
|
Layout.rightMargin: root.spacing
|
||||||
|
Layout.preferredWidth: textWidth
|
||||||
|
id: notifBody
|
||||||
|
text: root.notif.body
|
||||||
|
color: Appearance.colors.colOnLayer2
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
maximumLineCount: 4
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
id: actionLayer
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: root.spacing
|
||||||
|
Layout.rightMargin: root.spacing
|
||||||
|
Layout.bottomMargin: root.spacing
|
||||||
|
spacing: root.spacing
|
||||||
|
RippleButton {
|
||||||
|
buttonText: "Dismiss"
|
||||||
|
colBackground: Appearance.m3colors.m3primaryContainer
|
||||||
|
releaseAction: root.notif.dismiss
|
||||||
|
buttonRadius: root.notificationRounding
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.notif.actions
|
||||||
|
RippleButton {
|
||||||
|
buttonText: modelData.text
|
||||||
|
buttonTextColor: Appearance.m3colors.m3onTertiaryContainer
|
||||||
|
colBackground: Appearance.m3colors.m3tertiaryContainer
|
||||||
|
releaseAction: modelData.invoke
|
||||||
|
buttonRadius: root.notificationRounding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
osd/NotificationPanel.qml
Normal file
69
osd/NotificationPanel.qml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Services.Notifications
|
||||||
|
import qs
|
||||||
|
import qs.common
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: root
|
||||||
|
property bool visible: false
|
||||||
|
property int panelWidth: 350
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: notificationPanelLoader
|
||||||
|
active: GlobalStates.notificationPanelOpen
|
||||||
|
/**
|
||||||
|
onActiveChanged: {
|
||||||
|
if (!notificationPanelLoader.active & NotificationServer.amountNotifications == 0) {
|
||||||
|
GlobalStates.notificationPanelOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
|
||||||
|
sourceComponent: PanelWindow {
|
||||||
|
id: notificationPanelRoot
|
||||||
|
visible: true
|
||||||
|
|
||||||
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
exclusiveZone: 0
|
||||||
|
|
||||||
|
implicitWidth: root.panelWidth
|
||||||
|
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
right: true
|
||||||
|
bottom: true
|
||||||
|
}
|
||||||
|
margins {
|
||||||
|
top: Config.options.bar.height
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: Config.options.bar.cornerStyle === 1 ? (Appearance.sizes.hyprlandGapsOut) : 0
|
||||||
|
}
|
||||||
|
color: Config.options.bar.showBackground ? Appearance.colors.colLayer1 : "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: notifs
|
||||||
|
anchors.margins: 4
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
Repeater {
|
||||||
|
model: NotificationService.notifications
|
||||||
|
NotificationItem {
|
||||||
|
required property Notification modelData
|
||||||
|
notif: modelData
|
||||||
|
textWidth: root.panelWidth - 14
|
||||||
|
notificationRounding: Appearance.rounding.unsharpenmore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user