ProgramCheckerService: move bluetoothctl check from BluetoothService here

This commit is contained in:
Lysec
2026-02-18 14:24:29 +01:00
parent a3853caf1c
commit 7e9694c4dc
2 changed files with 19 additions and 31 deletions
+17 -31
View File
@@ -6,6 +6,7 @@ import Quickshell.Bluetooth
import Quickshell.Io
import "../../Helpers/BluetoothUtils.js" as BluetoothUtils
import qs.Commons
import qs.Services.System
import qs.Services.UI
Singleton {
@@ -66,8 +67,6 @@ Singleton {
// Internal: temporarily pause discovery during pair/connect to reduce HCI churn
property bool _discoveryWasRunning: false
property bool _ctlInit: false
// Track whether the bluetoothctl CLI is available on the system
property bool ctlBinaryAvailable: false
Timer {
id: initDelayTimer
@@ -116,6 +115,16 @@ Singleton {
}
}
// Re-run polling once bluetoothctl availability is known
Connections {
target: ProgramCheckerService
function onBluetoothctlAvailableChanged() {
if (!adapter && ProgramCheckerService.bluetoothctlAvailable) {
requestCtlPoll(0);
}
}
}
function setAirplaneMode(state) {
if (state) {
Quickshell.execDetached(["rfkill", "block", "wifi"]);
@@ -184,7 +193,7 @@ Singleton {
id: ctlPollTimer
interval: adapter ? ctlPollMs : 2000
repeat: true
running: adapter || root.ctlBinaryAvailable
running: adapter || ProgramCheckerService.bluetoothctlAvailable
onTriggered: {
pollCtlState();
var targetInterval = adapter ? ctlPollMs : 2000;
@@ -195,7 +204,7 @@ Singleton {
}
function requestCtlPoll(delayMs) {
if (!adapter && !root.ctlBinaryAvailable) {
if (!adapter && !ProgramCheckerService.bluetoothctlAvailable) {
return;
}
ctlPollTimer.interval = Math.max(50, delayMs || ctlPollSoonMs);
@@ -203,7 +212,7 @@ Singleton {
}
function pollCtlState() {
if (!adapter && !root.ctlBinaryAvailable) {
if (!adapter && !ProgramCheckerService.bluetoothctlAvailable) {
return;
}
if (ctlShowProcess.running) {
@@ -214,29 +223,6 @@ Singleton {
} catch (_) {}
}
// One-time detection of bluetoothctl binary presence to avoid spamming logs on systems without Bluetooth
Process {
id: ctlBinaryCheck
running: true
command: ["sh", "-c", "command -v bluetoothctl >/dev/null 2>&1 && echo yes || echo no"]
stdout: StdioCollector {
onStreamFinished: {
var available = (text || "").trim() === "yes";
root.ctlBinaryAvailable = available;
if (!available) {
Logger.i("Bluetooth", "bluetoothctl not found; disabling CLI fallback polling");
}
}
}
stderr: StdioCollector {
onStreamFinished: {
if (text && text.trim()) {
Logger.d("Bluetooth", "bluetoothctl check stderr:", text.trim());
}
}
}
}
// bluetoothctl state polling
Process {
id: ctlShowProcess
@@ -311,7 +297,7 @@ Singleton {
// Unify discovery controls
function setScanActive(active) {
if (!adapter && !root.ctlBinaryAvailable) {
if (!adapter && !ProgramCheckerService.bluetoothctlAvailable) {
Logger.d("Bluetooth", "Scan request ignored: bluetoothctl unavailable");
return;
}
@@ -344,7 +330,7 @@ Singleton {
// Adapter power (enable/disable) via bluetoothctl
function setBluetoothEnabled(state) {
Logger.i("Bluetooth", "SetBluetoothEnabled", state);
if (!adapter && !root.ctlBinaryAvailable) {
if (!adapter && !ProgramCheckerService.bluetoothctlAvailable) {
Logger.i("Bluetooth", "Enable/Disable skipped: no adapter or bluetoothctl");
return;
}
@@ -366,7 +352,7 @@ Singleton {
// Toggle adapter discoverability (advertising visibility) via bluetoothctl
function setDiscoverable(state) {
if (!adapter && !root.ctlBinaryAvailable) {
if (!adapter && !ProgramCheckerService.bluetoothctlAvailable) {
Logger.d("Bluetooth", "Discoverable change skipped: no adapter or bluetoothctl");
return;
}