Squash 3 commits

This commit is contained in:
Turann_
2026-02-09 01:56:47 +03:00
parent d241506bfc
commit e69886745b
4 changed files with 71 additions and 202 deletions
+9 -1
View File
@@ -3,6 +3,7 @@ import QtQuick.Controls
import Quickshell
import qs.Commons
import qs.Modules.Bar.Extras
import qs.Modules.Panels.Settings // For SettingsPanel
import qs.Services.Networking
import qs.Services.UI
import qs.Widgets
@@ -49,10 +50,15 @@ Item {
"action": "toggle-bluetooth",
"icon": BluetoothService.enabled ? "bluetooth-off" : "bluetooth"
},
{
"label": I18n.tr("common.bluetooth") + " " + I18n.tr("tooltips.open-settings"),
"action": "bluetooth-settings",
"icon": "settings"
},
{
"label": I18n.tr("actions.widget-settings"),
"action": "widget-settings",
"icon": "settings"
"icon": "settings-bar"
},
]
@@ -62,6 +68,8 @@ Item {
if (action === "toggle-bluetooth") {
BluetoothService.setBluetoothEnabled(!BluetoothService.enabled);
} else if (action === "bluetooth-settings") {
SettingsPanelService.openToTab(SettingsPanel.Tab.Network, 1, screen);
} else if (action === "widget-settings") {
BarService.openWidgetSettings(screen, section, sectionWidgetIndex, widgetId, widgetSettings);
}
+13 -175
View File
@@ -5,6 +5,8 @@ import Quickshell
import Quickshell.Bluetooth
import qs.Commons
import qs.Modules.MainScreen
import qs.Modules.Panels.Settings // For SettingsPanel
import qs.Services.Networking
import qs.Services.UI
import qs.Widgets
@@ -59,25 +61,6 @@ SmartPanel {
baseSize: Style.baseWidgetSize * 0.65
}
// Discoverability toggle (advertising)
NIconButton {
enabled: BluetoothService.enabled
icon: BluetoothService.discoverable ? "broadcast" : "broadcast-off"
tooltipText: I18n.tr("bluetooth.panel.discoverable")
baseSize: Style.baseWidgetSize * 0.8
onClicked: {
BluetoothService.setDiscoverable(!BluetoothService.discoverable);
}
}
NIconButton {
enabled: BluetoothService.enabled
icon: BluetoothService.scanningActive ? "stop" : "refresh"
tooltipText: I18n.tr("tooltips.refresh-devices")
baseSize: Style.baseWidgetSize * 0.8
onClicked: BluetoothService.toggleDiscovery()
}
NIconButton {
icon: "close"
tooltipText: I18n.tr("common.close")
@@ -150,17 +133,18 @@ SmartPanel {
}
}
// Empty state when no devices
// Empty state when no paired devices
NBox {
id: emptyBox
visible: {
if (!(BluetoothService.adapter && BluetoothService.adapter.enabled && BluetoothService.adapter.devices) || BluetoothService.scanningActive)
if (!(BluetoothService.adapter && BluetoothService.adapter.enabled && BluetoothService.adapter.devices))
return false;
var availableCount = BluetoothService.adapter.devices.values.filter(dev => {
return dev && !dev.blocked && (dev.signalStrength === undefined || dev.signalStrength > 0);
}).length;
return (availableCount === 0);
// Check for connected or paired/trusted devices
var knownCount = BluetoothService.adapter.devices.values.filter(dev => {
return dev && !dev.blocked && (dev.connected || dev.paired || dev.trusted);
}).length;
return (knownCount === 0);
}
Layout.fillWidth: true
Layout.preferredHeight: emptyColumn.implicitHeight + Style.marginXL
@@ -190,11 +174,12 @@ SmartPanel {
}
NButton {
text: I18n.tr("tooltips.refresh-devices")
icon: "refresh"
text: I18n.tr("common.settings")
icon: "settings"
Layout.alignment: Qt.AlignHCenter
onClicked: {
BluetoothService.toggleDiscovery();
SettingsPanel.openToTab(SettingsPanel.Tab.Bluetooth);
root.close();
}
}
@@ -235,153 +220,6 @@ SmartPanel {
visible: items.length > 0 && BluetoothService.adapter && BluetoothService.adapter.enabled
Layout.fillWidth: true
}
// Available devices (for pairing)
BluetoothDevicesList {
label: I18n.tr("bluetooth.panel.available-devices")
headerMode: "filter"
property var items: {
if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
return [];
var filtered = BluetoothService.adapter.devices.values.filter(dev => dev && !dev.blocked && !dev.paired && !dev.trusted);
// Optionally hide devices without a meaningful name when the filter is enabled
if (Settings.data && Settings.data.ui && Settings.data.network.bluetoothHideUnnamedDevices) {
filtered = filtered.filter(function (dev) {
// Extract display name
var dn = "";
if (dev && dev.name)
dn = dev.name;
else if (dev && dev.deviceName)
dn = dev.deviceName;
else
dn = "";
if (dn === undefined || dn === null)
dn = "";
var s = String(dn).trim();
// 1) Hide empty or whitespace-only
if (s.length === 0)
return false;
// 2) Hide common placeholders
var lower = s.toLowerCase();
if (lower === "unknown" || lower === "unnamed" || lower === "n/a" || lower === "na")
return false;
// 3) Hide if the name equals the device address (ignoring separators)
var addr = "";
if (dev && dev.address)
addr = String(dev.address);
else if (dev && dev.bdaddr)
addr = String(dev.bdaddr);
else if (dev && dev.mac)
addr = String(dev.mac);
if (addr && addr.length > 0) {
var normName = s.toLowerCase().replace(/[^0-9a-z]/g, "");
var normAddr = addr.toLowerCase().replace(/[^0-9a-z]/g, "");
if (normName.length > 0 && normName === normAddr)
return false;
}
// 4) Hide address-like strings
// - Colon-separated hex: 00:11:22:33:44:55
var macColonHex = /^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$/;
if (macColonHex.test(s))
return false;
// - Hyphen-separated hex: 00-11-22-33-44-55
var macHyphenHex = /^([0-9A-Fa-f]{2}-){5}[0-9A-Fa-f]{2}$/;
if (macHyphenHex.test(s))
return false;
// - Hyphen-separated alnum pairs (to catch non-hex variants like AB-CD-EF-GH-01-23)
var macHyphenAny = /^([0-9A-Za-z]{2}-){5}[0-9A-Za-z]{2}$/;
if (macHyphenAny.test(s))
return false;
// - Cisco dotted hex: 0011.2233.4455
var macDotted = /^[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}$/;
if (macDotted.test(s))
return false;
// - Bare hex: 001122334455
var macBare = /^[0-9A-Fa-f]{12}$/;
if (macBare.test(s))
return false;
// Keep device otherwise (has a meaningful user-facing name)
return true;
});
}
filtered = BluetoothService.dedupeDevices(filtered);
return BluetoothService.sortDevices(filtered);
}
model: items
visible: items.length > 0 && BluetoothService.adapter && BluetoothService.adapter.enabled
Layout.fillWidth: true
}
// Fallback - No devices, scanning
NBox {
id: scanningBox
Layout.fillWidth: true
Layout.preferredHeight: scanningColumn.implicitHeight + Style.marginXL
visible: {
if (!(BluetoothService.adapter && BluetoothService.adapter.enabled && BluetoothService.adapter.devices) || !BluetoothService.scanningActive) {
return false;
}
var availableCount = BluetoothService.adapter.devices.values.filter(dev => {
return dev && !dev.paired && !dev.pairing && !dev.blocked && (dev.signalStrength === undefined || dev.signalStrength > 0);
}).length;
return (availableCount === 0);
}
ColumnLayout {
id: scanningColumn
anchors.fill: parent
anchors.margins: Style.marginM
spacing: Style.marginL
Item {
Layout.fillHeight: true
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
spacing: Style.marginXS
NIcon {
icon: "refresh"
pointSize: Style.fontSizeXXL * 1.5
color: Color.mPrimary
RotationAnimation on rotation {
running: true
loops: Animation.Infinite
from: 0
to: 360
duration: Style.animationSlow * 4
}
}
NText {
text: I18n.tr("bluetooth.panel.scanning")
pointSize: Style.fontSizeL
color: Color.mOnSurface
}
}
NText {
text: I18n.tr("bluetooth.panel.pairing-mode")
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
wrapMode: Text.WordWrap
}
Item {
Layout.fillHeight: true
}
}
}
}
}
}
+27 -26
View File
@@ -1,42 +1,43 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services.Networking
import qs.Services.System
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
spacing: 0
NToggle {
label: I18n.tr("actions.enable-wifi")
description: I18n.tr("panels.network.wifi-description")
checked: ProgramCheckerService.nmcliAvailable && Settings.data.network.wifiEnabled
onToggled: checked => NetworkService.setWifiEnabled(checked)
enabled: ProgramCheckerService.nmcliAvailable
}
NDivider {
NTabBar {
id: subTabBar
Layout.fillWidth: true
Layout.bottomMargin: Style.marginM
distributeEvenly: true
currentIndex: tabView.currentIndex
NTabButton {
text: I18n.tr("common.wifi")
tabIndex: 0
checked: subTabBar.currentIndex === 0
}
NTabButton {
text: I18n.tr("common.bluetooth")
tabIndex: 1
checked: subTabBar.currentIndex === 1
}
}
// Bluetooth adapter toggle grouped with its panel settings
NToggle {
label: I18n.tr("actions.enable-bluetooth")
description: I18n.tr("panels.network.bluetooth-description")
checked: BluetoothService.enabled
onToggled: checked => BluetoothService.setBluetoothEnabled(checked)
Item {
Layout.fillWidth: true
Layout.preferredHeight: Style.marginL
}
// Bluetooth signal strength polling (RSSI via bluetoothctl)
NToggle {
label: I18n.tr("panels.network.bluetooth-rssi-polling-label")
description: I18n.tr("panels.network.bluetooth-rssi-polling-description")
checked: Settings.data && Settings.data.network && Settings.data.network.bluetoothRssiPollingEnabled
enabled: BluetoothService.enabled
onToggled: checked => Settings.data.network.bluetoothRssiPollingEnabled = checked
NTabView {
id: tabView
Layout.fillHeight: true
currentIndex: subTabBar.currentIndex
WifiSubTab {}
BluetoothSubTab {}
}
}
@@ -0,0 +1,22 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services.Networking
import qs.Services.System
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
Layout.fillWidth: true
NToggle {
label: I18n.tr("actions.enable-wifi")
description: I18n.tr("panels.network.wifi-description")
checked: ProgramCheckerService.nmcliAvailable && Settings.data.network.wifiEnabled
onToggled: checked => NetworkService.setWifiEnabled(checked)
enabled: ProgramCheckerService.nmcliAvailable
}
}