diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2025-09-10 15:57:26 +0200 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2025-09-10 15:57:26 +0200 |
commit | d20393e077b8d97b18f4a224ddcb20caf6dac23b (patch) | |
tree | 337a8630deecdb50a2c879754e6b34b71575bbe0 /accounts | |
parent | 9fab3828698199718a3d2f2faf8826f77d9258f7 (diff) | |
download | nixos-d20393e077b8d97b18f4a224ddcb20caf6dac23b.tar nixos-d20393e077b8d97b18f4a224ddcb20caf6dac23b.tar.gz nixos-d20393e077b8d97b18f4a224ddcb20caf6dac23b.tar.bz2 nixos-d20393e077b8d97b18f4a224ddcb20caf6dac23b.tar.xz nixos-d20393e077b8d97b18f4a224ddcb20caf6dac23b.zip |
...
Diffstat (limited to 'accounts')
16 files changed, 469 insertions, 90 deletions
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix index 1ff149bc..10b85169 100644 --- a/accounts/gkleen@sif/niri/default.nix +++ b/accounts/gkleen@sif/niri/default.nix | |||
@@ -10,7 +10,6 @@ let | |||
10 | makoctl = lib.getExe' config.services.mako.package "makoctl"; | 10 | makoctl = lib.getExe' config.services.mako.package "makoctl"; |
11 | loginctl = lib.getExe' hostConfig.systemd.package "loginctl"; | 11 | loginctl = lib.getExe' hostConfig.systemd.package "loginctl"; |
12 | systemctl = lib.getExe' hostConfig.systemd.package "systemctl"; | 12 | systemctl = lib.getExe' hostConfig.systemd.package "systemctl"; |
13 | swayosd-client = lib.getExe' config.services.swayosd.package "swayosd-client"; | ||
14 | 13 | ||
15 | focus_or_spawn = pkgs.writeShellApplication { | 14 | focus_or_spawn = pkgs.writeShellApplication { |
16 | name = "focus-or-spawn"; | 15 | name = "focus-or-spawn"; |
@@ -168,7 +167,6 @@ in { | |||
168 | imports = [ | 167 | imports = [ |
169 | ./waybar.nix | 168 | ./waybar.nix |
170 | ./mako.nix | 169 | ./mako.nix |
171 | ./swayosd.nix | ||
172 | ]; | 170 | ]; |
173 | 171 | ||
174 | options = { | 172 | options = { |
@@ -939,15 +937,6 @@ in { | |||
939 | allow-when-locked = true; | 937 | allow-when-locked = true; |
940 | }; | 938 | }; |
941 | 939 | ||
942 | "XF86MonBrightnessUp" = { | ||
943 | action = spawn swayosd-client "--brightness" "raise"; | ||
944 | allow-when-locked = true; | ||
945 | }; | ||
946 | "XF86MonBrightnessDown" = { | ||
947 | action = spawn swayosd-client "--brightness" "lower"; | ||
948 | allow-when-locked = true; | ||
949 | }; | ||
950 | |||
951 | "Mod+Semicolon".action = spawn makoctl "dismiss" "--group"; | 940 | "Mod+Semicolon".action = spawn makoctl "dismiss" "--group"; |
952 | "Mod+Shift+Semicolon".action = spawn makoctl "dismiss" "--all"; | 941 | "Mod+Shift+Semicolon".action = spawn makoctl "dismiss" "--all"; |
953 | "Mod+Period".action = spawn makoctl "menu" "--" (lib.getExe config.programs.fuzzel.package) "--dmenu"; | 942 | "Mod+Period".action = spawn makoctl "menu" "--" (lib.getExe config.programs.fuzzel.package) "--dmenu"; |
@@ -988,6 +977,14 @@ in { | |||
988 | allow-when-locked = true; | 977 | allow-when-locked = true; |
989 | action = shell { Volume."mic-muted" = "toggle"; }; | 978 | action = shell { Volume."mic-muted" = "toggle"; }; |
990 | }; | 979 | }; |
980 | "XF86MonBrightnessUp" = { | ||
981 | action = shell { Brightness = "up"; }; | ||
982 | allow-when-locked = true; | ||
983 | }; | ||
984 | "XF86MonBrightnessDown" = { | ||
985 | action = shell { Brightness = "down"; }; | ||
986 | allow-when-locked = true; | ||
987 | }; | ||
991 | })) | 988 | })) |
992 | (map ({ name, selector, spawn, key, ...}: if key != null && selector != null && spawn != null then bind key { action = focus-or-spawn-action selector name spawn; } else null) cfg.scratchspaces) | 989 | (map ({ name, selector, spawn, key, ...}: if key != null && selector != null && spawn != null then bind key { action = focus-or-spawn-action selector name spawn; } else null) cfg.scratchspaces) |
993 | (map ({ name, moveKey, ...}: if moveKey != null then bind moveKey { action = kdl.magic-leaf "move-column-to-workspace" name; } else null) cfg.scratchspaces) | 990 | (map ({ name, moveKey, ...}: if moveKey != null then bind moveKey { action = kdl.magic-leaf "move-column-to-workspace" name; } else null) cfg.scratchspaces) |
diff --git a/accounts/gkleen@sif/niri/swayosd.nix b/accounts/gkleen@sif/niri/swayosd.nix deleted file mode 100644 index 54ebb302..00000000 --- a/accounts/gkleen@sif/niri/swayosd.nix +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | { pkgs, ... }: | ||
2 | { | ||
3 | config = { | ||
4 | services.swayosd = { | ||
5 | enable = true; | ||
6 | topMargin = 0.4769706078; | ||
7 | stylePath = pkgs.runCommand "style.css" { | ||
8 | passAsFile = [ "src" ]; | ||
9 | src = '' | ||
10 | window#osd { | ||
11 | padding: 12px 20px; | ||
12 | border-radius: 999px; | ||
13 | border: none; | ||
14 | background: rgba(0, 0, 0, 0.87); | ||
15 | |||
16 | #container { | ||
17 | margin: 16px; | ||
18 | } | ||
19 | |||
20 | image, | ||
21 | label { | ||
22 | color: rgb(255, 255, 255); | ||
23 | |||
24 | &:disabled { | ||
25 | opacity: 1; | ||
26 | color: rgb(84, 84, 84); | ||
27 | } | ||
28 | } | ||
29 | |||
30 | progressbar { | ||
31 | min-height: 6px; | ||
32 | border-radius: 999px; | ||
33 | background: transparent; | ||
34 | border: none; | ||
35 | |||
36 | trough, progress { | ||
37 | min-height: inherit; | ||
38 | border-radius: inherit; | ||
39 | border: none; | ||
40 | } | ||
41 | |||
42 | trough { | ||
43 | background: rgb(127, 127, 127); | ||
44 | } | ||
45 | progress { | ||
46 | background: rgb(255, 255, 255); | ||
47 | } | ||
48 | |||
49 | &:disabled { | ||
50 | opacity: 1; | ||
51 | |||
52 | trough { | ||
53 | background: rgb(19, 19, 19); | ||
54 | } | ||
55 | progress { | ||
56 | background: rgb(38, 38, 38); | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | ''; | ||
62 | buildInputs = with pkgs; [sass]; | ||
63 | } "scss -C --sourcemap=none --style=compact $srcPath $out"; | ||
64 | }; | ||
65 | }; | ||
66 | } | ||
diff --git a/accounts/gkleen@sif/shell/quickshell-plugins/Systemd.cpp b/accounts/gkleen@sif/shell/quickshell-plugins/Systemd.cpp index 9ccd8ba0..5e607709 100644 --- a/accounts/gkleen@sif/shell/quickshell-plugins/Systemd.cpp +++ b/accounts/gkleen@sif/shell/quickshell-plugins/Systemd.cpp | |||
@@ -9,8 +9,16 @@ void Systemd::stopUserUnit(const QString& unit, const QString& mode) { | |||
9 | "/org/freedesktop/systemd1", | 9 | "/org/freedesktop/systemd1", |
10 | "org.freedesktop.systemd1.Manager", | 10 | "org.freedesktop.systemd1.Manager", |
11 | "StopUnit" | 11 | "StopUnit" |
12 | ); | 12 | ) << unit << mode; |
13 | m << unit; | ||
14 | m << mode; | ||
15 | QDBusConnection::sessionBus().send(m); | 13 | QDBusConnection::sessionBus().send(m); |
16 | } | 14 | } |
15 | |||
16 | void Systemd::setBrightness(const QString& subsystem, const QString& name, quint32 brightness) { | ||
17 | QDBusMessage m = QDBusMessage::createMethodCall( | ||
18 | "org.freedesktop.login1", | ||
19 | "/org/freedesktop/login1/session/auto", | ||
20 | "org.freedesktop.login1.Session", | ||
21 | "SetBrightness" | ||
22 | ) << subsystem << name << brightness; | ||
23 | QDBusConnection::systemBus().send(m); | ||
24 | } | ||
diff --git a/accounts/gkleen@sif/shell/quickshell-plugins/Systemd.hpp b/accounts/gkleen@sif/shell/quickshell-plugins/Systemd.hpp index 883a96f3..f8841518 100644 --- a/accounts/gkleen@sif/shell/quickshell-plugins/Systemd.hpp +++ b/accounts/gkleen@sif/shell/quickshell-plugins/Systemd.hpp | |||
@@ -10,4 +10,5 @@ class Systemd : public QObject { | |||
10 | 10 | ||
11 | public: | 11 | public: |
12 | Q_INVOKABLE void stopUserUnit(const QString& unit, const QString& mode); | 12 | Q_INVOKABLE void stopUserUnit(const QString& unit, const QString& mode); |
13 | Q_INVOKABLE void setBrightness(const QString& subsystem, const QString& name, quint32 brightness); | ||
13 | }; | 14 | }; |
diff --git a/accounts/gkleen@sif/shell/quickshell/Bar.qml b/accounts/gkleen@sif/shell/quickshell/Bar.qml index 3652af54..399b566f 100644 --- a/accounts/gkleen@sif/shell/quickshell/Bar.qml +++ b/accounts/gkleen@sif/shell/quickshell/Bar.qml | |||
@@ -1,7 +1,6 @@ | |||
1 | import Quickshell | 1 | import Quickshell |
2 | import QtQuick | 2 | import QtQuick |
3 | 3 | ||
4 | |||
5 | PanelWindow { | 4 | PanelWindow { |
6 | id: bar | 5 | id: bar |
7 | 6 | ||
@@ -64,25 +63,49 @@ 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 | } | ||
69 | |||
70 | Item { | ||
71 | enabled: privacy.active | ||
72 | height: parent.height | ||
73 | width: 8 | ||
74 | } | ||
75 | |||
76 | BatteryWidget {} | ||
77 | |||
78 | Item { | ||
79 | height: parent.height | ||
80 | width: 8 | ||
81 | } | ||
82 | |||
83 | BrightnessWidget {} | ||
68 | 84 | ||
69 | Item { | 85 | Item { |
70 | height: parent.height | 86 | height: parent.height |
71 | width: 4 | 87 | width: 4 |
72 | } | 88 | } |
73 | 89 | ||
90 | PipewireWidget {} | ||
91 | |||
92 | Item { | ||
93 | height: parent.height | ||
94 | width: 2 | ||
95 | } | ||
96 | |||
74 | SystemTray {} | 97 | SystemTray {} |
75 | 98 | ||
76 | Item { | 99 | Item { |
77 | height: parent.height | 100 | height: parent.height |
78 | width: 4 | 101 | width: 2 |
79 | } | 102 | } |
80 | 103 | ||
81 | KeyboardLayout {} | 104 | KeyboardLayout {} |
82 | 105 | ||
83 | Item { | 106 | Item { |
84 | height: parent.height | 107 | height: parent.height |
85 | width: 4 | 108 | width: 8 - 4 |
86 | } | 109 | } |
87 | 110 | ||
88 | Clock {} | 111 | 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 @@ | |||
1 | import QtQuick | ||
2 | import Quickshell | ||
3 | import Quickshell.Widgets | ||
4 | import Quickshell.Services.UPower | ||
5 | |||
6 | Item { | ||
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 @@ | |||
1 | import QtQuick | ||
2 | import QtQuick.Layouts | ||
3 | import Quickshell | ||
4 | import Quickshell.Widgets | ||
5 | import qs.Services | ||
6 | |||
7 | Scope { | ||
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 @@ | |||
1 | import QtQuick | ||
2 | import Quickshell | ||
3 | import Quickshell.Widgets | ||
4 | import qs.Services | ||
5 | |||
6 | Item { | ||
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 | |||
2 | import QtQuick.Effects | 2 | import QtQuick.Effects |
3 | 3 | ||
4 | Item { | 4 | Item { |
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 7fdb5006..007ce100 100644 --- a/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml +++ b/accounts/gkleen@sif/shell/quickshell/PipewireWidget.qml | |||
@@ -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 @@ | |||
1 | import QtQuick | ||
2 | import QtQuick.Layouts | ||
3 | import Quickshell | ||
4 | import Quickshell.Widgets | ||
5 | import qs.Services | ||
6 | |||
7 | Item { | ||
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..545ef24f --- /dev/null +++ b/accounts/gkleen@sif/shell/quickshell/Services/Brightness.qml | |||
@@ -0,0 +1,68 @@ | |||
1 | pragma Singleton | ||
2 | |||
3 | import QtQml | ||
4 | import Quickshell | ||
5 | import Quickshell.Io | ||
6 | import Custom as Custom | ||
7 | |||
8 | Singleton { | ||
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 | onLoaded: root.currBrightness = root.calcCurrBrightness() | ||
30 | } | ||
31 | Connections { | ||
32 | target: maxFile | ||
33 | 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 @@ | |||
1 | pragma Singleton | ||
2 | |||
3 | import QtQml | ||
4 | import Quickshell | ||
5 | import Quickshell.Services.Pipewire | ||
6 | |||
7 | Singleton { | ||
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..956f3995 100644 --- a/accounts/gkleen@sif/shell/quickshell/SystemTray.qml +++ b/accounts/gkleen@sif/shell/quickshell/SystemTray.qml | |||
@@ -116,7 +116,7 @@ Item { | |||
116 | color: "black" | 116 | color: "black" |
117 | 117 | ||
118 | implicitWidth: Math.max(tooltipTitle.contentWidth, tooltipDescription.contentWidth) + 16 | 118 | implicitWidth: Math.max(tooltipTitle.contentWidth, tooltipDescription.contentWidth) + 16 |
119 | implicitHeight: tooltipTitle.contentHeight + tooltipDescription.contentHeight + 16 | 119 | implicitHeight: (trayItem.tooltipTitle ? tooltipTitle.contentHeight : 0) + (trayItem.tooltipDescription ? tooltipDescription.contentHeight : 0) + 16 |
120 | 120 | ||
121 | WrapperMouseArea { | 121 | WrapperMouseArea { |
122 | id: tooltipMouseArea | 122 | id: tooltipMouseArea |
@@ -130,6 +130,8 @@ Item { | |||
130 | Text { | 130 | Text { |
131 | id: tooltipTitle | 131 | id: tooltipTitle |
132 | 132 | ||
133 | enabled: trayItem.tooltipTitle | ||
134 | |||
133 | font.pointSize: 10 | 135 | font.pointSize: 10 |
134 | font.family: "Fira Sans" | 136 | font.family: "Fira Sans" |
135 | font.bold: true | 137 | font.bold: true |
@@ -141,6 +143,8 @@ Item { | |||
141 | Text { | 143 | Text { |
142 | id: tooltipDescription | 144 | id: tooltipDescription |
143 | 145 | ||
146 | enabled: trayItem.tooltipDescription | ||
147 | |||
144 | font.pointSize: 10 | 148 | font.pointSize: 10 |
145 | font.family: "Fira Sans" | 149 | font.family: "Fira Sans" |
146 | color: "white" | 150 | color: "white" |
diff --git a/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml b/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml index 7b308ec0..742ef4f5 100644 --- a/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml +++ b/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml | |||
@@ -1,6 +1,7 @@ | |||
1 | import Quickshell | 1 | import Quickshell |
2 | import Quickshell.Io | 2 | import Quickshell.Io |
3 | import Quickshell.Services.Pipewire | 3 | import Quickshell.Services.Pipewire |
4 | import qs.Services | ||
4 | 5 | ||
5 | Scope { | 6 | Scope { |
6 | id: root | 7 | id: root |
@@ -16,6 +17,8 @@ Scope { | |||
16 | 17 | ||
17 | if (command.Volume) | 18 | if (command.Volume) |
18 | root.onCommandVolume(command.Volume); | 19 | root.onCommandVolume(command.Volume); |
20 | else if (command.Brightness) | ||
21 | root.onCommandBrightness(command.Brightness); | ||
19 | else | 22 | else |
20 | console.warn("UnixIPC: Command not handled:", JSON.stringify(command)); | 23 | console.warn("UnixIPC: Command not handled:", JSON.stringify(command)); |
21 | } catch (e) { | 24 | } catch (e) { |
@@ -46,4 +49,11 @@ Scope { | |||
46 | if (command["mic-muted"] === "toggle") | 49 | if (command["mic-muted"] === "toggle") |
47 | Pipewire.defaultAudioSource.audio.muted = !Pipewire.defaultAudioSource.audio.muted; | 50 | Pipewire.defaultAudioSource.audio.muted = !Pipewire.defaultAudioSource.audio.muted; |
48 | } | 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 | } | ||
49 | } | 59 | } |
diff --git a/accounts/gkleen@sif/shell/quickshell/shell.qml b/accounts/gkleen@sif/shell/quickshell/shell.qml index 3bb2ae00..0fa45f79 100644 --- a/accounts/gkleen@sif/shell/quickshell/shell.qml +++ b/accounts/gkleen@sif/shell/quickshell/shell.qml | |||
@@ -43,6 +43,7 @@ ShellRoot { | |||
43 | Lockscreen {} | 43 | Lockscreen {} |
44 | 44 | ||
45 | VolumeOSD {} | 45 | VolumeOSD {} |
46 | BrightnessOSD {} | ||
46 | 47 | ||
47 | UnixIPC {} | 48 | UnixIPC {} |
48 | } | 49 | } |