// Copyright (C) 2026 Danilo M. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. import Quickshell.Io import QtQuick // The one action that is not native. Quickshell ships no BlueZ agent and no // generic D-Bus module, so a device that needs a passkey or PIN confirmed // cannot be paired from QML. bluetoothctl registers its own agent and handles // the prompt, so pairing goes through it and everything else stays native. // // ponytail: one-shot bluetoothctl with a timeout, keyed on the exit code. If // a device needs input bluetoothctl cannot auto-confirm, pairing times out // and the error surfaces; upgrade to driving interactive bluetoothctl only // when a real device needs it. QtObject { id: root property string address: "" property string error: "" readonly property bool busy: proc.running signal finished(string address, bool ok) function pair(address) { root.address = address; root.error = ""; proc.command = ["bluetoothctl", "--timeout", "20", "pair", address]; proc.running = false; proc.running = true; } property Process proc: Process { stdout: StdioCollector { id: out } stderr: StdioCollector { id: err } onExited: code => { const ok = code === 0; if (!ok) root.error = (err.text.trim() || out.text.trim() || ("bluetoothctl exited " + code)); root.finished(root.address, ok); } } }