This commit is contained in:
2026-02-09 00:09:29 -08:00
parent add0b3d66f
commit 925b01939c
7 changed files with 270 additions and 125 deletions

View File

@@ -13,9 +13,7 @@ PanelWindow {
id: launcher
function close() {
visible = false
list.visible = false
searchInput.text = ""
exitAnim.start();
}
function open() {
visible = true
@@ -358,6 +356,45 @@ PanelWindow {
width: 24
height: 24
}
property var progress
}
transform: Translate {
NumberAnimation on x {
running: launcher.visible
duration: 200
from: launcher.implicitWidth/6
to: 0
easing.type: Easing.OutQuart
}
NumberAnimation on x {
running: exitAnim.running
duration: 200
from: 0
to: launcher.implicitWidth/6
easing.type: Easing.InCubic
}
}
NumberAnimation on opacity {
running: launcher.visible
from: 0
to: 1
duration: 150
}
SequentialAnimation on opacity {
id: exitAnim
running: false
PauseAnimation { duration: 50 }
NumberAnimation {
from: 1
to: 0
duration: 150
}
onFinished: {
launcher.visible = false
list.visible = false
searchInput.text = ""
}
}
}
}

View File

@@ -2,6 +2,7 @@ import Quickshell
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "NotificationBox.qml"
PanelWindow {
id: root
@@ -11,7 +12,7 @@ PanelWindow {
bottom: true
}
visible: false
exclusiveZone: 1
exclusionMode: ExclusionMode.Normal
implicitWidth: 500
color: "transparent"
@@ -58,7 +59,6 @@ PanelWindow {
anchors {
right: parent.right
top: parent.top
bottom: parent.bottom
topMargin: 14
rightMargin: 16
}
@@ -91,69 +91,49 @@ PanelWindow {
fill: parent
topMargin: 48
}
model: root.tracked
spacing: 10
add: Transition { NumberAnimation {
property: "translateX"
from: root.width
to: 0
duration: 300
easing.type: Easing.OutBack
easing.overshoot: 0.7
}}
remove: Transition { NumberAnimation {
property: "translateX"
from: 0
to: root.width
duration: 150
easing.type: Easing.InQuint
}}
displaced: Transition { NumberAnimation {
property: "y"
duration: 300
easing.type: Easing.InOutCubic
}}
model: root.tracked
delegate: Button {
anchors {
left: parent.left
right: parent.right
margins: 12
}
height: notifContent.childrenRect.height + 32
Image {
id: notifIcon
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: 12
}
width: 40
height: 40
source: Quickshell.iconPath(modelData.appIcon, true)
}
Column {
id: notifContent
height: notifBox.height
background: NotificationBox {
id: notifBox
notification: modelData
anchors {
left: parent.left
right: parent.right
top: parent.top
topMargin: 16
leftMargin: 16 + (notifIcon.source == "" ? 0 : 44)
rightMargin: 16
leftMargin: 12
rightMargin: 12
}
spacing: 6
Text {
anchors {
left: parent.left
right: parent.right
}
color: "white"
font.family: "Comfortaa"
font.pixelSize: 16
text: modelData.summary
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: 2
}
Text {
anchors {
left: parent.left
right: parent.right
}
color: "white"
font.family: "Comfortaa"
font.pixelSize: 12
text: modelData.body
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: 4
}
}
background: Rectangle {
color: "#333"
radius: 12
}
onClicked: modelData.tracked = false
property real translateX: 0
transform: Translate { x: translateX }
}
}
transform: Translate {

View File

@@ -2,6 +2,7 @@ import Quickshell
import Quickshell.Services.Notifications
import QtQuick
import QtQuick.Effects
import "./NotificationBox.qml"
PanelWindow {
id: root
@@ -20,10 +21,8 @@ PanelWindow {
Component {
id: notifPopup
Rectangle {
id: notifRect
required property var modelData
NotificationBox {
id: notifBox
y: {
let res = 0;
for (let i = 0; notifsList.children[i] && notifsList.children[i] != this; i++) {
@@ -35,67 +34,12 @@ PanelWindow {
duration: 300
easing.type: Easing.InOutCubic
}}
property bool exiting: false
width: parent?.width ?? 0
height: notifContent.childrenRect.height + 32
radius: 20
color: "#181818"
RectangularShadow {
z: -1
anchors.fill: parent
blur: 12
radius: parent.radius
}
Image {
id: notifIcon
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: 12
}
width: 40
height: 40
source: Quickshell.iconPath(modelData.appIcon, true)
}
Column {
id: notifContent
anchors {
left: parent.left
right: parent.right
top: parent.top
topMargin: 16
leftMargin: 16 + (notifIcon.source == "" ? 0 : 44)
rightMargin: 16
}
spacing: 6
Text {
anchors {
left: parent.left
right: parent.right
}
color: "white"
font.family: "Comfortaa"
font.pixelSize: 16
text: modelData.summary
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: 2
}
Text {
anchors {
left: parent.left
right: parent.right
}
color: "white"
font.family: "Comfortaa"
font.pixelSize: 12
text: modelData.body
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: 4
}
}
NumberAnimation on x {
running: root.visible
from: root.width
@@ -116,7 +60,7 @@ PanelWindow {
root.visible = false
root.implicitHeight = 200;
}
notifRect.destroy();
notifBox.destroy();
}
}
Timer {
@@ -147,6 +91,6 @@ PanelWindow {
function notify(notif) {
if (notif.lastGeneration) return
root.visible = true;
notifPopup.createObject(notifsList, {modelData: notif});
notifPopup.createObject(notifsList, {notification: notif});
}
}

91
NotificationBox.qml Normal file
View File

@@ -0,0 +1,91 @@
import Quickshell
import Quickshell.Services.Notifications
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
Rectangle {
id: notifRect
required property var notification
property bool exiting: false
width: parent?.width ?? 0
height: notifContent.childrenRect.height + 32
radius: 20
color: "#181818"
Image {
id: notifIcon
visible: false
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: 12
}
width: 40
height: 40
source: notification?.image ?? source
layer.enabled: true
}
Rectangle {
id: iconMask
antialiasing: true
layer.enabled: true
visible: false
anchors.fill: notifIcon
layer.smooth: true
radius: 8
}
MultiEffect {
anchors.fill: notifIcon
source: notifIcon
maskEnabled: true
maskSource: iconMask
maskThresholdMin: 0.5
maskSpreadAtMin: 1
}
Column {
id: notifContent
anchors {
left: parent.left
right: parent.right
top: parent.top
topMargin: 16
leftMargin: 16 + (notifIcon.source == "" ? 0 : 44)
rightMargin: 16
}
spacing: 6
Text {
anchors {
left: parent.left
right: parent.right
}
color: "white"
font.family: "Comfortaa"
font.pixelSize: 16
text: notification?.summary ?? text
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: 2
}
Text {
anchors {
left: parent.left
right: parent.right
}
color: "white"
font.family: "Comfortaa"
font.pixelSize: 12
text: notification?.body ?? text
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: 4
}
}
Timer {
running: notification?.expireTimeout > 0
interval: (notification?.expireTimeout > 0) ? notification?.expireTimeout : 0
onTriggered: notification.tracked = false
}
}

89
Wall.qml Normal file
View File

@@ -0,0 +1,89 @@
import Quickshell
import Quickshell.Io
import QtQuick
import QtQuick.Effects
Variants {
model: Quickshell.screens
PanelWindow {
anchors {
top: true
right: true
bottom: true
left: true
}
aboveWindows: false
property var modelData
screen: modelData
color: "#222222"
RectangularShadow {
anchors.fill: imageWrapper
transform: imageWrapper.transform
radius: roundMask.radius
blur: 30
spread: 10
color: "#000000"
}
Item {
id: imageWrapper
anchors.fill: parent
layer.enabled: true
Image {
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: {
const _source = path.text()
return _source.substring(0, _source.length - 1)
}
}
transform: [Scale {
origin {x: width/2; y: height/2}
xScale: 0.8
yScale: xScale
NumberAnimation on xScale {
id: scaleAnim
running: false
to: 1
duration: 800
easing.type: Easing.InOutCubic
}
}, Translate {
NumberAnimation on y {
from: 100
to: 0
duration: 500
easing.type: Easing.OutQuint
onFinished: scaleAnim.start()
}
}]
layer.effect: MultiEffect {
maskSource: roundMask
maskEnabled: true
}
NumberAnimation on opacity {
from: 0
to: 1
duration: 250
}
}
Rectangle {
id: roundMask
visible: false
antialiasing: true
anchors.fill: imageWrapper
radius: 40
layer.enabled: true
NumberAnimation on radius {
running: scaleAnim.running
to: 0
duration: 800
}
}
FileView {
id: path
path: Qt.resolvedUrl("wall.txt")
}
}
}

View File

@@ -6,13 +6,6 @@ import Quickshell.Services.Notifications
ShellRoot {
id: root
NotificationServer {
id: notificationServer
onNotification: (notif) => {
notif.tracked = true
notifPopup.notify(notif)
}
}
readonly property var font: {
family: "comfortaa"
}
@@ -27,8 +20,18 @@ ShellRoot {
Osu.IpcToggle {
target: "notifications"
item: Osu.NotifCenter {
id: notifCenter
tracked: notificationServer.trackedNotifications
}
}
Osu.Notifs { id: notifPopup }
Osu.Wall {}
Osu.NotifPopup { id: notifPopup }
NotificationServer {
id: notificationServer
imageSupported: true
onNotification: (notif) => {
notif.tracked = true
if (!notifCenter.visible) notifPopup.notify(notif)
}
}
}

1
wall.txt Normal file
View File

@@ -0,0 +1 @@
/home/spingus/Pictures/Wallpapers/osu-light-2.jpg