summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/shell/quickshell
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/gkleen@sif/shell/quickshell')
-rw-r--r--accounts/gkleen@sif/shell/quickshell/Bar.qml23
-rw-r--r--accounts/gkleen@sif/shell/quickshell/BatteryWidget.qml61
-rw-r--r--accounts/gkleen@sif/shell/quickshell/BrightnessOSD.qml117
-rw-r--r--accounts/gkleen@sif/shell/quickshell/BrightnessWidget.qml33
-rw-r--r--accounts/gkleen@sif/shell/quickshell/MaterialDesignIcon.qml17
-rw-r--r--accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml5
-rw-r--r--accounts/gkleen@sif/shell/quickshell/PrivacyWidget.qml49
-rw-r--r--accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml68
-rw-r--r--accounts/gkleen@sif/shell/quickshell/Services/Privacy.qml63
-rw-r--r--accounts/gkleen@sif/shell/quickshell/SystemTray.qml34
-rw-r--r--accounts/gkleen@sif/shell/quickshell/UnixIPC.qml59
-rw-r--r--accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml68
-rw-r--r--accounts/gkleen@sif/shell/quickshell/shell.qml3
13 files changed, 561 insertions, 39 deletions
diff --git a/accounts/gkleen@sif/shell/quickshell/Bar.qml b/accounts/gkleen@sif/shell/quickshell/Bar.qml
index 3652af54..d52740b2 100644
--- a/accounts/gkleen@sif/shell/quickshell/Bar.qml
+++ b/accounts/gkleen@sif/shell/quickshell/Bar.qml
@@ -1,7 +1,6 @@
1import Quickshell 1import Quickshell
2import QtQuick 2import QtQuick
3 3
4
5PanelWindow { 4PanelWindow {
6 id: bar 5 id: bar
7 6
@@ -64,25 +63,39 @@ PanelWindow {
64 anchors.verticalCenter: parent.verticalCenter 63 anchors.verticalCenter: parent.verticalCenter
65 spacing: 0 64 spacing: 0
66 65
67 PipewireWidget {} 66 PrivacyWidget {
67 id: privacy
68 }
68 69
69 Item { 70 Item {
71 enabled: privacy.active
70 height: parent.height 72 height: parent.height
71 width: 4 73 width: 8
72 } 74 }
73 75
74 SystemTray {} 76 BatteryWidget {}
77
78 Item {
79 height: parent.height
80 width: 8
81 }
82
83 BrightnessWidget {}
75 84
76 Item { 85 Item {
77 height: parent.height 86 height: parent.height
78 width: 4 87 width: 4
79 } 88 }
80 89
90 PipewireWidget {}
91
92 SystemTray {}
93
81 KeyboardLayout {} 94 KeyboardLayout {}
82 95
83 Item { 96 Item {
84 height: parent.height 97 height: parent.height
85 width: 4 98 width: 8 - 4
86 } 99 }
87 100
88 Clock {} 101 Clock {}
diff --git a/accounts/gkleen@sif/shell/quickshell/BatteryWidget.qml b/accounts/gkleen@sif/shell/quickshell/BatteryWidget.qml
new file mode 100644
index 00000000..896440f1
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/BatteryWidget.qml
@@ -0,0 +1,61 @@
1import QtQuick
2import Quickshell
3import Quickshell.Widgets
4import Quickshell.Services.UPower
5
6Item {
7 id: root
8
9 height: parent.height
10 width: batteryIcon.width
11 anchors.verticalCenter: parent.verticalCenter
12
13 property var batteryDevice: Array.from(UPower.devices.values).find(dev => dev.isLaptopBattery)
14
15 WrapperMouseArea {
16 id: widgetMouseArea
17
18 anchors.fill: parent
19
20 hoverEnabled: true
21
22 Item {
23 anchors.fill: parent
24
25 MaterialDesignIcon {
26 id: batteryIcon
27
28 implicitSize: 14
29 anchors.centerIn: parent
30
31 icon: {
32 if (!root.batteryDevice?.ready)
33 return "battery-unknown";
34
35 if (root.batteryDevice.state == UPowerDeviceState.FullyCharged)
36 return "power-plug-battery";
37
38 const perdec = 10 * Math.max(1, Math.ceil(root.batteryDevice.percentage * 10));
39 if (root.batteryDevice.state == UPowerDeviceState.Charging)
40 return `battery-charging-${perdec}`;
41 if (perdec == 100)
42 return "battery";
43 return `battery-${perdec}`;
44 }
45 color: {
46 if (!root.batteryDevice?.ready)
47 return "#555";
48
49 if (root.batteryDevice.state != UPowerDeviceState.FullyCharged && root.batteryDevice.state != UPowerDeviceState.Charging && root.batteryDevice.timeToEmpty < 20 * 60)
50 return "#f2201f";
51 if (root.batteryDevice.state != UPowerDeviceState.FullyCharged && root.batteryDevice.state != UPowerDeviceState.Charging && root.batteryDevice.timeToEmpty < 40 * 60)
52 return "#f28a21";
53 if (root.batteryDevice.state != UPowerDeviceState.FullyCharged)
54 return "#fff";
55 return "#555";
56 }
57 }
58
59 }
60 }
61}
diff --git a/accounts/gkleen@sif/shell/quickshell/BrightnessOSD.qml b/accounts/gkleen@sif/shell/quickshell/BrightnessOSD.qml
new file mode 100644
index 00000000..a432179e
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/BrightnessOSD.qml
@@ -0,0 +1,117 @@
1import QtQuick
2import QtQuick.Layouts
3import Quickshell
4import Quickshell.Widgets
5import qs.Services
6
7Scope {
8 id: root
9
10 property bool show: false
11 property bool inhibited: true
12
13 Connections {
14 target: Brightness
15
16 function onCurrBrightnessChanged() {
17 root.show = true;
18 hideTimer.restart();
19 }
20 }
21
22 onShowChanged: {
23 if (show)
24 hideTimer.restart();
25 }
26
27 Timer {
28 id: hideTimer
29 interval: 1000
30 onTriggered: root.show = false
31 }
32
33 Timer {
34 id: startInhibit
35 interval: 100
36 running: true
37 onTriggered: {
38 root.show = false;
39 root.inhibited = false;
40 }
41 }
42
43 LazyLoader {
44 active: root.show && !root.inhibited
45
46 Variants {
47 model: Quickshell.screens
48
49 delegate: Scope {
50 id: screenScope
51
52 required property var modelData
53
54 PanelWindow {
55 id: window
56
57 screen: screenScope.modelData
58
59 anchors.top: true
60 margins.top: screen.height / 2 - 50 + 3.5
61 exclusiveZone: 0
62 exclusionMode: ExclusionMode.Ignore
63
64 implicitWidth: 400
65 implicitHeight: 50
66
67 mask: Region {}
68
69 color: "transparent"
70
71 Rectangle {
72 anchors.fill: parent
73 color: Qt.rgba(0, 0, 0, 0.75)
74 }
75
76 RowLayout {
77 id: layout
78
79 anchors.centerIn: parent
80
81 height: 50 - 8*2
82 width: 400 - 8*2
83
84 MaterialDesignIcon {
85 id: volumeIcon
86
87 implicitWidth: parent.height
88 implicitHeight: parent.height
89
90 icon: `brightness-${Math.min(7, Math.floor(Brightness.currBrightness * 7) + 1)}`
91 }
92
93 Rectangle {
94 Layout.fillWidth: true
95
96 implicitHeight: 10
97
98 color: "#50ffffff"
99
100 Rectangle {
101 anchors {
102 left: parent.left
103 top: parent.top
104 bottom: parent.bottom
105 }
106
107 color: "white"
108
109 implicitWidth: parent.width * Brightness.currBrightness
110 }
111 }
112 }
113 }
114 }
115 }
116 }
117}
diff --git a/accounts/gkleen@sif/shell/quickshell/BrightnessWidget.qml b/accounts/gkleen@sif/shell/quickshell/BrightnessWidget.qml
new file mode 100644
index 00000000..664b28e2
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/BrightnessWidget.qml
@@ -0,0 +1,33 @@
1import QtQuick
2import Quickshell
3import Quickshell.Widgets
4import qs.Services
5
6Item {
7 height: parent.height
8 width: brightnessIcon.width
9 anchors.verticalCenter: parent.verticalCenter
10
11 WrapperMouseArea {
12 id: widgetMouseArea
13
14 anchors.fill: parent
15
16 property real sensitivity: (1 / 50) / 120
17 onWheel: event => Brightness.currBrightness += event.angleDelta.y * sensitivity
18
19 Item {
20 anchors.fill: parent
21
22 MaterialDesignIcon {
23 id: brightnessIcon
24
25 implicitSize: 14
26 anchors.centerIn: parent
27
28 icon: `brightness-${Math.min(7, Math.floor(Brightness.currBrightness * 7) + 1)}`
29 color: "#555"
30 }
31 }
32 }
33}
diff --git a/accounts/gkleen@sif/shell/quickshell/MaterialDesignIcon.qml b/accounts/gkleen@sif/shell/quickshell/MaterialDesignIcon.qml
index 387dcc8b..155a009e 100644
--- a/accounts/gkleen@sif/shell/quickshell/MaterialDesignIcon.qml
+++ b/accounts/gkleen@sif/shell/quickshell/MaterialDesignIcon.qml
@@ -2,15 +2,26 @@ import QtQuick
2import QtQuick.Effects 2import QtQuick.Effects
3 3
4Item { 4Item {
5 id: icon 5 id: root
6 6
7 required property string icon 7 required property string icon
8 property color color: "white" 8 property color color: "white"
9 9
10 property real implicitSize: 0
11
12 readonly property real actualSize: Math.min(root.width, root.height)
13
14 implicitWidth: root.implicitSize
15 implicitHeight: root.implicitSize
16
10 Image { 17 Image {
11 id: sourceImage 18 id: sourceImage
12 source: "file://" + @mdi@ + "/svg/" + icon.icon + ".svg" 19 source: "file://" + @mdi@ + "/svg/" + root.icon + ".svg"
13 anchors.fill: parent 20 anchors.fill: parent
21 fillMode: Image.PreserveAspectFit
22
23 sourceSize.width: root.actualSize
24 sourceSize.height: root.actualSize
14 25
15 layer.enabled: true 26 layer.enabled: true
16 layer.effect: MultiEffect { 27 layer.effect: MultiEffect {
@@ -18,7 +29,7 @@ Item {
18 29
19 brightness: 1 30 brightness: 1
20 colorization: 1 31 colorization: 1
21 colorizationColor: icon.color 32 colorizationColor: root.color
22 } 33 }
23 } 34 }
24} 35}
diff --git a/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml b/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml
index 5bf0ac3a..007ce100 100644
--- a/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml
+++ b/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml
@@ -27,7 +27,7 @@ Item {
27 Pipewire.defaultAudioSink.audio.muted = !Pipewire.defaultAudioSink.audio.muted; 27 Pipewire.defaultAudioSink.audio.muted = !Pipewire.defaultAudioSink.audio.muted;
28 } 28 }
29 29
30 property real sensitivity: (1 / 20) / 120 30 property real sensitivity: (1 / 40) / 120
31 onWheel: event => { 31 onWheel: event => {
32 if (!Pipewire.defaultAudioSink) 32 if (!Pipewire.defaultAudioSink)
33 return; 33 return;
@@ -50,8 +50,7 @@ Item {
50 MaterialDesignIcon { 50 MaterialDesignIcon {
51 id: volumeIcon 51 id: volumeIcon
52 52
53 width: 16 53 implicitSize: 14
54 height: 16
55 anchors.centerIn: parent 54 anchors.centerIn: parent
56 55
57 icon: { 56 icon: {
diff --git a/accounts/gkleen@sif/shell/quickshell/PrivacyWidget.qml b/accounts/gkleen@sif/shell/quickshell/PrivacyWidget.qml
new file mode 100644
index 00000000..bb02528b
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/PrivacyWidget.qml
@@ -0,0 +1,49 @@
1import QtQuick
2import QtQuick.Layouts
3import Quickshell
4import Quickshell.Widgets
5import qs.Services
6
7Item {
8 height: parent.height
9 width: layout.childrenRect.width
10 anchors.verticalCenter: parent.verticalCenter
11
12 readonly property bool active: Boolean(Privacy.activeItems)
13
14 RowLayout {
15 id: layout
16
17 anchors.fill: parent
18
19 spacing: 8
20
21 Repeater {
22 model: Privacy.activeItems
23
24 Item {
25 id: privacyItem
26
27 required property var modelData;
28
29 height: parent.height
30 width: icon.width
31
32 MaterialDesignIcon {
33 id: icon
34
35 implicitSize: 14
36 anchors.centerIn: parent
37
38 icon: {
39 if (privacyItem.modelData == Privacy.Item.Microphone)
40 return "microphone";
41 if (privacyItem.modelData == Privacy.Item.Screensharing)
42 return "monitor-share";
43 }
44 color: "#f2201f"
45 }
46 }
47 }
48 }
49}
diff --git a/accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml b/accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml
new file mode 100644
index 00000000..87c7c05b
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml
@@ -0,0 +1,68 @@
1pragma Singleton
2
3import QtQml
4import Quickshell
5import Quickshell.Io
6import Custom as Custom
7
8Singleton {
9 id: root
10
11 property string subsystem: "backlight"
12 property string device: "intel_backlight"
13
14 property real currBrightness
15 property real exponent: 4
16
17 function calcCurrBrightness() {
18 if (!currFile.loaded || !maxFile.loaded)
19 return undefined;
20 const curr = Number(currFile.text());
21 const max = Number(maxFile.text());
22 const val = Math.pow(curr / max, 1 / root.exponent);
23 return val;
24 }
25
26 Component.onCompleted: root.currBrightness = root.calcCurrBrightness()
27 Connections {
28 target: currFile
29 function onLoaded() { root.currBrightness = root.calcCurrBrightness(); }
30 }
31 Connections {
32 target: maxFile
33 function onLoaded() { root.currBrightness = root.calcCurrBrightness(); }
34 }
35
36 onCurrBrightnessChanged: {
37 root.currBrightness = Math.max(0, Math.min(1, root.currBrightness));
38
39 const prev = root.calcCurrBrightness();
40 if (typeof prev === 'undefined' || Math.abs(root.currBrightness - prev) < 0.01)
41 return;
42
43 const max = Number(maxFile.text());
44 const actual = Number(currFile.text());
45 let curr = Math.max(0, Math.min(max, Math.pow(root.currBrightness, root.exponent) * max));
46 if (Math.round(curr) == actual && curr < actual)
47 curr = Math.max(0, actual - 1);
48 else if (Math.round(curr) == actual && curr > actual)
49 curr = Math.min(max, actual + 1);
50 // root.currBrightness = Math.pow(curr / max, 1 / root.exponent);
51 Custom.Systemd.setBrightness(root.subsystem, root.device, Math.round(curr));
52 }
53
54 FileView {
55 id: currFile
56 path: `/sys/class/${root.subsystem}/${root.device}/brightness`
57 blockAllReads: true
58 watchChanges: true
59 onFileChanged: reload()
60 }
61 FileView {
62 id: maxFile
63 path: `/sys/class/${root.subsystem}/${root.device}/max_brightness`
64 blockAllReads: true
65 watchChanges: true
66 onFileChanged: reload()
67 }
68}
diff --git a/accounts/gkleen@sif/shell/quickshell/Services/Privacy.qml b/accounts/gkleen@sif/shell/quickshell/Services/Privacy.qml
new file mode 100644
index 00000000..9c813e49
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/Services/Privacy.qml
@@ -0,0 +1,63 @@
1pragma Singleton
2
3import QtQml
4import Quickshell
5import Quickshell.Services.Pipewire
6
7Singleton {
8 id: root
9
10 PwObjectTracker {
11 objects: Pipewire.nodes.values
12 }
13
14 enum Item {
15 Microphone,
16 Screensharing
17 }
18
19 readonly property list<var> activeItems: {
20 var items = [];
21 if (microphoneActive)
22 items.push(Privacy.Item.Microphone);
23 if (screensharingActive)
24 items.push(Privacy.Item.Screensharing);
25 return items;
26 }
27
28 readonly property bool microphoneActive: {
29 if (!Pipewire.ready || !Pipewire.nodes?.values) {
30 return false
31 }
32
33 for (const node of Pipewire.nodes.values) {
34 if (!node || (node.type & PwNodeType.AudioInStream) != PwNodeType.AudioInStream)
35 continue;
36
37 if (node.properties?.["stream.monitor"] === "true")
38 continue;
39
40 if (node.audio?.muted)
41 continue;
42
43 return true;
44 }
45
46 return false;
47 }
48
49 readonly property bool screensharingActive: {
50 if (!Pipewire.ready || !Pipewire.nodes?.values) {
51 return false
52 }
53
54 for (const node of Pipewire.nodes.values) {
55 if (!node || (node.type & PwNodeType.VideoInStream) != PwNodeType.VideoInStream)
56 continue;
57
58 return true;
59 }
60
61 return false;
62 }
63}
diff --git a/accounts/gkleen@sif/shell/quickshell/SystemTray.qml b/accounts/gkleen@sif/shell/quickshell/SystemTray.qml
index 55b1690e..6f70be29 100644
--- a/accounts/gkleen@sif/shell/quickshell/SystemTray.qml
+++ b/accounts/gkleen@sif/shell/quickshell/SystemTray.qml
@@ -47,7 +47,7 @@ Item {
47 return "" 47 return ""
48 } 48 }
49 49
50 width: 16 50 width: icon.width + 6
51 height: parent.height 51 height: parent.height
52 anchors.verticalCenter: parent.verticalCenter 52 anchors.verticalCenter: parent.verticalCenter
53 53
@@ -83,14 +83,24 @@ Item {
83 } 83 }
84 } 84 }
85 85
86 IconImage { 86 Rectangle {
87 anchors.centerIn: parent 87 anchors.fill: parent
88 width: parent.width 88 color: {
89 height: parent.width 89 if (trayItemArea.containsMouse)
90 source: trayItemWrapper.iconSource 90 return "#33808080";
91 asynchronous: true 91 return "transparent";
92 smooth: true 92 }
93 mipmap: true 93
94 IconImage {
95 id: icon
96
97 anchors.centerIn: parent
98 implicitSize: 16
99 source: trayItemWrapper.iconSource
100 asynchronous: true
101 smooth: true
102 mipmap: true
103 }
94 } 104 }
95 } 105 }
96 106
@@ -116,7 +126,7 @@ Item {
116 color: "black" 126 color: "black"
117 127
118 implicitWidth: Math.max(tooltipTitle.contentWidth, tooltipDescription.contentWidth) + 16 128 implicitWidth: Math.max(tooltipTitle.contentWidth, tooltipDescription.contentWidth) + 16
119 implicitHeight: tooltipTitle.contentHeight + tooltipDescription.contentHeight + 16 129 implicitHeight: (trayItem.tooltipTitle ? tooltipTitle.contentHeight : 0) + (trayItem.tooltipDescription ? tooltipDescription.contentHeight : 0) + 16
120 130
121 WrapperMouseArea { 131 WrapperMouseArea {
122 id: tooltipMouseArea 132 id: tooltipMouseArea
@@ -130,6 +140,8 @@ Item {
130 Text { 140 Text {
131 id: tooltipTitle 141 id: tooltipTitle
132 142
143 enabled: trayItem.tooltipTitle
144
133 font.pointSize: 10 145 font.pointSize: 10
134 font.family: "Fira Sans" 146 font.family: "Fira Sans"
135 font.bold: true 147 font.bold: true
@@ -141,6 +153,8 @@ Item {
141 Text { 153 Text {
142 id: tooltipDescription 154 id: tooltipDescription
143 155
156 enabled: trayItem.tooltipDescription
157
144 font.pointSize: 10 158 font.pointSize: 10
145 font.family: "Fira Sans" 159 font.family: "Fira Sans"
146 color: "white" 160 color: "white"
diff --git a/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml b/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml
new file mode 100644
index 00000000..742ef4f5
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml
@@ -0,0 +1,59 @@
1import Quickshell
2import Quickshell.Io
3import Quickshell.Services.Pipewire
4import qs.Services
5
6Scope {
7 id: root
8
9 SocketServer {
10 active: true
11 path: `${Quickshell.env("XDG_RUNTIME_DIR")}/shell.sock`
12 handler: Socket {
13 parser: SplitParser {
14 onRead: line => {
15 try {
16 const command = JSON.parse(line);
17
18 if (command.Volume)
19 root.onCommandVolume(command.Volume);
20 else if (command.Brightness)
21 root.onCommandBrightness(command.Brightness);
22 else
23 console.warn("UnixIPC: Command not handled:", JSON.stringify(command));
24 } catch (e) {
25 console.warn("UnixIPC: Failed to parse command:", line, e);
26 }
27 }
28 }
29
30 onError: e => {
31 if (e == 1)
32 return;
33 console.warn("QLocalSocket::LocalSocketError", e);
34 }
35 }
36 }
37
38 PwObjectTracker {
39 objects: [ Pipewire.defaultAudioSink, Pipewire.defaultAudioSource ]
40 }
41 function onCommandVolume(command) {
42 if (command.muted === "toggle")
43 Pipewire.defaultAudioSink.audio.muted = !Pipewire.defaultAudioSink.audio.muted;
44 if (command.volume === "up")
45 Pipewire.defaultAudioSink.audio.volume += 0.02;
46 if (command.volume === "down")
47 Pipewire.defaultAudioSink.audio.volume -= 0.02;
48
49 if (command["mic-muted"] === "toggle")
50 Pipewire.defaultAudioSource.audio.muted = !Pipewire.defaultAudioSource.audio.muted;
51 }
52
53 function onCommandBrightness(command) {
54 if (command === "up")
55 Brightness.currBrightness += 0.02
56 if (command === "down")
57 Brightness.currBrightness -= 0.02
58 }
59}
diff --git a/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml b/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml
index 3a78d91b..16fb5dea 100644
--- a/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml
+++ b/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml
@@ -7,23 +7,38 @@ import Quickshell.Widgets
7Scope { 7Scope {
8 id: root 8 id: root
9 9
10 property bool show: false 10 property string show: ""
11 property bool inhibited: true 11 property bool inhibited: true
12 12
13 PwObjectTracker { 13 PwObjectTracker {
14 objects: [ Pipewire.defaultAudioSink ] 14 objects: [ Pipewire.defaultAudioSink, Pipewire.defaultAudioSource ]
15 } 15 }
16 16
17 Connections { 17 Connections {
18 enabled: Pipewire.defaultAudioSink
18 target: Pipewire.defaultAudioSink?.audio 19 target: Pipewire.defaultAudioSink?.audio
19 20
20 function onVolumeChanged() { 21 function onVolumeChanged() {
21 root.show = true; 22 root.show = "sink";
22 hideTimer.reset(); 23 hideTimer.restart();
23 } 24 }
24 function onMutedChanged() { 25 function onMutedChanged() {
25 root.show = true; 26 root.show = "sink";
26 hideTimer.reset(); 27 hideTimer.restart();
28 }
29 }
30
31 Connections {
32 enabled: Pipewire.defaultAudioSource
33 target: Pipewire.defaultAudioSource?.audio
34
35 function onVolumeChanged() {
36 root.show = "source";
37 hideTimer.restart();
38 }
39 function onMutedChanged() {
40 root.show = "source";
41 hideTimer.restart();
27 } 42 }
28 } 43 }
29 44
@@ -34,15 +49,18 @@ Scope {
34 49
35 Timer { 50 Timer {
36 id: hideTimer 51 id: hideTimer
37 interval: 2000 52 interval: 1000
38 onTriggered: root.show = false 53 onTriggered: root.show = ""
39 } 54 }
40 55
41 Timer { 56 Timer {
42 id: startInhibit 57 id: startInhibit
43 interval: 100 58 interval: 100
44 running: true 59 running: true
45 onTriggered: root.inhibited = false; 60 onTriggered: {
61 root.show = "";
62 root.inhibited = false;
63 }
46 } 64 }
47 65
48 LazyLoader { 66 LazyLoader {
@@ -62,8 +80,9 @@ Scope {
62 screen: screenScope.modelData 80 screen: screenScope.modelData
63 81
64 anchors.top: true 82 anchors.top: true
65 margins.top: (screen.height - window.height) / 2 83 margins.top: screen.height / 2 - 50 + 3.5
66 exclusiveZone: 0 84 exclusiveZone: 0
85 exclusionMode: ExclusionMode.Ignore
67 86
68 implicitWidth: 400 87 implicitWidth: 400
69 implicitHeight: 50 88 implicitHeight: 50
@@ -92,13 +111,20 @@ Scope {
92 implicitHeight: parent.height 111 implicitHeight: parent.height
93 112
94 icon: { 113 icon: {
95 if (!Pipewire.defaultAudioSink || Pipewire.defaultAudioSink.audio.muted) 114 if (root.show == "sink") {
96 return "volume-off"; 115 if (!Pipewire.defaultAudioSink || Pipewire.defaultAudioSink.audio.muted)
97 if (Pipewire.defaultAudioSink.audio.volume <= 0.33) 116 return "volume-off";
98 return "volume-low"; 117 if (Pipewire.defaultAudioSink.audio.volume <= 0.33)
99 if (Pipewire.defaultAudioSink.audio.volume <= 0.67) 118 return "volume-low";
100 return "volume-medium"; 119 if (Pipewire.defaultAudioSink.audio.volume <= 0.67)
101 return "volume-high"; 120 return "volume-medium";
121 return "volume-high";
122 } else if (root.show == "source") {
123 if (!Pipewire.defaultAudioSource || Pipewire.defaultAudioSource.audio.muted)
124 return "microphone-off";
125 return "microphone";
126 }
127 return "volume-high";
102 } 128 }
103 } 129 }
104 130
@@ -118,7 +144,13 @@ Scope {
118 144
119 color: Pipewire.defaultAudioSink?.audio.muted ? "#70ffffff" : "white" 145 color: Pipewire.defaultAudioSink?.audio.muted ? "#70ffffff" : "white"
120 146
121 implicitWidth: parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0) 147 implicitWidth: {
148 if (root.show == "sink")
149 return parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0);
150 else if (root.show == "source")
151 return parent.width * (Pipewire.defaultAudioSource?.audio.volume ?? 0);
152 return 0;
153 }
122 } 154 }
123 } 155 }
124 } 156 }
diff --git a/accounts/gkleen@sif/shell/quickshell/shell.qml b/accounts/gkleen@sif/shell/quickshell/shell.qml
index 3657f77f..0fa45f79 100644
--- a/accounts/gkleen@sif/shell/quickshell/shell.qml
+++ b/accounts/gkleen@sif/shell/quickshell/shell.qml
@@ -43,4 +43,7 @@ ShellRoot {
43 Lockscreen {} 43 Lockscreen {}
44 44
45 VolumeOSD {} 45 VolumeOSD {}
46 BrightnessOSD {}
47
48 UnixIPC {}
46} 49}