privacy module: screenshare and microphone indicators with glow + pulse
This commit is contained in:
parent
0568f71d1b
commit
87b7bb00d0
3 changed files with 85 additions and 0 deletions
|
|
@ -57,6 +57,7 @@ PanelWindow {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: M.Theme.barSpacing
|
spacing: M.Theme.barSpacing
|
||||||
|
|
||||||
|
M.Privacy {}
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
borderColor: M.Theme.base0D
|
borderColor: M.Theme.base0D
|
||||||
M.Clock {
|
M.Clock {
|
||||||
|
|
|
||||||
83
modules/Privacy.qml
Normal file
83
modules/Privacy.qml
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
import Quickshell.Services.Pipewire
|
||||||
|
import "." as M
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: root
|
||||||
|
spacing: M.Theme.moduleSpacing
|
||||||
|
|
||||||
|
readonly property bool _screenShare: {
|
||||||
|
if (!Pipewire.nodes) return false;
|
||||||
|
for (const node of Pipewire.nodes.values) {
|
||||||
|
if (!node.isStream) continue;
|
||||||
|
const mc = node.properties?.["media.class"] ?? "";
|
||||||
|
if (mc.includes("Video")) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property bool _audioIn: {
|
||||||
|
if (!Pipewire.nodes) return false;
|
||||||
|
for (const node of Pipewire.nodes.values) {
|
||||||
|
if (!node.isStream) continue;
|
||||||
|
const mc = node.properties?.["media.class"] ?? "";
|
||||||
|
if (mc === "Stream/Input/Audio") return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: root._screenShare || root._audioIn
|
||||||
|
|
||||||
|
// Screenshare indicator
|
||||||
|
Text {
|
||||||
|
visible: root._screenShare
|
||||||
|
text: "\uF03D"
|
||||||
|
color: M.Theme.base08
|
||||||
|
font.pixelSize: M.Theme.fontSize + 2
|
||||||
|
font.family: M.Theme.iconFontFamily
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
shadowEnabled: true
|
||||||
|
shadowColor: M.Theme.base08
|
||||||
|
shadowBlur: 0.8
|
||||||
|
shadowVerticalOffset: 0
|
||||||
|
shadowHorizontalOffset: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation on opacity {
|
||||||
|
running: root._screenShare
|
||||||
|
loops: Animation.Infinite
|
||||||
|
NumberAnimation { to: 0.4; duration: 600; easing.type: Easing.InOutQuad }
|
||||||
|
NumberAnimation { to: 1; duration: 600; easing.type: Easing.InOutQuad }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Microphone indicator
|
||||||
|
Text {
|
||||||
|
visible: root._audioIn
|
||||||
|
text: "\uF130"
|
||||||
|
color: M.Theme.base0B
|
||||||
|
font.pixelSize: M.Theme.fontSize + 2
|
||||||
|
font.family: M.Theme.iconFontFamily
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
shadowEnabled: true
|
||||||
|
shadowColor: M.Theme.base0B
|
||||||
|
shadowBlur: 0.8
|
||||||
|
shadowVerticalOffset: 0
|
||||||
|
shadowHorizontalOffset: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation on opacity {
|
||||||
|
running: root._audioIn
|
||||||
|
loops: Animation.Infinite
|
||||||
|
NumberAnimation { to: 0.4; duration: 600; easing.type: Easing.InOutQuad }
|
||||||
|
NumberAnimation { to: 1; duration: 600; easing.type: Easing.InOutQuad }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -34,3 +34,4 @@ PowerProfile 1.0 PowerProfile.qml
|
||||||
IdleInhibitor 1.0 IdleInhibitor.qml
|
IdleInhibitor 1.0 IdleInhibitor.qml
|
||||||
Notifications 1.0 Notifications.qml
|
Notifications 1.0 Notifications.qml
|
||||||
Power 1.0 Power.qml
|
Power 1.0 Power.qml
|
||||||
|
Privacy 1.0 Privacy.qml
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue