diff --git a/flake.lock b/flake.lock index 01f22b1..41ca741 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ ] }, "locked": { - "lastModified": 1774211390, - "narHash": "sha256-sTtAgCCaX8VNNZlQFACd3i1IQ+DB0Wf3COgiFS152ds=", + "lastModified": 1776702787, + "narHash": "sha256-qc5uwEWbuubzYthmZcfCapooZGXhoYZWfTQ24TozbCQ=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "f62a4dbfa4e5584f14ad4c62afedf6e4b433cf70", + "rev": "9a1ca6b8cb4d86a599787a55b78f2ddf809bf945", "type": "github" }, "original": { @@ -43,11 +43,11 @@ ] }, "locked": { - "lastModified": 1775381444, - "narHash": "sha256-06aT/yhP4aLA15e8ASbXBfe615jG6QE+sis+KhhVtSo=", + "lastModified": 1776911729, + "narHash": "sha256-Kbc7+DhyrZCRIaNzTtgEzLEODzwLutbFnSgxfy8CYjM=", "owner": "nix-community", "repo": "emacs-overlay", - "rev": "c868f794043735f1e2cc8d93f6a6d947bfa9e0f0", + "rev": "f9d21a08a5783795bae91d091d62bb6554558c61", "type": "github" }, "original": { @@ -122,11 +122,11 @@ ] }, "locked": { - "lastModified": 1775427330, - "narHash": "sha256-pm1SDX9Tj4eHWwjtDEqSU+5QZO7nHHqU8GT0JtbI9rc=", + "lastModified": 1776904464, + "narHash": "sha256-sBUCj7/4d3Hoevpu3oQp8ccJNA1EDeVmFi1F8O6VJro=", "owner": "nix-community", "repo": "home-manager", - "rev": "7e7269ac064bea120d7b23daed432a096617872d", + "rev": "667b3c47325441e6a444faaf405bba76ec70338a", "type": "github" }, "original": { @@ -151,11 +151,11 @@ ] }, "locked": { - "lastModified": 1772461003, - "narHash": "sha256-pVICsV7FtcEeVwg5y/LFh3XFUkVJninm/P1j/JHzEbM=", + "lastModified": 1776511930, + "narHash": "sha256-fCpwFiTW0rT7oKJqr3cqHMnkwypSwQKpbtUEtxdkgrM=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "b62396457b9cfe2ebf24fe05404b09d2a40f8ed7", + "rev": "39435900785d0c560c6ae8777d29f28617d031ef", "type": "github" }, "original": { @@ -180,11 +180,11 @@ ] }, "locked": { - "lastModified": 1772461523, - "narHash": "sha256-mI6A51do+hEUzeJKk9YSWfVHdI/SEEIBi2tp5Whq5mI=", + "lastModified": 1776426399, + "narHash": "sha256-RUESLKNikIeEq9ymGJ6nmcDXiSFQpUW1IhJ245nL3xM=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "7d63c04b4a2dd5e59ef943b4b143f46e713df804", + "rev": "68d064434787cf1ed4a2fe257c03c5f52f33cf84", "type": "github" }, "original": { @@ -218,11 +218,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1775416789, - "narHash": "sha256-0IELkB6YXCZGqZqLdmOcTw8mki6NNhDmG47y7Qynuj8=", + "lastModified": 1776889279, + "narHash": "sha256-oKSqtplor0a6xzWRq6KL2um504x5VZ0Afw1N6ZiiC48=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "aaa2fc342f002bf4acd965f1ad2ead3796347e35", + "rev": "300cdb7c3241969ac04cd02a5e13010a28ebb830", "type": "github" }, "original": { @@ -264,11 +264,11 @@ ] }, "locked": { - "lastModified": 1772467975, - "narHash": "sha256-kipyuDBxrZq+beYpZqWzGvFWm4QbayW9agAvi94vDXY=", + "lastModified": 1776426575, + "narHash": "sha256-KI6nIfVihn/DPaeB5Et46Xg3dkNHrrEtUd5LBBVomB0=", "owner": "hyprwm", "repo": "hyprland-guiutils", - "rev": "5e1c6b9025aaf4d578f3eff7c0eb1f0c197a9507", + "rev": "a968d211048e3ed538e47b84cb3649299578f19d", "type": "github" }, "original": { @@ -335,11 +335,11 @@ ] }, "locked": { - "lastModified": 1772459629, - "narHash": "sha256-/iwvNUYShmmnwmz/czEUh6+0eF5vCMv0xtDW0STPIuM=", + "lastModified": 1776426736, + "narHash": "sha256-rl7i4aY+9p8LysJp7o8uRWahCkpFznCgGHXszlTw7b0=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "7615ee388de18239a4ab1400946f3d0e498a8186", + "rev": "7833ff33b2e82d3406337b5dcf0d1cec595d83e9", "type": "github" }, "original": { @@ -410,11 +410,11 @@ ] }, "locked": { - "lastModified": 1774911391, - "narHash": "sha256-c4YVwO33Mmw+FIV8E0u3atJZagHvGTJ9Jai6RtiB8rE=", + "lastModified": 1776428866, + "narHash": "sha256-XfRlBolGtjvalTHJp3XvvpYLBjkMhaZLLU0WqZ91Fcg=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "e6caa3d4d1427eedbdf556cf4ceb70f2d9c0b56d", + "rev": "eedd60805cd96d4442586f2ba5fe51d549b12674", "type": "github" }, "original": { @@ -435,11 +435,11 @@ ] }, "locked": { - "lastModified": 1772459835, - "narHash": "sha256-978jRz/y/9TKmZb/qD4lEYHCQGHpEXGqy+8X2lFZsak=", + "lastModified": 1776430932, + "narHash": "sha256-Yv3RPiUvl7CAsJgwIVsqcj7akn1gLyJP1F/mocof5hA=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "0a692d4a645165eebd65f109146b8861e3a925e7", + "rev": "4c2fcc06dc9722c97dbb54ba649c69b18ce83d2e", "type": "github" }, "original": { @@ -464,11 +464,11 @@ ] }, "locked": { - "lastModified": 1773074819, - "narHash": "sha256-qRqYnXiKoJLRTcfaRukn7EifmST2IVBUMZOeZMAc5UA=", + "lastModified": 1776728575, + "narHash": "sha256-z9eGphrArEBpl1O/GCH0wlY6z4K9vA6yWh2gAS6qytU=", "owner": "hyprwm", "repo": "hyprwire", - "rev": "f68afd0e73687598cc2774804fedad76693046f0", + "rev": "f3a80888783702a39691b684d099e16b83ed4702", "type": "github" }, "original": { @@ -499,11 +499,11 @@ ] }, "locked": { - "lastModified": 1775365369, - "narHash": "sha256-DgH5mveLoau20CuTnaU5RXZWgFQWn56onQ4Du2CqYoI=", + "lastModified": 1776829403, + "narHash": "sha256-oHVcvP2Ahhj1KUsEzp+2BQF55/r5VSa3QxdPdwE1p00=", "owner": "Mic92", "repo": "nix-index-database", - "rev": "cef5cf82671e749ac87d69aadecbb75967e6f6c3", + "rev": "c43246d4e9e506178b69baed075d797ec2d873e2", "type": "github" }, "original": { @@ -534,11 +534,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1775036866, - "narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=", + "lastModified": 1776548001, + "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6201e203d09599479a3b3450ed24fa81537ebc4e", + "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", "type": "github" }, "original": { @@ -555,11 +555,11 @@ ] }, "locked": { - "lastModified": 1775435376, - "narHash": "sha256-j38MtwM1VFWWU+bCEBGOsZbR1oaR7ByXSlP2+VRBMy4=", + "lastModified": 1776918210, + "narHash": "sha256-gWgRMF3g+iSgOZ97H/9OKGhLS9HULzZFCRR25VJnWvA=", "owner": "nix-community", "repo": "NUR", - "rev": "c8fe168c59186cbcb65d5b4022cd5cf39d99a201", + "rev": "8b7d3409042a6fb07fd2bfa7d43de3b1604b05d2", "type": "github" }, "original": { @@ -578,11 +578,11 @@ ] }, "locked": { - "lastModified": 1774104215, - "narHash": "sha256-EAtviqz0sEAxdHS4crqu7JGR5oI3BwaqG0mw7CmXkO8=", + "lastModified": 1776796298, + "narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "f799ae951fde0627157f40aec28dec27b22076d0", + "rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad", "type": "github" }, "original": { @@ -618,11 +618,11 @@ ] }, "locked": { - "lastModified": 1775335892, - "narHash": "sha256-rWJ//l6k1hwe/A2fNdzuvEuHedBQkMIHLU9eNTu4N7I=", + "lastModified": 1777019459, + "narHash": "sha256-/JPmIuzUuNjxgYEnm56KqDIMpQbPN4hzTlOsMTMahok=", "ref": "refs/heads/master", - "rev": "ad5fd9116e25bc502468f4dfa884ee027887c51c", - "revCount": 793, + "rev": "e162429b6fa4443a0b45e19a867277dcc25d506b", + "revCount": 807, "type": "git", "url": "https://git.outfoxxed.me/quickshell/quickshell" }, @@ -708,11 +708,11 @@ ] }, "locked": { - "lastModified": 1773601989, - "narHash": "sha256-2tJf/CQoHApoIudxHeJye+0Ii7scR0Yyi7pNiWk0Hn8=", + "lastModified": 1776608502, + "narHash": "sha256-UH8YoQxx4hFOm6qjMdjRQNRvSejFIR/wBZ8fW1p9sME=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "a9b862d1aa000a676d310cc62d249f7ad726233d", + "rev": "4a293523d36dfa367e67ec304cc718ea66a8fec2", "type": "github" }, "original": { diff --git a/modules/user/modules/quickshell/shell/bar/audio/AudioControls.qml b/modules/user/modules/quickshell/shell/bar/audio/AudioControls.qml index f3fd830..6390997 100644 --- a/modules/user/modules/quickshell/shell/bar/audio/AudioControls.qml +++ b/modules/user/modules/quickshell/shell/bar/audio/AudioControls.qml @@ -1,6 +1,8 @@ import QtQuick import QtQuick.Layouts import Quickshell +import Quickshell.Widgets +import Quickshell.Wayland import Quickshell.Io import Quickshell.Services.Pipewire import qs.bar @@ -42,6 +44,41 @@ BarWidgetInner { } } + Variants { + model: { + if (!Pipewire.defaultAudioSource.audio?.muted) return []; + return [...new Set(ToplevelManager.toplevels.values.filter(t => t.fullscreen).map(t => t.screens[0]))]; + } + + PanelWindow { + required property ShellScreen modelData; + screen: modelData + + anchors.left: true + anchors.bottom: true + margins.left: 100 + margins.bottom: 100 + exclusionMode: ExclusionMode.Ignore + WlrLayershell.layer: WlrLayer.Overlay + mask: Region {} + color: "transparent" + implicitWidth: 64 + implicitHeight: 64 + + Rectangle { + anchors.fill: parent + color: "#40000000" + radius: 15 + + IconImage { + source: Quickshell.iconPath("microphone-sensitivity-muted-symbolic") + anchors.fill: parent + opacity: 0.3 + } + } + } + } + IpcHandler { target: "audio" diff --git a/modules/user/modules/quickshell/shell/bar/connections/Bluetooth.qml b/modules/user/modules/quickshell/shell/bar/connections/Bluetooth.qml index 3e075c2..78842a3 100644 --- a/modules/user/modules/quickshell/shell/bar/connections/Bluetooth.qml +++ b/modules/user/modules/quickshell/shell/bar/connections/Bluetooth.qml @@ -82,13 +82,6 @@ ClickableIcon { Item { Layout.fillWidth: true } - ClickableIcon { - image: root.adapter.enabled ? "root:/icons/bluetooth-slash.svg" : "root:/icons/bluetooth.svg" - implicitHeight: 24 - implicitWidth: height - onClicked: root.adapter.enabled = !root.adapter.enabled - } - ActivityButton { image: "root:/icons/binoculars.svg" implicitHeight: 24 diff --git a/modules/user/modules/quickshell/shell/bar/connections/Network.qml b/modules/user/modules/quickshell/shell/bar/connections/Network.qml index 6b6143f..b9391f9 100644 --- a/modules/user/modules/quickshell/shell/bar/connections/Network.qml +++ b/modules/user/modules/quickshell/shell/bar/connections/Network.qml @@ -11,9 +11,29 @@ import qs.bar ClickableIcon { id: root required property var bar; - readonly property WifiDevice adapter: Networking.devices.values[0] ?? null + readonly property WifiDevice adapter: Networking.devices.values.find(d => d.type === DeviceType.Wifi) + readonly property WiredDevice eth: Networking.devices.values.find(d => d.type === DeviceType.Wired) readonly property bool connected: adapter.connected readonly property WifiNetwork activeNetwork: adapter.networks.values.find(network => network.connected) + readonly property string wifiIcon: { + if (root.adapter) { + if (!Networking.wifiEnabled) return "root:/icons/wifi-slash.svg"; + if (!root.adapter.connected) return "root:/icons/wifi-x.svg"; + return `root:/icons/wifi-${Math.round(root.activeNetwork.signalStrength * 3)}.svg` + } + + return "root:/icons/wifi-x.svg"; + } + + readonly property string ethIcon: { + if (root.eth) { + if (!root.eth.network) return "root:/icons/ethernet-x.svg"; + else if (!root.eth.network.connected) return "root:/icons/ethernet-slash.svg"; + else return "root:/icons/ethernet.svg"; + } + + return "root:/icons/ethernet-x.svg"; + } property bool showMenu: false @@ -35,9 +55,17 @@ ClickableIcon { implicitHeight: width fillWindowWidth: true acceptedButtons: Qt.LeftButton | Qt.RightButton - image: Networking.wifiEnabled - ? (connected ? `root:/icons/wifi-${Math.round(root.activeNetwork.signalStrength * 3)}.svg` : "root:/icons/wifi-x.svg") - : "root:/icons/wifi-slash.svg" + image: { + if (root.eth?.network && root.eth.network.connected) { + return "root:/icons/ethernet.svg"; + } else if (Networking.wifiEnabled) { + return root.wifiIcon; + } else if (root.eth?.network) { + return "root:/icons/ethernet-slash.svg"; + } else { + return "root:/icons/ethernet-x.svg"; + } + } property var tooltip: TooltipItem { tooltip: bar.tooltip @@ -67,64 +95,97 @@ ClickableIcon { SmoothedAnimation { property: "y"; velocity: 350 } } - RowLayout { + Loader { width: parent.width + active: root.eth != null + visible: active + sourceComponent: ColumnLayout { + RowLayout { + Layout.fillWidth: true - ClickableIcon { - image: root.image - implicitHeight: 40 - implicitWidth: height - onClicked: root.adapter.enabled = !root.adapter.enabled - } + ClickableIcon { + image: root.ethIcon + implicitHeight: 40 + implicitWidth: height + onClicked: { + const n = root.eth.network; + if (n.connected) n.disconnect(); + else n.connect(); + } + } - Label { - text: `Wifi (${root.adapter.name})` - } + Label { + text: `Ethernet (${root.eth?.name ?? ""})` + } + } - Item { Layout.fillWidth: true } - - ClickableIcon { - image: Networking.wifiEnabled ? "root:/icons/wifi-slash.svg" : "root:/icons/wifi-x.svg" - implicitHeight: 24 - implicitWidth: height - onClicked: Networking.wifiEnabled = !Networking.wifiEnabled - } - - ActivityButton { - image: "root:/icons/binoculars.svg" - implicitHeight: 24 - implicitWidth: height - onClicked: root.adapter.scannerEnabled = !root.adapter.scannerEnabled - showAction: root.adapter.scannerEnabled - Layout.rightMargin: 4 + Rectangle { + Layout.fillWidth: true + implicitHeight: 1 + color: ShellGlobals.colors.separator + visible: root.adapter != null + } } } - Rectangle { + Loader { width: parent.width - implicitHeight: 1 - visible: root.adapter.networks.values.length > 0 + active: root.adapter != null + visible: active + sourceComponent: ColumnLayout { + RowLayout { + Layout.fillWidth: true + ClickableIcon { + image: root.wifiIcon + implicitHeight: 40 + implicitWidth: height + onClicked: Networking.wifiEnabled = !Networking.wifiEnabled + } - color: ShellGlobals.colors.separator - } + Label { + text: `Wifi (${root.adapter.name})` + } - Repeater { - model: ScriptModel { - values: [...root.adapter.networks.values].sort((a, b) => { - if (a.connected && !b.connected) return -1; - if (b.connected && !a.connected) return 1; - if (a.bonded && !b.bonded) return -1; - if (b.bonded && !a.bonded) return 1; - return b.name - a.name; - }) - } + Item { Layout.fillWidth: true } - delegate: NetworkDelegate { - required property var modelData - device: root.adapter - network: modelData - width: parent.width - onConnectionAttempted: root.adapter.scannerEnabled = false + ActivityButton { + image: "root:/icons/binoculars.svg" + implicitHeight: 24 + implicitWidth: height + onClicked: root.adapter.scannerEnabled = !root.adapter.scannerEnabled + showAction: root.adapter.scannerEnabled + Layout.rightMargin: 4 + } + } + + Rectangle { + Layout.fillWidth: parent + implicitHeight: 1 + visible: root.adapter.networks.values.length > 0 + + color: ShellGlobals.colors.separator + } + + Repeater { + model: ScriptModel { + values: [...root.adapter.networks.values].sort((a, b) => { + if (a.connected && !b.connected) return -1; + if (b.connected && !a.connected) return 1; + if (a.bonded && !b.bonded) return -1; + if (b.bonded && !a.bonded) return 1; + return b.name - a.name; + }) + } + + delegate: NetworkDelegate { + required property var modelData + Layout.fillWidth: parent + device: root.adapter + network: modelData + width: parent.width + onConnectionAttempted: root.adapter.scannerEnabled = false + } + } } } } diff --git a/modules/user/modules/quickshell/shell/icons/ethernet-slash.svg b/modules/user/modules/quickshell/shell/icons/ethernet-slash.svg new file mode 100644 index 0000000..940ed38 --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/ethernet-slash.svg @@ -0,0 +1 @@ + diff --git a/modules/user/modules/quickshell/shell/icons/ethernet-x.svg b/modules/user/modules/quickshell/shell/icons/ethernet-x.svg new file mode 100644 index 0000000..cdee1a8 --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/ethernet-x.svg @@ -0,0 +1 @@ + diff --git a/modules/user/modules/quickshell/shell/icons/ethernet.svg b/modules/user/modules/quickshell/shell/icons/ethernet.svg new file mode 100644 index 0000000..403d18d --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/ethernet.svg @@ -0,0 +1 @@ +