mirror of
https://github.com/belsabbagh/dotfiles.git
synced 2026-04-11 09:36:46 +00:00
quickshell and hyprland additions
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
import qs.config
|
||||
import qs.modules.components
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Wayland
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property bool startAnim: false
|
||||
property string title: "No Title"
|
||||
property string body: "No content"
|
||||
property var rawNotif: null
|
||||
property bool tracked: false
|
||||
property string image: ""
|
||||
property var buttons: [
|
||||
{ label: "Okay!", onClick: () => console.log("Okay") }
|
||||
]
|
||||
|
||||
opacity: tracked ? 1 : (startAnim ? 1 : 0)
|
||||
Behavior on opacity {
|
||||
enabled: Config.runtime.appearance.animations.enabled
|
||||
NumberAnimation {
|
||||
duration: Metrics.chronoDuration("small")
|
||||
easing.type: Easing.InOutExpo
|
||||
}
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
radius: Metrics.radius("large")
|
||||
|
||||
property bool hovered: mouseHandler.containsMouse
|
||||
property bool clicked: mouseHandler.containsPress
|
||||
color: hovered ? (clicked ? Appearance.m3colors.m3surfaceContainerHigh : Appearance.m3colors.m3surfaceContainerLow) : Appearance.m3colors.m3surface
|
||||
Behavior on color {
|
||||
enabled: Config.runtime.appearance.animations.enabled
|
||||
ColorAnimation {
|
||||
duration: Metrics.chronoDuration("small")
|
||||
easing.type: Easing.InOutExpo
|
||||
}
|
||||
}
|
||||
implicitHeight: Math.max(content.implicitHeight + 30, 80)
|
||||
|
||||
RowLayout {
|
||||
id: content
|
||||
anchors.fill: parent
|
||||
anchors.margins: Metrics.margin(10)
|
||||
spacing: Metrics.spacing(10)
|
||||
|
||||
ClippingRectangle {
|
||||
width: 50
|
||||
height: 50
|
||||
radius: Metrics.radius("large")
|
||||
clip: true
|
||||
color: root.image === "" ? Appearance.m3colors.m3surfaceContainer : "transparent"
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: root.image
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
smooth: true
|
||||
}
|
||||
MaterialSymbol {
|
||||
icon: "chat"
|
||||
color: Appearance.m3colors.m3onSurfaceVariant
|
||||
anchors.centerIn: parent
|
||||
visible: root.image === ""
|
||||
iconSize: Metrics.iconSize(22)
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: root.title
|
||||
font.bold: true
|
||||
font.pixelSize: Metrics.fontSize(18)
|
||||
wrapMode: Text.Wrap
|
||||
color: Appearance.m3colors.m3onSurface
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.body.length > 123 ? root.body.substr(0, 120) + "..." : root.body
|
||||
visible: root.body.length > 0
|
||||
font.pixelSize: Metrics.fontSize(12)
|
||||
color: Appearance.m3colors.m3onSurfaceVariant
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.buttons.length > 1
|
||||
Layout.preferredHeight: 40
|
||||
Layout.fillWidth: true
|
||||
spacing: Metrics.spacing(10)
|
||||
|
||||
Repeater {
|
||||
model: buttons
|
||||
|
||||
StyledButton {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 30
|
||||
implicitWidth: 0
|
||||
text: modelData.label
|
||||
base_bg: index !== 0
|
||||
? Appearance.m3colors.m3secondaryContainer
|
||||
: Appearance.m3colors.m3primary
|
||||
|
||||
base_fg: index !== 0
|
||||
? Appearance.m3colors.m3onSecondaryContainer
|
||||
: Appearance.m3colors.m3onPrimary
|
||||
onClicked: modelData.onClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseHandler
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
visible: root.buttons.length === 0 || root.buttons.length === 1
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (root.buttons.length === 1 && root.buttons[0].onClick) {
|
||||
root.buttons[0].onClick()
|
||||
root.rawNotif?.notification.dismiss()
|
||||
} else if (root.buttons.length === 0) {
|
||||
console.log("[Notification] Dismissed a notification with no action.")
|
||||
root.rawNotif.notification.tracked = false
|
||||
root.rawNotif.popup = false
|
||||
root.rawNotif?.notification.dismiss()
|
||||
} else {
|
||||
console.log("[Notification] Dismissed a notification with multiple actions.")
|
||||
root.rawNotif?.notification.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
startAnim = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Notifications
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Widgets
|
||||
import qs.services
|
||||
import qs.config
|
||||
import qs.modules.components
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
|
||||
property int innerSpacing: Metrics.spacing(10)
|
||||
|
||||
PanelWindow {
|
||||
id: window
|
||||
|
||||
implicitWidth: 520
|
||||
visible: true
|
||||
color: "transparent"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Normal
|
||||
WlrLayershell.namespace: "nucleus:notification"
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: Config.runtime.notifications.position.endsWith("left")
|
||||
bottom: true
|
||||
right: Config.runtime.notifications.position.endsWith("right")
|
||||
}
|
||||
|
||||
Item {
|
||||
id: notificationList
|
||||
|
||||
anchors.leftMargin: 0
|
||||
anchors.topMargin: Metrics.margin(10)
|
||||
anchors.rightMargin: 0
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Rectangle {
|
||||
id: bgRectangle
|
||||
|
||||
layer.enabled: true
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Metrics.margin(20)
|
||||
anchors.rightMargin: Metrics.margin(20)
|
||||
anchors.right: parent.right
|
||||
height: window.mask.height > 0 ? window.mask.height + 40 : 0
|
||||
color: Appearance.m3colors.m3background
|
||||
radius: Metrics.radius("large")
|
||||
|
||||
layer.effect: MultiEffect {
|
||||
shadowEnabled: true
|
||||
shadowOpacity: 1
|
||||
shadowColor: Appearance.m3colors.m3shadow
|
||||
shadowBlur: 1
|
||||
shadowScale: 1
|
||||
}
|
||||
|
||||
Behavior on height {
|
||||
enabled: Config.runtime.appearance.animations.enabled
|
||||
NumberAnimation {
|
||||
duration: Metrics.chronoDuration("small")
|
||||
easing.type: Easing.InOutExpo
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Item {
|
||||
id: notificationColumn
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Repeater {
|
||||
id: rep
|
||||
|
||||
model: (!Config.runtime.notifications.doNotDisturb && Config.runtime.notifications.enabled) ? NotifServer.popups : []
|
||||
|
||||
NotificationChild {
|
||||
id: child
|
||||
|
||||
width: notificationColumn.width - 80
|
||||
anchors.horizontalCenter: notificationColumn.horizontalCenter
|
||||
y: {
|
||||
var pos = 0;
|
||||
for (let i = 0; i < index; i++) {
|
||||
var prev = rep.itemAt(i);
|
||||
if (prev)
|
||||
pos += prev.height + root.innerSpacing;
|
||||
|
||||
}
|
||||
return pos + 20;
|
||||
}
|
||||
Component.onCompleted: {
|
||||
if (!modelData.shown)
|
||||
modelData.shown = true;
|
||||
|
||||
}
|
||||
title: modelData.summary
|
||||
body: modelData.body
|
||||
image: modelData.image || modelData.appIcon
|
||||
rawNotif: modelData
|
||||
tracked: modelData.shown
|
||||
buttons: modelData.actions.map((action) => {
|
||||
return ({
|
||||
"label": action.text,
|
||||
"onClick": () => {
|
||||
return action.invoke();
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
Behavior on y {
|
||||
enabled: Config.runtime.appearance.animations.enabled
|
||||
NumberAnimation {
|
||||
duration: Metrics.chronoDuration("normal")
|
||||
easing.type: Easing.InOutExpo
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mask: Region {
|
||||
width: window.width
|
||||
height: {
|
||||
var total = 0;
|
||||
for (let i = 0; i < rep.count; i++) {
|
||||
var child = rep.itemAt(i);
|
||||
if (child)
|
||||
total += child.height + (i < rep.count - 1 ? root.innerSpacing : 0);
|
||||
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user