pragma Singleton pragma ComponentBehavior: Bound import QtQuick import Quickshell import Quickshell.Io Singleton { id: root property string currentWifiSSID: "" property string wifiSignalStrength: "excellent" // "excellent", "good", "fair", "poor" property var wifiNetworks: [] property var savedWifiNetworks: [] property bool isScanning: false property string connectionStatus: "" // "cosnnecting", "connected", "failed", "" property string connectingSSID: "" // Auto-refresh timer for when control center is open property bool autoRefreshEnabled: false function scanWifi() { if (root.isScanning) return ; root.isScanning = true; console.log("Starting WiFi scan..."); wifiScanner.running = true; savedWifiScanner.running = true; currentWifiInfo.running = true; // Fallback timer in case no networks are found fallbackTimer.start(); } function connectToWifi(ssid) { console.log("Connecting to WiFi:", ssid); root.connectionStatus = "connecting"; root.connectingSSID = ssid; let connectProcess = Qt.createQmlObject(` import Quickshell.Io Process { command: ["bash", "-c", "nmcli dev wifi connect \\"' + ssid + '\\" || nmcli connection up \\"' + ssid + '\\"; if [ $? -eq 0 ]; then nmcli connection modify \\"' + ssid + '\\" connection.autoconnect-priority 50; nmcli connection down \\"' + ssid + '\\"; nmcli connection up \\"' + ssid + '\\"; fi"] running: true onExited: (exitCode) => { console.log("WiFi connection result:", exitCode) if (exitCode === 0) { root.connectionStatus = "connected" console.log("Connected to WiFi successfully") // Set user preference to WiFi when manually connecting NetworkService.setNetworkPreference("wifi") // Force network status refresh after successful connection NetworkService.delayedRefreshNetworkStatus() } else { root.connectionStatus = "failed" console.log("WiFi connection failed") } scanWifi() statusResetTimer.start() } stderr: SplitParser { splitMarker: "\\n" onRead: (data) => { console.log("WiFi connection stderr:", data) } } } `, root); } function connectToWifiWithPassword(ssid, password) { console.log("Connecting to WiFi with password:", ssid); root.connectionStatus = "connecting"; root.connectingSSID = ssid; let connectProcess = Qt.createQmlObject(` import Quickshell.Io Process { command: ["bash", "-c", "nmcli dev wifi connect \\"' + ssid + '\\" password \\"' + password + '\\"; if [ $? -eq 0 ]; then nmcli connection modify \\"' + ssid + '\\" connection.autoconnect-priority 50; nmcli connection down \\"' + ssid + '\\"; nmcli connection up \\"' + ssid + '\\"; fi"] running: true onExited: (exitCode) => { console.log("WiFi connection with password result:", exitCode) if (exitCode === 0) { root.connectionStatus = "connected" console.log("Connected to WiFi with password successfully") // Set user preference to WiFi when manually connecting NetworkService.setNetworkPreference("wifi") // Force network status refresh after successful connection NetworkService.delayedRefreshNetworkStatus() } else { root.connectionStatus = "failed" console.log("WiFi connection with password failed") } scanWifi() statusResetTimer.start() } stderr: SplitParser { splitMarker: "\\n" onRead: (data) => { console.log("WiFi connection with password stderr:", data) } } } `, root); } function forgetWifiNetwork(ssid) { console.log("Forgetting WiFi network:", ssid); let forgetProcess = Qt.createQmlObject(` import Quickshell.Io Process { command: ["bash", "-c", "nmcli connection delete \\"' + ssid + '\\" || nmcli connection delete id \\"' + ssid + '\\""] running: true onExited: (exitCode) => { console.log("WiFi forget result:", exitCode) if (exitCode === 0) { console.log("Successfully forgot WiFi network:", "' + ssid + '") } else { console.log("Failed to forget WiFi network:", "' + ssid + '") } scanWifi() } stderr: SplitParser { splitMarker: "\\n" onRead: (data) => { console.log("WiFi forget stderr:", data) } } } `, root); } function updateCurrentWifiInfo() { console.log("Updating current WiFi info..."); currentWifiInfo.running = true; } Process { id: currentWifiInfo command: ["bash", "-c", "nmcli -t -f ACTIVE,SSID,SIGNAL dev wifi | grep '^yes' | head -1"] running: false stdout: SplitParser { splitMarker: "\n" onRead: (data) => { if (data.trim()) { let parts = data.split(":"); if (parts.length >= 3 && parts[1].trim() !== "") { root.currentWifiSSID = parts[1].trim(); let signal = parseInt(parts[2]) || 100; if (signal >= 75) root.wifiSignalStrength = "excellent"; else if (signal >= 50) root.wifiSignalStrength = "good"; else if (signal >= 25) root.wifiSignalStrength = "fair"; else root.wifiSignalStrength = "poor"; console.log("Active WiFi:", root.currentWifiSSID, "Signal:", signal + "%"); } } } } } Process { id: wifiScanner command: ["nmcli", "-t", "-f", "SSID,SIGNAL,SECURITY", "dev", "wifi"] running: false stdout: StdioCollector { onStreamFinished: { if (text.trim()) { let networks = []; let lines = text.trim().split('\n'); for (let line of lines) { let parts = line.split(':'); if (parts.length >= 3 && parts[0].trim() !== "") { let ssid = parts[0].trim(); let signal = parseInt(parts[1]) || 0; let security = parts[2].trim(); // Skip duplicates if (!networks.find((n) => { return n.ssid === ssid; })) { // Check if this network is saved let isSaved = root.savedWifiNetworks.some((saved) => { return saved.ssid === ssid; }); networks.push({ "ssid": ssid, "signal": signal, "secured": security !== "", "connected": ssid === root.currentWifiSSID, "saved": isSaved, "signalStrength": signal >= 75 ? "excellent" : signal >= 50 ? "good" : signal >= 25 ? "fair" : "poor" }); } } } // Sort by signal strength networks.sort((a, b) => { return b.signal - a.signal; }); root.wifiNetworks = networks; console.log("Found", networks.length, "WiFi networks"); // Stop scanning once we have results if (networks.length > 0) { root.isScanning = false; fallbackTimer.stop(); } } } } } Process { id: savedWifiScanner command: ["nmcli", "-t", "-f", "NAME", "connection", "show"] running: false stdout: StdioCollector { onStreamFinished: { if (text.trim()) { let saved = []; let lines = text.trim().split('\n'); for (let line of lines) { let connectionName = line.trim(); if (connectionName && !connectionName.includes("ethernet") && !connectionName.includes("lo") && !connectionName.includes("Wired") && !connectionName.toLowerCase().includes("eth")) saved.push({ "ssid": connectionName, "saved": true }); } root.savedWifiNetworks = saved; console.log("Found", saved.length, "saved WiFi networks"); } } } } Timer { id: fallbackTimer interval: 5000 onTriggered: { root.isScanning = false; console.log("WiFi scan timeout - no networks found"); } } Timer { id: statusResetTimer interval: 3000 onTriggered: { root.connectionStatus = ""; root.connectingSSID = ""; } } Timer { id: autoRefreshTimer interval: 20000 running: root.autoRefreshEnabled repeat: true onTriggered: { if (root.autoRefreshEnabled) root.scanWifi(); } } }