move notifications to top overlay

This commit is contained in:
lucy 2026-09-04 13:21:47 +02:00
commit 021c82f438
12 changed files with 106 additions and 172 deletions

View file

@ -1 +1 @@
/nix/store/yj22sprk8zwdhbc8jcf5nqbkc2vwd5yz-home-manager-files/.config/quickshell/Colors.js /nix/store/l7wgb12q1ackaqs9v9g79p2pr567dsgk-home-manager-files/.config/quickshell/Colors.js

View file

@ -8,10 +8,10 @@ import "Colors.js" as Colors
Singleton { Singleton {
id: root id: root
readonly property color accent: base0D readonly property color accent: base0D
readonly property color rootBarColor: base01 readonly property color rootBarColor: base00
readonly property color barBg: Qt.rgba(rootBarColor.r,rootBarColor.g,rootBarColor.b,Config.opacity) readonly property color barBg: Qt.rgba(rootBarColor.r,rootBarColor.g,rootBarColor.b,Config.opacity)
readonly property color moduleBg: base02 readonly property color moduleBg: base02
readonly property color activeModuleBg: base03 readonly property color activeModuleBg: base04
readonly property color text: base05 readonly property color text: base05
readonly property color base00: Colors.colors.base00 readonly property color base00: Colors.colors.base00
readonly property color base01: Colors.colors.base01 readonly property color base01: Colors.colors.base01

View file

@ -0,0 +1,20 @@
pragma Singleton
import Quickshell
import Quickshell.Wayland
Singleton {
id: root
// Screen des gerade fokussierten Fensters, oder null wenn keins fokussiert ist.
// Reagiert sowohl auf Fokuswechsel als auch darauf, dass das fokussierte
// Fenster auf einen anderen Monitor wandert.
readonly property ShellScreen liveScreen: ToplevelManager.activeToplevel?.screens?.[0] ?? null
property ShellScreen focusedScreen: Quickshell.screens[0] ?? null
onLiveScreenChanged: {
if (liveScreen)
root.focusedScreen = liveScreen;
}
}

View file

@ -2,7 +2,7 @@ import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import qs.settings import qs.settings
import qs.modules.applets import qs.widgets
import qs import qs
Variants { Variants {
@ -19,13 +19,13 @@ Variants {
color: 'transparent' color: 'transparent'
implicitHeight: Config.cfg.bar.height implicitHeight: Config.cfg.bar.height
margins.top: Config.cfg.bar.floating ? 10 : 0 margins.top: Config.cfg.bar.floating ?? 10
margins.left: Config.cfg.bar.floating ? 10 : 0 margins.left: Config.cfg.bar.floating ?? 10
margins.right: Config.cfg.bar.floating ? 10 : 0 margins.right: Config.cfg.bar.floating ?? 10
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: Colors.barBg color: Colors.barBg
radius: Config.cfg.bar.floating ? Config.cfg.appearance.rounding : 0 radius: Config.cfg.bar.floating ?? Config.cfg.appearance.rounding
RowLayout { RowLayout {
anchors.leftMargin: 4 anchors.leftMargin: 4
anchors.left: parent.left anchors.left: parent.left
@ -33,7 +33,9 @@ Variants {
Ws { Ws {
barScreen: root.modelData barScreen: root.modelData
} }
ActiveWindow {screen: root.modelData} ActiveWindow {
screen: root.modelData
}
} }
RowLayout { RowLayout {
anchors.centerIn: parent anchors.centerIn: parent
@ -43,15 +45,46 @@ Variants {
anchors.rightMargin: 4 anchors.rightMargin: 4
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
Mpris {} Mpris {
Bat {} id: mpris
Tray {} }
WallPickerButton {barScreen: root.modelData} StyledText {
text: "|"
visible: mpris.visible
}
Bat {
id: bat
Pw { }
StyledText {
text: "|"
visible: bat.visible
}
Tray {
id: tray
}
StyledText {
text: "|"
visible: tray.visible
}
WallPickerButton {
id: wpButton
barScreen: root.modelData barScreen: root.modelData
} }
Netstatus {} StyledText {
text: "|"
}
Pw {
id: pw
barScreen: root.modelData
}
StyledText {
text: "|"
}
Netstatus {
id: net
}
} }
} }
} }

View file

@ -11,25 +11,17 @@ BarComponent {
required property ShellScreen barScreen required property ShellScreen barScreen
implicitWidth: wsLayout.implicitWidth implicitWidth: wsLayout.implicitWidth
RowLayout { RowLayout {
id: wsLayout id: wsLayout
anchors.centerIn: parent anchors.centerIn: parent
spacing: 0 spacing: 4
Repeater { Repeater {
model: WindowManager.screenProjection(root.barScreen).windowsets model: WindowManager.screenProjection(root.barScreen).windowsets
delegate: BarComponent { delegate: BarComponent {
id: wsContainer id: wsContainer
required property var modelData required property var modelData
visible: modelData.shouldDisplay implicitWidth: root.implicitHeight / 1.5
implicitWidth: modelData.active ? root.implicitHeight * 2.2 : root.implicitHeight implicitHeight: implicitWidth
color: modelData.active ? Colors.accent : 'transparent' color: modelData.active ? Colors.accent : 'transparent'
Behavior on implicitWidth {
PropertyAnimation {
duration: 350
easing.type: Easing.InOutBack
easing.overshoot: 1.2
}
}
MouseArea { MouseArea {
id: clickHandler id: clickHandler
anchors.fill: parent anchors.fill: parent
@ -41,7 +33,8 @@ BarComponent {
id: wsText id: wsText
anchors.centerIn: parent anchors.centerIn: parent
text: parent.modelData.name text: parent.modelData.name
color: parent.modelData.active ? Colors.base00 : Colors.text color: parent.modelData.shouldDisplay ? parent.modelData.active ? Colors.base00 : Colors.base05 : Colors.base03
font.bold: parent.modelData.active
} }
} }
} }

View file

@ -1,38 +0,0 @@
pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import Quickshell.Wayland
import qs.settings
import Quickshell.Hyprland
Variants {
model: Quickshell.screens
delegate: WlrLayershell {
required property ShellScreen modelData
id: notiPopup
exclusionMode: ExclusionMode.Ignore
layer: WlrLayer.Overlay
screen: modelData
anchors {
top: true
right: true
}
margins.top: Config.cfg.bar.height + 8 + (Config.cfg.bar.floating ? 10 : 0)
margins.right: 8
implicitHeight: notiList.contentHeight
implicitWidth: modelData.width / 6
color: 'transparent'
visible: NotiServer.notifications.values.length > 0
ListView {
id: notiList
anchors.fill: parent
model: NotiServer.notifications
spacing: 6
delegate: NotiCard {
required property var modelData
nScreen: notiPopup.screen
notification: modelData
}
}
}
}

View file

@ -5,7 +5,7 @@ import QtQuick
Singleton { Singleton {
id: root id: root
property alias notifications: server.trackedNotifications property list<Notification> notifications: server.trackedNotifications.values
NotificationServer { NotificationServer {
id: server id: server
imageSupported: true imageSupported: true

View file

@ -1,101 +0,0 @@
import QtQuick
import Quickshell
import Quickshell.Wayland
import qs.modules.Services
import qs.modules.applets
import qs.settings
Variants {
model: Quickshell.screens
delegate: PanelWindow {
id: root
required property ShellScreen modelData
property bool shown: WidgetTracker.current !== "" && WidgetTracker.screen === modelData
screen: modelData
anchors {
top: true
left: true
bottom: true
right: true
}
exclusionMode: ExclusionMode.Ignore
color: 'transparent'
visible: true
mask: Region {
item: root.shown ? dismisser : null
}
WlrLayershell.keyboardFocus: shown ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
Item {
anchors.fill: parent
focus: true
Keys.onEscapePressed: event => {
WidgetTracker.close();
event.accepted = true;
}
VolPopup {
id: volPopup
z: 1
property bool shown: root.shown && WidgetTracker.current === "volume"
opacity: shown ? 1 : 0
visible: opacity > 0
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: Config.cfg.bar.floating ? Config.cfg.bar.height + 20 : Config.cfg.bar.height
anchors.rightMargin: 10
Behavior on opacity {
NumberAnimation {
duration: 140
easing.type: Easing.OutCubic
}
}
transform: Translate {
y: volPopup.shown ? 0 : -12
Behavior on y {
NumberAnimation {
duration: 140
easing.type: Easing.OutCubic
}
}
}
}
WallPicker {
id: wallpapers
z: 1
property bool shown: root.shown && WidgetTracker.current === "wallpapers"
opacity: shown ? 1 : 0
visible: opacity > 0
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 20
implicitWidth: 1000
implicitHeight: 200
Behavior on opacity {
NumberAnimation {
duration: 200
easing.type: Easing.OutCubic
}
}
transform: Translate {
y: wallpapers.shown ? 0 : 12
Behavior on y {
NumberAnimation {
duration: 200
easing.type: Easing.OutCubic
}
}
}
}
MouseArea {
id: dismisser
z: 0
anchors.fill: parent
acceptedButtons: Qt.LeftButton
onClicked: WidgetTracker.close()
}
}
}
}

View file

@ -4,6 +4,7 @@ import Quickshell.Wayland
import qs.modules.Services import qs.modules.Services
import qs.modules.applets import qs.modules.applets
import qs.settings import qs.settings
import qs.modules.notifications
Variants { Variants {
model: Quickshell.screens model: Quickshell.screens
@ -23,8 +24,13 @@ Variants {
color: 'transparent' color: 'transparent'
visible: true visible: true
mask: Region { mask: Region {
Region {
item: notiList.visible ? notiList : null
}
Region {
item: root.shown ? dismisser : null item: root.shown ? dismisser : null
} }
}
WlrLayershell.keyboardFocus: shown ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None WlrLayershell.keyboardFocus: shown ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
Item { Item {
anchors.fill: parent anchors.fill: parent
@ -41,7 +47,7 @@ Variants {
visible: opacity > 0 visible: opacity > 0
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: Config.cfg.bar.floating ? Config.cfg.bar.height + 20 : Config.cfg.bar.height anchors.topMargin: Config.cfg.bar.floating ? Config.cfg.bar.height + 20 : Config.cfg.bar.height + 10
anchors.rightMargin: 10 anchors.rightMargin: 10
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
@ -59,6 +65,27 @@ Variants {
} }
} }
} }
ListView {
id: notiList
z: 2
anchors.top: parent.top
anchors.right: parent.right
anchors.topMargin: Config.cfg.bar.height + 10 + (Config.cfg.bar.floating ? 10 : 0)
anchors.rightMargin: 10
width: root.modelData.width / 6
height: contentHeight
interactive: false
visible: count > 0 && Compositor.focusedScreen === root.modelData
model: NotiServer.notifications
spacing: 6
delegate: NotiCard {
required property var modelData
nScreen: root.modelData
notification: modelData
}
}
WallPicker { WallPicker {
id: wallpapers id: wallpapers
z: 1 z: 1

View file

@ -6,12 +6,12 @@
"rounding": 16 "rounding": 16
}, },
"bar": { "bar": {
"floating": true, "floating": false,
"height": 34, "height": 34,
"opacity": 1 "opacity": 1
}, },
"wallpaper": { "wallpaper": {
"wallDir": "/home/lucy/.walls/", "wallDir": "/home/lucy/.walls/",
"wallpaper": "/home/lucy/.walls/faris.png" "wallpaper": "/home/lucy/.walls/walkingcastle.png"
} }
} }

View file

@ -8,7 +8,6 @@ import qs.modules.Services
ShellRoot { ShellRoot {
Bar {} Bar {}
NotiPopup {}
Bottom {} Bottom {}
Top {} Top {}
} }

View file

@ -5,7 +5,8 @@ import qs.settings
Rectangle { Rectangle {
property bool active: false property bool active: false
color: active ? Colors.activeModuleBg : Colors.moduleBg color: active ? Colors.activeModuleBg : Colors.barBg
implicitHeight: Config.cfg.bar.height - 8 implicitHeight: Config.cfg.bar.height - 8
radius: Config.cfg.appearance.rounding radius: Config.cfg.appearance.rounding
} }