bluetooth and wifi

This commit is contained in:
end-4
2025-04-15 20:10:52 +02:00
parent ff8cee9dde
commit 62ef2fc421
13 changed files with 373 additions and 42 deletions
+21 -2
View File
@@ -136,9 +136,27 @@ Scope {
spacing: 20
layoutDirection: Qt.RightToLeft
Item { // TODO make this wifi & bluetooth
Layout.leftMargin: Appearance.rounding.screenRounding
RowLayout { // TODO make this wifi & bluetooth
Layout.rightMargin: Appearance.rounding.screenRounding
Layout.fillWidth: false
spacing: 15
MaterialSymbol {
text: (Network.networkName.length > 0 && Network.networkName != "lo") ? (
Network.networkStrength > 80 ? "signal_wifi_4_bar" :
Network.networkStrength > 60 ? "network_wifi_3_bar" :
Network.networkStrength > 40 ? "network_wifi_2_bar" :
Network.networkStrength > 20 ? "network_wifi_1_bar" :
"signal_wifi_0_bar"
) : "signal_wifi_off"
font.pointSize: Appearance.font.pointSize.larger
color: Appearance.colors.colOnLayer0
}
MaterialSymbol {
text: Bluetooth.bluetoothConnected ? "bluetooth_connected" : Bluetooth.bluetoothEnabled ? "bluetooth" : "bluetooth_disabled"
font.pointSize: Appearance.font.pointSize.larger
color: Appearance.colors.colOnLayer0
}
}
SysTray {
@@ -155,6 +173,7 @@ Scope {
MouseArea {
anchors.fill: rightSection
acceptedButtons: Qt.LeftButton
propagateComposedEvents: true
onPressed: (event) => {
if (event.button === Qt.LeftButton) {
toggleSidebarRight.running = true
@@ -7,6 +7,7 @@ import Quickshell.Services.SystemTray
import Quickshell.Wayland
import Quickshell.Widgets
// TODO: More fancy animation
Item {
id: root
@@ -34,6 +35,17 @@ Item {
}
StyledText {
Layout.alignment: Qt.AlignVCenter
font.pointSize: Appearance.font.pointSize.larger
color: Appearance.colors.colSubtext
text: "•"
visible: {
console.log("SystemTray.values.length", SystemTray.items.values.length)
SystemTray.items.values.length > 0
}
}
}
}
@@ -12,6 +12,7 @@ Item {
required property var bar
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(bar.screen)
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / ConfigOptions.bar.workspacesShown)
property list<bool> workspaceOccupied: []
property int widgetPadding: 4
@@ -70,6 +71,16 @@ Item {
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.BackButton
onPressed: (event) => {
if (event.button === Qt.BackButton) {
Hyprland.dispatch(`togglespecialworkspace`);
}
}
}
// Workspaces - background
RowLayout {
id: rowLayout
@@ -0,0 +1,69 @@
pragma Singleton
import Quickshell;
import Quickshell.Io;
import QtQuick;
Singleton {
id: root
property int updateInterval: 1000
property string bluetoothDeviceName: ""
property string bluetoothDeviceAddress: ""
property bool bluetoothEnabled: false
property bool bluetoothConnected: false
function update() {
updateBluetoothDevice.running = true
updateBluetoothStatus.running = true
updateBluetoothEnabled.running = true
}
Timer {
interval: 10
running: true
repeat: true
onTriggered: {
update()
interval = root.updateInterval
}
}
// Check if Bluetooth is enabled (controller powered on)
Process {
id: updateBluetoothEnabled
command: ["sh", "-c", "bluetoothctl show | grep -q 'Powered: yes' && echo 1 || echo 0"]
running: true
stdout: SplitParser {
onRead: data => {
root.bluetoothEnabled = (parseInt(data) === 1)
}
}
}
// Get the name and address of the first connected Bluetooth device
Process {
id: updateBluetoothDevice
command: ["sh", "-c", "bluetoothctl info | awk -F': ' '/Name: /{name=$2} /Device /{addr=$2} END{print name \":\" addr}'"]
running: true
stdout: SplitParser {
onRead: data => {
let parts = data.split(":")
root.bluetoothDeviceName = parts[0] || ""
root.bluetoothDeviceAddress = parts[1] || ""
}
}
}
// Check if any device is connected
Process {
id: updateBluetoothStatus
command: ["sh", "-c", "bluetoothctl info | grep -q 'Connected: yes' && echo 1 || echo 0"]
running: true
stdout: SplitParser {
onRead: data => {
root.bluetoothConnected = (parseInt(data) === 1)
}
}
}
}
@@ -7,6 +7,15 @@ Singleton {
property int fakeScreenRounding: 1 // 0: None | 1: Always | 2: When not fullscreen
}
property QtObject apps: QtObject {
property string bluetooth: "blueberry"
property string imageViewer: "loupe"
property string network: "XDG_CURRENT_DESKTOP=\"gnome\" gnome-control-center wifi"
property string settings: "XDG_CURRENT_DESKTOP=\"gnome\" gnome-control-center"
property string taskManager: "gnome-usage"
property string terminal: "foot" // This is only for shell actions
}
property QtObject bar: QtObject {
property int workspacesShown: 10
property int batteryLowThreshold: 20
@@ -0,0 +1,53 @@
pragma Singleton
import Quickshell;
import Quickshell.Io;
import Quickshell.Services.Pipewire;
import QtQuick;
Singleton {
id: root
property int updateInterval: 1000
property string networkName: "";
property int networkStrength;
function update() {
updateNetworkName.running = true
updateNetworkStrength.running = true
}
Timer {
interval: 10
running: true
repeat: true
onTriggered: {
update()
interval = root.updateInterval;
}
}
Process {
id: updateNetworkName
command: ["sh", "-c", "nmcli -t -f NAME c show --active | head -1"]
running: true;
stdout: SplitParser {
onRead: data => {
root.networkName = data
// console.log("Network: " + data);
}
}
}
Process {
id: updateNetworkStrength
running: true
command: ["sh", "-c", "nmcli -f IN-USE,SIGNAL,SSID device wifi | awk '/^\*/{if (NR!=1) {print $2}}'"];
stdout: SplitParser {
onRead: data => {
root.networkStrength = parseInt(data);
// console.log("Network Strength: " + data);
}
}
}
}
@@ -12,10 +12,12 @@ ToolTip {
background: Rectangle {
color: Appearance.colors.colTooltip
radius: Appearance.rounding.small
implicitWidth: tooltipText.implicitWidth + 2 * padding
}
StyledText {
text: content
id: tooltipText
text: content
color: Appearance.colors.colOnTooltip
wrapMode: Text.WordWrap
}
}
@@ -1,5 +1,6 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "./quickToggles/"
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
@@ -128,45 +129,11 @@ Scope {
anchors.margins: 5
spacing: 5
QuickToggleButton {
property bool enabled: false
buttonIcon: "gamepad"
toggled: enabled
onClicked: {
enabled = !enabled
if (enabled) {
gameModeOn.running = true
} else {
gameModeOff.running = true
}
}
Process {
id: gameModeOn
command: ['bash', '-c', `hyprctl --batch "keyword animations:enabled 0; keyword decoration:shadow:enabled 0; keyword decoration:blur:enabled 0; keyword general:gaps_in 0; keyword general:gaps_out 0; keyword general:border_size 1; keyword decoration:rounding 0; keyword general:allow_tearing 1"`]
}
Process {
id: gameModeOff
command: ['bash', '-c', `hyprctl reload`]
}
StyledToolTip {
content: "Game mode"
}
}
QuickToggleButton {
toggled: idleInhibitor.running
buttonIcon: "coffee"
onClicked: {
idleInhibitor.running = !idleInhibitor.running
}
Process {
id: idleInhibitor
command: ["bash", "-c", "${XDG_CONFIG_HOME:-$HOME/.config}/quickshell/scripts/wayland-idle-inhibitor.py"]
}
StyledToolTip {
content: "Keep system awake"
}
}
Network {}
Bluetooth {}
NightLight {}
GameMode {}
IdleInhibitor {}
}
}
@@ -203,6 +170,15 @@ Scope {
}
}
}
function close(): void {
for (let i = 0; i < sidebarVariants.instances.length; i++) {
let panelWindow = sidebarVariants.instances[i];
if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) {
panelWindow.visible = false;
}
}
}
}
}
@@ -0,0 +1,41 @@
import "../"
import "root:/modules/common"
import "root:/modules/common/widgets"
import QtQuick
import Quickshell
import Quickshell.Io
QuickToggleButton {
toggled: Bluetooth.bluetoothEnabled
buttonIcon: Bluetooth.bluetoothConnected ? "bluetooth_connected" : Bluetooth.bluetoothEnabled ? "bluetooth" : "bluetooth_disabled"
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton | Qt.LeftButton
onClicked: {
if (mouse.button === Qt.LeftButton) {
toggleBluetooth.running = true
}
if (mouse.button === Qt.RightButton) {
configureBluetooth.running = true
}
}
hoverEnabled: false
propagateComposedEvents: true
}
Process {
id: configureBluetooth
command: ["bash", "-c", `${ConfigOptions.apps.bluetooth} & qs ipc call sidebarRight close`]
}
Process {
id: toggleBluetooth
command: ["bash", "-c", `bluetoothctl power ${Bluetooth.bluetoothEnabled ? "off" : "on"}`]
onRunningChanged: {
if(!running) {
Bluetooth.update()
}
}
}
StyledToolTip {
content: `${Bluetooth.bluetoothEnabled ? Bluetooth.bluetoothDeviceName : "Bluetooth"} | Right-click to configure`
}
}
@@ -0,0 +1,30 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "../"
import Quickshell.Io
import Quickshell
QuickToggleButton {
property bool enabled: false
buttonIcon: "gamepad"
toggled: enabled
onClicked: {
enabled = !enabled
if (enabled) {
gameModeOn.running = true
} else {
gameModeOff.running = true
}
}
Process {
id: gameModeOn
command: ['bash', '-c', `hyprctl --batch "keyword animations:enabled 0; keyword decoration:shadow:enabled 0; keyword decoration:blur:enabled 0; keyword general:gaps_in 0; keyword general:gaps_out 0; keyword general:border_size 1; keyword decoration:rounding 0; keyword general:allow_tearing 1"`]
}
Process {
id: gameModeOff
command: ['bash', '-c', `hyprctl reload`]
}
StyledToolTip {
content: "Game mode"
}
}
@@ -0,0 +1,20 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "../"
import Quickshell.Io
import Quickshell
QuickToggleButton {
toggled: idleInhibitor.running
buttonIcon: "coffee"
onClicked: {
idleInhibitor.running = !idleInhibitor.running
}
Process {
id: idleInhibitor
command: ["bash", "-c", "${XDG_CONFIG_HOME:-$HOME/.config}/quickshell/scripts/wayland-idle-inhibitor.py"]
}
StyledToolTip {
content: "Keep system awake"
}
}
@@ -0,0 +1,47 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "../"
import Quickshell.Io
import Quickshell
import QtQuick
QuickToggleButton {
toggled: Network.networkName.length > 0 && Network.networkName != "lo"
buttonIcon: toggled ? (
Network.networkStrength > 80 ? "signal_wifi_4_bar" :
Network.networkStrength > 60 ? "network_wifi_3_bar" :
Network.networkStrength > 40 ? "network_wifi_2_bar" :
Network.networkStrength > 20 ? "network_wifi_1_bar" :
"signal_wifi_0_bar"
) : "signal_wifi_off"
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton | Qt.LeftButton
onClicked: {
if (mouse.button === Qt.LeftButton) {
toggleNetwork.running = true
}
if (mouse.button === Qt.RightButton) {
configureNetwork.running = true
}
}
hoverEnabled: false
propagateComposedEvents: true
}
Process {
id: configureNetwork
command: ["bash", "-c", `${ConfigOptions.apps.network} & qs ipc call sidebarRight close`]
}
Process {
id: toggleNetwork
command: ["bash", "-c", "nmcli radio wifi | grep -q enabled && nmcli radio wifi off || nmcli radio wifi on"]
onRunningChanged: {
if(!running) {
Network.update()
}
}
}
StyledToolTip {
content: `${Network.networkName} | Right-click to configure`
}
}
@@ -0,0 +1,42 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "../"
import Quickshell.Io
import Quickshell
QuickToggleButton {
id: nightLightButton
property bool enabled: false
toggled: enabled
buttonIcon: "nightlight"
onClicked: {
nightLightButton.enabled = !nightLightButton.enabled
if (enabled) {
nightLightOn.running = true
}
else {
nightLightOff.running = true
}
}
Process {
id: nightLightOn
command: ["gammastep"]
}
Process {
id: nightLightOff
command: ["pkill", "gammastep"]
}
Process {
id: updateNightLightState
running: true
command: ["pidof", "gammastep"]
stdout: SplitParser {
onRead: (data) => { // if not empty then set toggled to true
nightLightButton.enabled = data.length > 0
}
}
}
StyledToolTip {
content: "Night Light"
}
}