From 6c73e52f6d15a14cc4ba3a1be168d417543901b2 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 24 Jul 2025 18:51:24 -0700 Subject: [PATCH 1/3] qs bluetooth --- .../quickshell/shell/bar/ActivityButton.qml | 19 +++ .../user/modules/quickshell/shell/bar/Bar.qml | 10 +- .../shell/bar/connections/Bluetooth.qml | 129 ++++++++++++++++++ .../connections/BluetoothDeviceDelegate.qml | 88 ++++++++++++ .../bar/connections/ConnectionDelegate.qml | 1 + .../shell/bar/connections/Connections.qml | 23 ++++ .../quickshell/shell/icons/binoculars.svg | 1 + .../shell/icons/bluetooth-connected.svg | 1 + .../shell/icons/bluetooth-slash.svg | 1 + .../quickshell/shell/icons/bluetooth-x.svg | 1 + .../quickshell/shell/icons/bluetooth.svg | 1 + .../shell/icons/plugs-connected.svg | 1 + .../modules/quickshell/shell/icons/plugs.svg | 1 + .../modules/quickshell/shell/icons/trash.svg | 1 + .../quickshell/shell/icons/wifi-slash.svg | 1 + .../modules/quickshell/shell/icons/wifi.svg | 1 + 16 files changed, 277 insertions(+), 3 deletions(-) create mode 100644 modules/user/modules/quickshell/shell/bar/ActivityButton.qml create mode 100644 modules/user/modules/quickshell/shell/bar/connections/Bluetooth.qml create mode 100644 modules/user/modules/quickshell/shell/bar/connections/BluetoothDeviceDelegate.qml create mode 100644 modules/user/modules/quickshell/shell/bar/connections/ConnectionDelegate.qml create mode 100644 modules/user/modules/quickshell/shell/bar/connections/Connections.qml create mode 100644 modules/user/modules/quickshell/shell/icons/binoculars.svg create mode 100644 modules/user/modules/quickshell/shell/icons/bluetooth-connected.svg create mode 100644 modules/user/modules/quickshell/shell/icons/bluetooth-slash.svg create mode 100644 modules/user/modules/quickshell/shell/icons/bluetooth-x.svg create mode 100644 modules/user/modules/quickshell/shell/icons/bluetooth.svg create mode 100644 modules/user/modules/quickshell/shell/icons/plugs-connected.svg create mode 100644 modules/user/modules/quickshell/shell/icons/plugs.svg create mode 100644 modules/user/modules/quickshell/shell/icons/trash.svg create mode 100644 modules/user/modules/quickshell/shell/icons/wifi-slash.svg create mode 100644 modules/user/modules/quickshell/shell/icons/wifi.svg diff --git a/modules/user/modules/quickshell/shell/bar/ActivityButton.qml b/modules/user/modules/quickshell/shell/bar/ActivityButton.qml new file mode 100644 index 0000000..99c2338 --- /dev/null +++ b/modules/user/modules/quickshell/shell/bar/ActivityButton.qml @@ -0,0 +1,19 @@ +import QtQuick +import QtQuick.Controls + +ClickableIcon { + id: root + property bool showAction: false + showPressed: mouseArea.pressed || showAction + + BusyIndicator { + parent: root + anchors.centerIn: parent + opacity: root.showAction ? 1 : 0 + Behavior on opacity { SmoothedAnimation { velocity: 8 }} + visible: opacity != 0 + width: root.width - 3 + opacity * 11 + height: width + padding: 0 + } +} diff --git a/modules/user/modules/quickshell/shell/bar/Bar.qml b/modules/user/modules/quickshell/shell/bar/Bar.qml index 955993c..08dab26 100644 --- a/modules/user/modules/quickshell/shell/bar/Bar.qml +++ b/modules/user/modules/quickshell/shell/bar/Bar.qml @@ -1,11 +1,12 @@ pragma ComponentBehavior: Bound + import QtQuick import QtQuick.Layouts -import QtQuick.Controls import Quickshell import qs.bar.systray as SysTray import qs.bar.audio as Audio import qs.bar.mpris as Mpris +import qs.bar.connections as Connections import qs.bar.power as Power import qs.notifications as Notifs @@ -14,7 +15,6 @@ BarContainment { property bool isSoleBar: Quickshell.screens.length == 1; ColumnLayout { - anchors { left: parent.left right: parent.right @@ -75,6 +75,11 @@ BarContainment { Layout.fillWidth: true } + Connections.Connections { + bar: root + Layout.fillWidth: true + } + Power.Power { bar: root Layout.fillWidth: true @@ -84,6 +89,5 @@ BarContainment { bar: root Layout.fillWidth: true } - } } diff --git a/modules/user/modules/quickshell/shell/bar/connections/Bluetooth.qml b/modules/user/modules/quickshell/shell/bar/connections/Bluetooth.qml new file mode 100644 index 0000000..459938a --- /dev/null +++ b/modules/user/modules/quickshell/shell/bar/connections/Bluetooth.qml @@ -0,0 +1,129 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Quickshell +import Quickshell.Widgets +import Quickshell.Bluetooth +import qs +import qs.bar + +ClickableIcon { + id: root + required property var bar; + readonly property BluetoothAdapter adapter: Bluetooth.defaultAdapter + readonly property bool connected: adapter.devices.values.some(device => device.connected) + + property bool showMenu: false + + onPressed: event => { + event.accepted = true; + if (event.button === Qt.RightButton) { + showMenu = !showMenu; + } + } + + onClicked: event => { + if (event.button === Qt.LeftButton) { + adapter.enabled = !adapter.enabled; + } + } + + showPressed: showMenu || (pressedButtons & ~Qt.RightButton) + + implicitHeight: width + fillWindowWidth: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + image: adapter.enabled + ? (connected ? "root:/icons/bluetooth-connected.svg" : "root:/icons/bluetooth.svg") + : "root:/icons/bluetooth-slash.svg" + + property var tooltip: TooltipItem { + tooltip: bar.tooltip + owner: root + show: root.containsMouse + + Label { text: "Bluetooth" } + } + + property var rightclickMenu: TooltipItem { + id: rightclickMenu + tooltip: bar.tooltip + owner: root + + isMenu: true + show: root.showMenu + onClose: root.showMenu = false + + Loader { + width: 400 + active: root.showMenu || rightclickMenu.visible + + sourceComponent: Column { + spacing: 5 + + move: Transition { + SmoothedAnimation { property: "y"; velocity: 350 } + } + + RowLayout { + width: parent.width + + ClickableIcon { + image: root.image + implicitHeight: 40 + implicitWidth: height + onClicked: root.adapter.enabled = !root.adapter.enabled + } + + Label { + text: `Bluetooth (${root.adapter.adapterId})` + } + + 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 + implicitWidth: height + onClicked: root.adapter.discovering = !root.adapter.discovering + showAction: root.adapter.discovering + Layout.rightMargin: 4 + } + } + + Rectangle { + width: parent.width + implicitHeight: 1 + visible: linkTracker.linkGroups.length > 0 + + color: ShellGlobals.colors.separator + } + + Repeater { + model: ScriptModel { + values: [...root.adapter.devices.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: BluetoothDeviceDelegate { + required property BluetoothDevice modelData + device: modelData + width: parent.width + } + } + } + } + } +} diff --git a/modules/user/modules/quickshell/shell/bar/connections/BluetoothDeviceDelegate.qml b/modules/user/modules/quickshell/shell/bar/connections/BluetoothDeviceDelegate.qml new file mode 100644 index 0000000..6118690 --- /dev/null +++ b/modules/user/modules/quickshell/shell/bar/connections/BluetoothDeviceDelegate.qml @@ -0,0 +1,88 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Quickshell +import Quickshell.Widgets +import Quickshell.Bluetooth +import qs +import qs.bar + +WrapperMouseArea { + id: root + required property BluetoothDevice device + property bool menuOpen: false + readonly property bool showBg: false//pairingContext.attentionRequested //device.connected//menuOpen //|| containsMouse + hoverEnabled: true + + onClicked: menuOpen = !menuOpen + + WrapperRectangle { + color: root.showBg ? ShellGlobals.colors.widget : "transparent" + border.width: 1 + border.color: root.showBg ? ShellGlobals.colors.widgetOutline : "transparent" + radius: 4 + rightMargin: 2 + + ColumnLayout { + RowLayout { + ClickableIcon { + image: Quickshell.iconPath(root.device.icon) + implicitHeight: 40 + implicitWidth: height + } + + Label { + text: root.device.name + } + + Item { Layout.fillWidth: true } + + ActivityButton { + image: root.device.connected ? "root:/icons/plugs-connected.svg" : "root:/icons/plugs.svg" + implicitHeight: 24 + implicitWidth: height + showAction: root.device.pairing || root.device.state === BluetoothDeviceState.Connecting || root.device.state === BluetoothDeviceState.Disconnecting + onClicked: { + if (showAction) return; + else if (root.device.connected) root.device.disconnect(); + else if (root.device.paired) root.device.connect(); + else root.device.pair(); + } + } + + ClickableIcon { + image: "root:/icons/trash.svg" + implicitHeight: 24 + implicitWidth: height + visible: root.device.bonded + onClicked: root.device.forget() + } + } + + /*RowLayout { + Layout.margins: 3 + Layout.topMargin: 0 + visible: root.showBg + + BluetoothPairingContext { + id: pairingContext + device: root.device + } + + Label { + text: `Pairing Code: ${pairingContext.pairingCode}` + } + + Button { + text: "Accept" + onClicked: pairingContext.confirmCode(true) + } + + Button { + text: "Reject" + onClicked: pairingContext.confirmCode(false) + } + }*/ + } + } +} diff --git a/modules/user/modules/quickshell/shell/bar/connections/ConnectionDelegate.qml b/modules/user/modules/quickshell/shell/bar/connections/ConnectionDelegate.qml new file mode 100644 index 0000000..83f9bc3 --- /dev/null +++ b/modules/user/modules/quickshell/shell/bar/connections/ConnectionDelegate.qml @@ -0,0 +1 @@ +import Quickshell diff --git a/modules/user/modules/quickshell/shell/bar/connections/Connections.qml b/modules/user/modules/quickshell/shell/bar/connections/Connections.qml new file mode 100644 index 0000000..c3c9a98 --- /dev/null +++ b/modules/user/modules/quickshell/shell/bar/connections/Connections.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Layouts +import qs.bar + +BarWidgetInner { + id: root + required property var bar; + implicitHeight: column.implicitHeight + 10 + + ColumnLayout { + id: column + + anchors { + fill: parent + margins: 5 + } + + Bluetooth { + Layout.fillWidth: true + bar: root.bar + } + } +} diff --git a/modules/user/modules/quickshell/shell/icons/binoculars.svg b/modules/user/modules/quickshell/shell/icons/binoculars.svg new file mode 100644 index 0000000..06592fc --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/binoculars.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/bluetooth-connected.svg b/modules/user/modules/quickshell/shell/icons/bluetooth-connected.svg new file mode 100644 index 0000000..8a1cc58 --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/bluetooth-connected.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/bluetooth-slash.svg b/modules/user/modules/quickshell/shell/icons/bluetooth-slash.svg new file mode 100644 index 0000000..0991c7e --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/bluetooth-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/bluetooth-x.svg b/modules/user/modules/quickshell/shell/icons/bluetooth-x.svg new file mode 100644 index 0000000..8603667 --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/bluetooth-x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/bluetooth.svg b/modules/user/modules/quickshell/shell/icons/bluetooth.svg new file mode 100644 index 0000000..e57998a --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/bluetooth.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/plugs-connected.svg b/modules/user/modules/quickshell/shell/icons/plugs-connected.svg new file mode 100644 index 0000000..3659335 --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/plugs-connected.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/plugs.svg b/modules/user/modules/quickshell/shell/icons/plugs.svg new file mode 100644 index 0000000..9d704ec --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/plugs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/trash.svg b/modules/user/modules/quickshell/shell/icons/trash.svg new file mode 100644 index 0000000..d73b018 --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/wifi-slash.svg b/modules/user/modules/quickshell/shell/icons/wifi-slash.svg new file mode 100644 index 0000000..1adff03 --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/wifi-slash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/user/modules/quickshell/shell/icons/wifi.svg b/modules/user/modules/quickshell/shell/icons/wifi.svg new file mode 100644 index 0000000..c4840c7 --- /dev/null +++ b/modules/user/modules/quickshell/shell/icons/wifi.svg @@ -0,0 +1 @@ + \ No newline at end of file From 54e0964b71a7561a702b5da5f3926b5ad2b4768b Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 24 Jul 2025 18:52:44 -0700 Subject: [PATCH 2/3] qs internal pragma --- modules/user/modules/quickshell/default.nix | 4 ++-- .../user/modules/quickshell/shell/bar/mpris/BackgroundArt.qml | 3 +++ .../user/modules/quickshell/shell/bar/mpris/MediaSlider.qml | 1 + .../modules/quickshell/shell/bar/systray/MenuCheckBox.qml | 1 + .../quickshell/shell/bar/systray/MenuChildrenRevealer.qml | 1 + .../user/modules/quickshell/shell/bar/systray/MenuItem.qml | 1 + .../modules/quickshell/shell/bar/systray/MenuRadioButton.qml | 1 + .../user/modules/quickshell/shell/bar/systray/MenuView.qml | 2 +- 8 files changed, 11 insertions(+), 3 deletions(-) diff --git a/modules/user/modules/quickshell/default.nix b/modules/user/modules/quickshell/default.nix index 0f5598c..9dff89b 100644 --- a/modules/user/modules/quickshell/default.nix +++ b/modules/user/modules/quickshell/default.nix @@ -10,12 +10,12 @@ in { qt6.qtdeclarative # qtdecl types in path (quickshell.packages.${system}.default.override (prevqs: { debug = true; - qt6 = prevqs.qt6.overrideScope (_: prevqt: { + /*qt6 = prevqs.qt6.overrideScope (_: prevqt: { qtdeclarative = prevqt.qtdeclarative.overrideAttrs (prev: { cmakeBuildType = "Debug"; dontStrip = true; }); - }); + });*/ })) grim imagemagick # screenshot ]; diff --git a/modules/user/modules/quickshell/shell/bar/mpris/BackgroundArt.qml b/modules/user/modules/quickshell/shell/bar/mpris/BackgroundArt.qml index 4c7b81c..b7c0204 100644 --- a/modules/user/modules/quickshell/shell/bar/mpris/BackgroundArt.qml +++ b/modules/user/modules/quickshell/shell/bar/mpris/BackgroundArt.qml @@ -1,3 +1,6 @@ +//@ pragma Internal +pragma ComponentBehavior: Bound + import QtQuick import QtQuick.Controls import QtQuick.Layouts diff --git a/modules/user/modules/quickshell/shell/bar/mpris/MediaSlider.qml b/modules/user/modules/quickshell/shell/bar/mpris/MediaSlider.qml index 5670051..af3ae41 100644 --- a/modules/user/modules/quickshell/shell/bar/mpris/MediaSlider.qml +++ b/modules/user/modules/quickshell/shell/bar/mpris/MediaSlider.qml @@ -1,3 +1,4 @@ +//@ pragma Internal import QtQuick import QtQuick.Templates as T diff --git a/modules/user/modules/quickshell/shell/bar/systray/MenuCheckBox.qml b/modules/user/modules/quickshell/shell/bar/systray/MenuCheckBox.qml index 257229d..eb42eb3 100644 --- a/modules/user/modules/quickshell/shell/bar/systray/MenuCheckBox.qml +++ b/modules/user/modules/quickshell/shell/bar/systray/MenuCheckBox.qml @@ -1,3 +1,4 @@ +//@ pragma Internal import QtQuick import QtQuick.Shapes import qs diff --git a/modules/user/modules/quickshell/shell/bar/systray/MenuChildrenRevealer.qml b/modules/user/modules/quickshell/shell/bar/systray/MenuChildrenRevealer.qml index ad7c0f8..55f9c8e 100644 --- a/modules/user/modules/quickshell/shell/bar/systray/MenuChildrenRevealer.qml +++ b/modules/user/modules/quickshell/shell/bar/systray/MenuChildrenRevealer.qml @@ -1,3 +1,4 @@ +//@ pragma Internal import QtQuick import QtQuick.Shapes import Quickshell diff --git a/modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml b/modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml index 7271841..326ccaf 100644 --- a/modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml +++ b/modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml @@ -1,3 +1,4 @@ +//@ pragma Internal import QtQuick import QtQuick.Layouts import Quickshell diff --git a/modules/user/modules/quickshell/shell/bar/systray/MenuRadioButton.qml b/modules/user/modules/quickshell/shell/bar/systray/MenuRadioButton.qml index adabdf5..fd5c288 100644 --- a/modules/user/modules/quickshell/shell/bar/systray/MenuRadioButton.qml +++ b/modules/user/modules/quickshell/shell/bar/systray/MenuRadioButton.qml @@ -1,3 +1,4 @@ +//@ pragma Internal import QtQuick import qs diff --git a/modules/user/modules/quickshell/shell/bar/systray/MenuView.qml b/modules/user/modules/quickshell/shell/bar/systray/MenuView.qml index fc80aea..b90514f 100644 --- a/modules/user/modules/quickshell/shell/bar/systray/MenuView.qml +++ b/modules/user/modules/quickshell/shell/bar/systray/MenuView.qml @@ -1,7 +1,7 @@ +//@ pragma Internal import QtQuick import QtQuick.Layouts import Quickshell -import Quickshell.DBusMenu import qs ColumnLayout { From 406ffd6c1546c43ec29795d86e424a7db4f3b3d0 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 24 Jul 2025 18:53:50 -0700 Subject: [PATCH 3/3] qs tray: close on click --- modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml b/modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml index 326ccaf..2ed52d6 100644 --- a/modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml +++ b/modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml @@ -25,7 +25,7 @@ MouseArea { if (entry.hasChildren) childrenRevealer.expanded = !childrenRevealer.expanded else { entry.triggered(); - if (entry.toggleType == ToggleButtonType.None) close(); + close(); } }