1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

DankOSD and fix exit animations

This commit is contained in:
bbedward
2025-08-20 10:41:55 -04:00
parent 9b7a41e282
commit 1f24ad51f8
10 changed files with 445 additions and 694 deletions

View File

@@ -1,242 +0,0 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
PanelWindow {
id: root
property var modelData
property bool brightnessPopupVisible: false
property var brightnessDebounceTimer
function show() {
root.brightnessPopupVisible = true;
// Update slider to current device brightness when showing
if (BrightnessService.brightnessAvailable)
brightnessSlider.value = BrightnessService.brightnessLevel;
hideTimer.restart();
}
function resetHideTimer() {
if (root.brightnessPopupVisible)
hideTimer.restart();
}
screen: modelData
visible: brightnessPopupVisible
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
color: "transparent"
anchors {
top: true
left: true
right: true
bottom: true
}
Timer {
id: hideTimer
interval: 3000
repeat: false
onTriggered: {
if (!brightnessPopup.containsMouse)
root.brightnessPopupVisible = false;
else
hideTimer.restart();
}
}
Connections {
function onBrightnessChanged() {
root.show();
}
target: BrightnessService
}
Rectangle {
id: brightnessPopup
property bool containsMouse: popupMouseArea.containsMouse
width: Math.min(260, Screen.width - Theme.spacingM * 2)
height: brightnessContent.height + Theme.spacingS * 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.spacingM
color: Theme.popupBackground()
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 1
opacity: root.brightnessPopupVisible ? 1 : 0
scale: root.brightnessPopupVisible ? 1 : 0.9
layer.enabled: true
Column {
id: brightnessContent
anchors.centerIn: parent
width: parent.width - Theme.spacingS * 2
spacing: Theme.spacingXS
Item {
property int gap: Theme.spacingS
width: parent.width
height: 40
Rectangle {
width: Theme.iconSize
height: Theme.iconSize
radius: Theme.iconSize / 2
color: "transparent"
x: parent.gap
anchors.verticalCenter: parent.verticalCenter
DankIcon {
anchors.centerIn: parent
name: {
const deviceInfo = BrightnessService.getCurrentDeviceInfo();
if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc")
return "brightness_medium";
else if (deviceInfo.name.includes("kbd"))
return "keyboard";
else
return "lightbulb";
}
size: Theme.iconSize
color: Theme.primary
}
}
DankSlider {
id: brightnessSlider
width: parent.width - Theme.iconSize - parent.gap * 3
height: 40
x: parent.gap * 2 + Theme.iconSize
anchors.verticalCenter: parent.verticalCenter
minimum: 1
maximum: 100
enabled: BrightnessService.brightnessAvailable
showValue: true
unit: "%"
Component.onCompleted: {
if (BrightnessService.brightnessAvailable)
value = BrightnessService.brightnessLevel;
}
onSliderValueChanged: function(newValue) {
if (BrightnessService.brightnessAvailable) {
brightnessDebounceTimer.pendingValue = newValue;
brightnessDebounceTimer.restart();
root.resetHideTimer();
}
}
onSliderDragFinished: function(finalValue) {
if (BrightnessService.brightnessAvailable) {
brightnessDebounceTimer.stop();
BrightnessService.setBrightnessInternal(finalValue, BrightnessService.lastIpcDevice);
}
}
Connections {
function onBrightnessChanged() {
if (!brightnessSlider.pressed)
brightnessSlider.value = BrightnessService.brightnessLevel;
}
function onDeviceSwitched() {
if (!brightnessSlider.pressed)
brightnessSlider.value = BrightnessService.brightnessLevel;
}
target: BrightnessService
}
}
}
}
MouseArea {
id: popupMouseArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
propagateComposedEvents: true
z: -1
}
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 4
shadowBlur: 0.8
shadowColor: Qt.rgba(0, 0, 0, 0.3)
shadowOpacity: 0.3
}
transform: Translate {
y: root.brightnessPopupVisible ? 0 : 20
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on transform {
PropertyAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
brightnessDebounceTimer: Timer {
property int pendingValue: 0
interval: {
const deviceInfo = BrightnessService.getCurrentDeviceInfo()
return (deviceInfo && deviceInfo.class === "ddc") ? 200 : 50
}
repeat: false
onTriggered: {
BrightnessService.setBrightnessInternal(pendingValue, BrightnessService.lastIpcDevice);
}
}
mask: Region {
item: brightnessPopup
}
}

View File

@@ -1,117 +0,0 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
PanelWindow {
id: root
property var modelData
property bool inhibitorPopupVisible: false
function show() {
root.inhibitorPopupVisible = true
hideTimer.restart()
}
screen: modelData
visible: inhibitorPopupVisible
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
color: "transparent"
anchors {
top: true
left: true
right: true
bottom: true
}
Timer {
id: hideTimer
interval: 2000
repeat: false
onTriggered: {
root.inhibitorPopupVisible = false
}
}
Connections {
function onInhibitorChanged() {
root.show()
}
target: IdleInhibitorService
}
Rectangle {
id: inhibitorPopup
width: Theme.iconSize + Theme.spacingS * 2
height: Theme.iconSize + Theme.spacingS * 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.spacingM
color: Theme.popupBackground()
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
Theme.outline.b, 0.08)
border.width: 1
opacity: root.inhibitorPopupVisible ? 1 : 0
scale: root.inhibitorPopupVisible ? 1 : 0.9
layer.enabled: true
DankIcon {
id: inhibitorContent
anchors.centerIn: parent
name: IdleInhibitorService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
size: Theme.iconSize
color: IdleInhibitorService.idleInhibited ? Theme.primary : Theme.outline
}
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 4
shadowBlur: 0.8
shadowColor: Qt.rgba(0, 0, 0, 0.3)
shadowOpacity: 0.3
}
transform: Translate {
y: root.inhibitorPopupVisible ? 0 : 20
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on transform {
PropertyAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
mask: Region {
item: inhibitorPopup
}
}

View File

@@ -1,119 +0,0 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
PanelWindow {
id: root
property var modelData
property bool micPopupVisible: false
function show() {
root.micPopupVisible = true
hideTimer.restart()
}
screen: modelData
visible: micPopupVisible
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
color: "transparent"
anchors {
top: true
left: true
right: true
bottom: true
}
Timer {
id: hideTimer
interval: 2000
repeat: false
onTriggered: {
root.micPopupVisible = false
}
}
Connections {
function onMicMuteChanged() {
root.show()
}
target: AudioService
}
Rectangle {
id: micPopup
width: Theme.iconSize + Theme.spacingS * 2
height: Theme.iconSize + Theme.spacingS * 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.spacingM
color: Theme.popupBackground()
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
Theme.outline.b, 0.08)
border.width: 1
opacity: root.micPopupVisible ? 1 : 0
scale: root.micPopupVisible ? 1 : 0.9
layer.enabled: true
DankIcon {
id: micContent
anchors.centerIn: parent
name: AudioService.source && AudioService.source.audio
&& AudioService.source.audio.muted ? "mic_off" : "mic"
size: Theme.iconSize
color: AudioService.source && AudioService.source.audio
&& AudioService.source.audio.muted ? Theme.error : Theme.primary
}
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 4
shadowBlur: 0.8
shadowColor: Qt.rgba(0, 0, 0, 0.3)
shadowOpacity: 0.3
}
transform: Translate {
y: root.micPopupVisible ? 0 : 20
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on transform {
PropertyAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
mask: Region {
item: micPopup
}
}

View File

@@ -0,0 +1,130 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
DankOSD {
id: root
osdWidth: Math.min(260, Screen.width - Theme.spacingM * 2)
osdHeight: 40 + Theme.spacingS * 2
autoHideInterval: 3000
enableMouseInteraction: true
property var brightnessDebounceTimer: Timer {
property int pendingValue: 0
interval: {
const deviceInfo = BrightnessService.getCurrentDeviceInfo()
return (deviceInfo && deviceInfo.class === "ddc") ? 200 : 50
}
repeat: false
onTriggered: {
BrightnessService.setBrightnessInternal(pendingValue, BrightnessService.lastIpcDevice)
}
}
function resetHideTimer() {
if (root.shouldBeVisible)
root.hideTimer.restart()
}
Connections {
target: BrightnessService
function onBrightnessChanged() {
root.show()
}
}
content: Item {
anchors.fill: parent
Item {
property int gap: Theme.spacingS
anchors.centerIn: parent
width: parent.width - Theme.spacingS * 2
height: 40
Rectangle {
width: Theme.iconSize
height: Theme.iconSize
radius: Theme.iconSize / 2
color: "transparent"
x: parent.gap
anchors.verticalCenter: parent.verticalCenter
DankIcon {
anchors.centerIn: parent
name: {
const deviceInfo = BrightnessService.getCurrentDeviceInfo()
if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc")
return "brightness_medium"
else if (deviceInfo.name.includes("kbd"))
return "keyboard"
else
return "lightbulb"
}
size: Theme.iconSize
color: Theme.primary
}
}
DankSlider {
id: brightnessSlider
width: parent.width - Theme.iconSize - parent.gap * 3
height: 40
x: parent.gap * 2 + Theme.iconSize
anchors.verticalCenter: parent.verticalCenter
minimum: 1
maximum: 100
enabled: BrightnessService.brightnessAvailable
showValue: true
unit: "%"
Component.onCompleted: {
if (BrightnessService.brightnessAvailable)
value = BrightnessService.brightnessLevel
}
onSliderValueChanged: function(newValue) {
if (BrightnessService.brightnessAvailable) {
root.brightnessDebounceTimer.pendingValue = newValue
root.brightnessDebounceTimer.restart()
root.resetHideTimer()
}
}
onSliderDragFinished: function(finalValue) {
if (BrightnessService.brightnessAvailable) {
root.brightnessDebounceTimer.stop()
BrightnessService.setBrightnessInternal(finalValue, BrightnessService.lastIpcDevice)
}
}
Connections {
target: BrightnessService
function onBrightnessChanged() {
if (!brightnessSlider.pressed)
brightnessSlider.value = BrightnessService.brightnessLevel
}
function onDeviceSwitched() {
if (!brightnessSlider.pressed)
brightnessSlider.value = BrightnessService.brightnessLevel
}
}
}
}
}
onOsdShown: {
if (BrightnessService.brightnessAvailable && contentLoader.item) {
let slider = contentLoader.item.children[0].children[1]
if (slider)
slider.value = BrightnessService.brightnessLevel
}
}
}

View File

@@ -0,0 +1,27 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
DankOSD {
id: root
osdWidth: Theme.iconSize + Theme.spacingS * 2
osdHeight: Theme.iconSize + Theme.spacingS * 2
autoHideInterval: 2000
enableMouseInteraction: false
Connections {
target: IdleInhibitorService
function onInhibitorChanged() {
root.show()
}
}
content: DankIcon {
anchors.centerIn: parent
name: IdleInhibitorService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
size: Theme.iconSize
color: IdleInhibitorService.idleInhibited ? Theme.primary : Theme.outline
}
}

View File

@@ -0,0 +1,27 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
DankOSD {
id: root
osdWidth: Theme.iconSize + Theme.spacingS * 2
osdHeight: Theme.iconSize + Theme.spacingS * 2
autoHideInterval: 2000
enableMouseInteraction: false
Connections {
target: AudioService
function onMicMuteChanged() {
root.show()
}
}
content: DankIcon {
anchors.centerIn: parent
name: AudioService.source && AudioService.source.audio && AudioService.source.audio.muted ? "mic_off" : "mic"
size: Theme.iconSize
color: AudioService.source && AudioService.source.audio && AudioService.source.audio.muted ? Theme.error : Theme.primary
}
}

114
Modules/OSD/VolumeOSD.qml Normal file
View File

@@ -0,0 +1,114 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
DankOSD {
id: root
osdWidth: Math.min(260, Screen.width - Theme.spacingM * 2)
osdHeight: 40 + Theme.spacingS * 2
autoHideInterval: 3000
enableMouseInteraction: true
function resetHideTimer() {
if (root.shouldBeVisible)
root.hideTimer.restart()
}
Connections {
target: AudioService
function onVolumeChanged() {
root.show()
}
function onSinkChanged() {
if (root.shouldBeVisible)
root.show()
}
}
content: Item {
anchors.fill: parent
Item {
property int gap: Theme.spacingS
anchors.centerIn: parent
width: parent.width - Theme.spacingS * 2
height: 40
Rectangle {
width: Theme.iconSize
height: Theme.iconSize
radius: Theme.iconSize / 2
color: "transparent"
x: parent.gap
anchors.verticalCenter: parent.verticalCenter
DankIcon {
anchors.centerIn: parent
name: AudioService.sink && AudioService.sink.audio && AudioService.sink.audio.muted ? "volume_off" : "volume_up"
size: Theme.iconSize
color: muteButton.containsMouse ? Theme.primary : Theme.surfaceText
}
MouseArea {
id: muteButton
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
AudioService.toggleMute()
root.resetHideTimer()
}
}
}
DankSlider {
id: volumeSlider
width: parent.width - Theme.iconSize - parent.gap * 3
height: 40
x: parent.gap * 2 + Theme.iconSize
anchors.verticalCenter: parent.verticalCenter
minimum: 0
maximum: 100
enabled: AudioService.sink && AudioService.sink.audio
showValue: true
unit: "%"
Component.onCompleted: {
if (AudioService.sink && AudioService.sink.audio)
value = Math.round(AudioService.sink.audio.volume * 100)
}
onSliderValueChanged: function(newValue) {
if (AudioService.sink && AudioService.sink.audio) {
AudioService.sink.audio.volume = newValue / 100
root.resetHideTimer()
}
}
Connections {
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
function onVolumeChanged() {
if (volumeSlider && !volumeSlider.pressed)
volumeSlider.value = Math.round(AudioService.sink.audio.volume * 100)
}
}
}
}
}
onOsdShown: {
if (AudioService.sink && AudioService.sink.audio && contentLoader.item) {
let slider = contentLoader.item.children[0].children[1]
if (slider)
slider.value = Math.round(AudioService.sink.audio.volume * 100)
}
}
}

View File

@@ -1,212 +0,0 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
PanelWindow {
id: root
property var modelData
property bool volumePopupVisible: false
function show() {
root.volumePopupVisible = true
hideTimer.restart()
}
function resetHideTimer() {
if (root.volumePopupVisible)
hideTimer.restart()
}
screen: modelData
visible: volumePopupVisible
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
color: "transparent"
anchors {
top: true
left: true
right: true
bottom: true
}
Timer {
id: hideTimer
interval: 3000
repeat: false
onTriggered: {
if (!volumePopup.containsMouse)
root.volumePopupVisible = false
else
hideTimer.restart()
}
}
Connections {
function onVolumeChanged() {
root.show()
}
function onSinkChanged() {
if (root.volumePopupVisible)
root.show()
}
target: AudioService
}
Rectangle {
id: volumePopup
property bool containsMouse: popupMouseArea.containsMouse
width: Math.min(260, Screen.width - Theme.spacingM * 2)
height: volumeContent.height + Theme.spacingS * 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.spacingM
color: Theme.popupBackground()
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
Theme.outline.b, 0.08)
border.width: 1
opacity: root.volumePopupVisible ? 1 : 0
scale: root.volumePopupVisible ? 1 : 0.9
layer.enabled: true
Column {
id: volumeContent
anchors.centerIn: parent
width: parent.width - Theme.spacingS * 2
spacing: Theme.spacingXS
Item {
property int gap: Theme.spacingS
width: parent.width
height: 40
Rectangle {
width: Theme.iconSize
height: Theme.iconSize
radius: Theme.iconSize / 2
color: "transparent"
x: parent.gap
anchors.verticalCenter: parent.verticalCenter
DankIcon {
anchors.centerIn: parent
name: AudioService.sink && AudioService.sink.audio
&& AudioService.sink.audio.muted ? "volume_off" : "volume_up"
size: Theme.iconSize
color: muteButton.containsMouse ? Theme.primary : Theme.surfaceText
}
MouseArea {
id: muteButton
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
AudioService.toggleMute()
root.resetHideTimer()
}
}
}
DankSlider {
id: volumeSlider
width: parent.width - Theme.iconSize - parent.gap * 3
height: 40
x: parent.gap * 2 + Theme.iconSize
anchors.verticalCenter: parent.verticalCenter
minimum: 0
maximum: 100
enabled: AudioService.sink && AudioService.sink.audio
showValue: true
unit: "%"
Component.onCompleted: {
if (AudioService.sink && AudioService.sink.audio)
value = Math.round(
AudioService.sink.audio.volume * 100)
}
onSliderValueChanged: function (newValue) {
if (AudioService.sink && AudioService.sink.audio) {
AudioService.sink.audio.volume = newValue / 100
root.resetHideTimer()
}
}
Connections {
function onVolumeChanged() {
volumeSlider.value = Math.round(
AudioService.sink.audio.volume * 100)
}
target: AudioService.sink
&& AudioService.sink.audio ? AudioService.sink.audio : null
}
}
}
}
MouseArea {
id: popupMouseArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
propagateComposedEvents: true
z: -1
}
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 4
shadowBlur: 0.8
shadowColor: Qt.rgba(0, 0, 0, 0.3)
shadowOpacity: 0.3
}
transform: Translate {
y: root.volumePopupVisible ? 0 : 20
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on transform {
PropertyAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
mask: Region {
item: volumePopup
}
}

142
Widgets/DankOSD.qml Normal file
View File

@@ -0,0 +1,142 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import Quickshell.Wayland
import qs.Common
PanelWindow {
id: root
property alias content: contentLoader.sourceComponent
property alias contentLoader: contentLoader
property var modelData
property bool shouldBeVisible: false
property int autoHideInterval: 2000
property bool enableMouseInteraction: false
property real osdWidth: Theme.iconSize + Theme.spacingS * 2
property real osdHeight: Theme.iconSize + Theme.spacingS * 2
property int animationDuration: Theme.mediumDuration
property var animationEasing: Theme.emphasizedEasing
signal osdShown
signal osdHidden
function show() {
closeTimer.stop()
shouldBeVisible = true
visible = true
hideTimer.restart()
osdShown()
}
function hide() {
shouldBeVisible = false
closeTimer.restart()
}
function resetHideTimer() {
if (shouldBeVisible && enableMouseInteraction)
hideTimer.restart()
}
screen: modelData
visible: shouldBeVisible
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
color: "transparent"
anchors {
top: true
left: true
right: true
bottom: true
}
Timer {
id: hideTimer
interval: autoHideInterval
repeat: false
onTriggered: {
if (!enableMouseInteraction || !osdContainer.containsMouse) {
hide()
} else {
hideTimer.restart()
}
}
}
Timer {
id: closeTimer
interval: animationDuration + 50
onTriggered: {
if (!shouldBeVisible) {
visible = false
osdHidden()
}
}
}
Rectangle {
id: osdContainer
property bool containsMouse: enableMouseInteraction && mouseArea.containsMouse
width: osdWidth
height: osdHeight
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.spacingM
color: Theme.popupBackground()
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 1
opacity: shouldBeVisible ? 1 : 0
scale: shouldBeVisible ? 1 : 0.9
layer.enabled: true
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: enableMouseInteraction
acceptedButtons: Qt.NoButton
propagateComposedEvents: true
z: -1
}
Loader {
id: contentLoader
anchors.fill: parent
active: root.visible
asynchronous: false
}
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 4
shadowBlur: 0.8
shadowColor: Qt.rgba(0, 0, 0, 0.3)
shadowOpacity: 0.3
}
Behavior on opacity {
NumberAnimation {
duration: animationDuration
easing.type: animationEasing
}
}
Behavior on scale {
NumberAnimation {
duration: animationDuration
easing.type: animationEasing
}
}
}
mask: Region {
item: osdContainer
}
}

View File

@@ -6,6 +6,7 @@ import Quickshell.Widgets
import qs.Modals
import qs.Modules
import qs.Modules.AppDrawer
import qs.Modules.OSD
import qs.Modules.CentcomCenter
import qs.Modules.ControlCenter
import qs.Modules.ControlCenter.Network
@@ -252,7 +253,7 @@ ShellRoot {
Variants {
model: Quickshell.screens
delegate: VolumePopup {
delegate: VolumeOSD {
modelData: item
}
}
@@ -260,7 +261,7 @@ ShellRoot {
Variants {
model: Quickshell.screens
delegate: MicMutePopup {
delegate: MicMuteOSD {
modelData: item
}
}
@@ -268,7 +269,7 @@ ShellRoot {
Variants {
model: Quickshell.screens
delegate: BrightnessPopup {
delegate: BrightnessOSD {
modelData: item
}
}
@@ -276,7 +277,7 @@ ShellRoot {
Variants {
model: Quickshell.screens
delegate: IdleInhibitorPopup {
delegate: IdleInhibitorOSD {
modelData: item
}
}