1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-08 22:45:38 -05:00
Files
DankMaterialShell/Services/NetworkService.qml
2025-07-22 11:50:07 -04:00

450 lines
19 KiB
QML

pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Common
Singleton {
id: root
property string networkStatus: "disconnected" // "ethernet", "wifi", "disconnected"
property string ethernetIP: ""
property string ethernetInterface: ""
property bool ethernetConnected: false
property string wifiIP: ""
property bool wifiAvailable: false
property bool wifiEnabled: true
property bool wifiToggling: false
property string userPreference: "auto" // "auto", "wifi", "ethernet"
property bool changingPreference: false
property string targetPreference: "" // Track what preference we're switching to
// Load saved preference on startup
Component.onCompleted: {
// Load preference from Prefs system
root.userPreference = Prefs.networkPreference
console.log("NetworkService: Loaded network preference from Prefs:", root.userPreference)
// Trigger immediate WiFi info update if WiFi is connected and enabled
if (root.networkStatus === "wifi" && root.wifiEnabled) {
WifiService.updateCurrentWifiInfo()
}
}
// Real Network Management
Process {
id: networkStatusChecker
command: ["sh", "-c", "nmcli -t -f DEVICE,TYPE,STATE device | grep -E '(ethernet|wifi)' && echo '---' && ip link show | grep -E '^[0-9]+:.*ethernet.*state UP'"]
running: true
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
console.log("Network status full output:", text.trim())
let hasEthernet = text.includes("ethernet:connected")
let hasWifi = text.includes("wifi:connected")
let ethernetCableUp = text.includes("state UP")
// Update connection status properties
root.ethernetConnected = hasEthernet || ethernetCableUp
// Always check both IPs when available
if (hasWifi) {
wifiIPChecker.running = true
}
if (hasEthernet || ethernetCableUp) {
ethernetIPChecker.running = true
}
// Check connection priorities when both are active
if (hasWifi && hasEthernet) {
console.log("Both WiFi and Ethernet connected, user preference:", root.userPreference)
// Use user preference if set, otherwise check default route
if (root.userPreference === "wifi") {
root.networkStatus = "wifi"
console.log("User prefers WiFi, setting status to wifi")
if (root.wifiEnabled) {
WifiService.updateCurrentWifiInfo()
}
} else if (root.userPreference === "ethernet") {
root.networkStatus = "ethernet"
console.log("User prefers Ethernet, setting status to ethernet")
} else {
// Auto mode - check which interface has the default route
defaultRouteChecker.running = true
}
} else if (hasWifi) {
root.networkStatus = "wifi"
console.log("Only WiFi connected, setting status to wifi")
// Trigger WiFi SSID update
if (root.wifiEnabled) {
WifiService.updateCurrentWifiInfo()
}
} else if (hasEthernet || ethernetCableUp) {
root.networkStatus = "ethernet"
console.log("Only Ethernet connected, setting status to ethernet")
} else {
root.networkStatus = "disconnected"
root.ethernetIP = ""
root.ethernetInterface = ""
root.ethernetConnected = false
root.wifiIP = ""
console.log("Setting network status to disconnected")
}
// Check if we're done changing preferences
if (root.changingPreference && root.targetPreference !== "") {
let preferenceComplete = false
if (root.targetPreference === "wifi" && root.networkStatus === "wifi") {
preferenceComplete = true
console.log("WiFi preference change complete - network is now using WiFi")
} else if (root.targetPreference === "ethernet" && root.networkStatus === "ethernet") {
preferenceComplete = true
console.log("Ethernet preference change complete - network is now using Ethernet")
}
if (preferenceComplete) {
root.changingPreference = false
root.targetPreference = ""
console.log("Network preference change completed successfully")
}
}
// Always check WiFi radio status
wifiRadioChecker.running = true
} else {
root.networkStatus = "disconnected"
root.ethernetIP = ""
root.ethernetInterface = ""
root.ethernetConnected = false
root.wifiIP = ""
console.log("No network output, setting to disconnected")
}
}
}
}
Process {
id: defaultRouteChecker
command: ["sh", "-c", "ip route show default | head -1 | cut -d' ' -f5"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: function(data) {
let defaultInterface = data.trim()
console.log("Default route interface:", defaultInterface)
// Check if the interface is wifi or ethernet
if (defaultInterface.startsWith("wl") || defaultInterface.includes("wifi")) {
root.networkStatus = "wifi"
console.log("WiFi interface has default route, setting status to wifi")
// Trigger WiFi SSID update
if (root.wifiEnabled) {
WifiService.updateCurrentWifiInfo()
}
} else if (defaultInterface.startsWith("en") || defaultInterface.includes("eth")) {
root.networkStatus = "ethernet"
console.log("Ethernet interface has default route, setting status to ethernet")
} else {
root.networkStatus = "disconnected"
console.log("Unknown interface type:", defaultInterface)
}
}
}
}
Process {
id: wifiRadioChecker
command: ["nmcli", "radio", "wifi"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: function(data) {
let response = data.trim()
root.wifiAvailable = response === "enabled" || response === "disabled"
root.wifiEnabled = response === "enabled"
console.log("WiFi available:", root.wifiAvailable, "enabled:", root.wifiEnabled)
}
}
}
Process {
id: ethernetIPChecker
command: ["sh", "-c", "ETH_DEV=$(nmcli -t -f DEVICE,TYPE device | grep ethernet | grep connected | cut -d: -f1 | head -1); if [ -n \"$ETH_DEV\" ]; then nmcli -t -f IP4.ADDRESS dev show \"$ETH_DEV\" | cut -d: -f2 | cut -d/ -f1 | head -1; fi"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: function(data) {
if (data.trim()) {
root.ethernetIP = data.trim()
console.log("Ethernet IP:", root.ethernetIP)
// Get the ethernet interface name
ethernetInterfaceChecker.running = true
} else {
console.log("No ethernet IP found")
root.ethernetIP = ""
root.ethernetInterface = ""
}
}
}
}
Process {
id: ethernetInterfaceChecker
command: ["sh", "-c", "nmcli -t -f DEVICE,TYPE device | grep ethernet | grep connected | cut -d: -f1 | head -1"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: function(interfaceData) {
if (interfaceData.trim()) {
root.ethernetInterface = interfaceData.trim()
console.log("Ethernet Interface:", root.ethernetInterface)
// Ethernet interface detected - status will be determined by route checking
console.log("Ethernet interface detected:", root.ethernetInterface)
}
}
}
}
Process {
id: wifiIPChecker
command: ["sh", "-c", "WIFI_DEV=$(nmcli -t -f DEVICE,TYPE device | grep wifi | grep connected | cut -d: -f1 | head -1); if [ -n \"$WIFI_DEV\" ]; then nmcli -t -f IP4.ADDRESS dev show \"$WIFI_DEV\" | cut -d: -f2 | cut -d/ -f1 | head -1; fi"]
running: false
stdout: SplitParser {
splitMarker: "\n"
onRead: function(data) {
if (data.trim()) {
root.wifiIP = data.trim()
console.log("WiFi IP:", root.wifiIP)
// WiFi IP detected - status will be determined by route checking
console.log("WiFi has IP:", root.wifiIP)
} else {
console.log("No WiFi IP found")
root.wifiIP = ""
}
}
}
}
// Static processes for network operations
Process {
id: ethernetDisconnector
command: ["sh", "-c", "nmcli device disconnect $(nmcli -t -f DEVICE,TYPE device | grep ethernet | cut -d: -f1 | head -1)"]
running: false
onExited: function(exitCode) {
console.log("Ethernet disconnect result:", exitCode)
delayedRefreshNetworkStatus()
}
stderr: SplitParser {
splitMarker: "\n"
onRead: function(data) {
console.log("Ethernet disconnect stderr:", data)
}
}
}
Process {
id: ethernetConnector
command: ["sh", "-c", "ETH_DEV=$(nmcli -t -f DEVICE,TYPE device | grep ethernet | cut -d: -f1 | head -1); if [ -n \"$ETH_DEV\" ]; then nmcli device connect \"$ETH_DEV\"; ETH_CONN=$(nmcli -t -f NAME,DEVICE connection show --active | grep \"$ETH_DEV\" | cut -d: -f1); if [ -n \"$ETH_CONN\" ]; then nmcli connection modify \"$ETH_CONN\" connection.autoconnect-priority 100; nmcli connection down \"$ETH_CONN\"; nmcli connection up \"$ETH_CONN\"; fi; else echo \"No ethernet device found\"; exit 1; fi"]
running: false
onExited: function(exitCode) {
console.log("Ethernet connect result:", exitCode)
if (exitCode === 0) {
console.log("Ethernet connected successfully with higher priority")
} else {
console.log("Ethernet connection failed")
}
delayedRefreshNetworkStatus()
}
stderr: SplitParser {
splitMarker: "\n"
onRead: function(data) {
console.log("Ethernet connect stderr:", data)
}
}
}
Process {
id: wifiDeviceConnector
command: ["sh", "-c", "WIFI_DEV=$(nmcli -t -f DEVICE,TYPE device | grep wifi | cut -d: -f1 | head -1); if [ -n \"$WIFI_DEV\" ]; then nmcli device connect \"$WIFI_DEV\"; else echo \"No WiFi device found\"; exit 1; fi"]
running: false
onExited: function(exitCode) {
console.log("WiFi device connect result:", exitCode)
delayedRefreshNetworkStatus()
}
stderr: SplitParser {
splitMarker: "\n"
onRead: function(data) {
console.log("WiFi device connect stderr:", data)
}
}
}
Process {
id: wifiSwitcher
command: ["sh", "-c", "ETH_DEV=$(nmcli -t -f DEVICE,TYPE device | grep ethernet | cut -d: -f1 | head -1); WIFI_DEV=$(nmcli -t -f DEVICE,TYPE device | grep wifi | cut -d: -f1 | head -1); [ -n \"$ETH_DEV\" ] && nmcli device disconnect \"$ETH_DEV\" 2>/dev/null; [ -n \"$WIFI_DEV\" ] && nmcli device connect \"$WIFI_DEV\" 2>/dev/null || true"]
running: false
onExited: function(exitCode) {
console.log("Switch to wifi result:", exitCode)
delayedRefreshNetworkStatus()
}
stderr: SplitParser {
splitMarker: "\n"
onRead: function(data) {
console.log("Switch to wifi stderr:", data)
}
}
}
Process {
id: ethernetSwitcher
command: ["sh", "-c", "WIFI_DEV=$(nmcli -t -f DEVICE,TYPE device | grep wifi | cut -d: -f1 | head -1); ETH_DEV=$(nmcli -t -f DEVICE,TYPE device | grep ethernet | cut -d: -f1 | head -1); [ -n \"$WIFI_DEV\" ] && nmcli device disconnect \"$WIFI_DEV\" 2>/dev/null; [ -n \"$ETH_DEV\" ] && nmcli device connect \"$ETH_DEV\" 2>/dev/null || true"]
running: false
onExited: function(exitCode) {
console.log("Switch to ethernet result:", exitCode)
delayedRefreshNetworkStatus()
}
stderr: SplitParser {
splitMarker: "\n"
onRead: function(data) {
console.log("Switch to ethernet stderr:", data)
}
}
}
Process {
id: wifiRadioToggler
command: ["nmcli", "radio", "wifi", root.wifiEnabled ? "off" : "on"]
running: false
onExited: {
root.wifiToggling = false
networkStatusChecker.running = true
}
}
Process {
id: wifiPriorityChanger
command: ["sh", "-c", "nmcli -t -f NAME,TYPE connection show | grep 802-11-wireless | cut -d: -f1 | while read conn; do nmcli connection modify \"$conn\" ipv4.route-metric 50; done; nmcli -t -f NAME,TYPE connection show | grep 802-3-ethernet | cut -d: -f1 | while read conn; do nmcli connection modify \"$conn\" ipv4.route-metric 200; done; nmcli -t -f NAME,TYPE connection show --active | grep -E \"(802-11-wireless|802-3-ethernet)\" | cut -d: -f1 | while read conn; do nmcli connection down \"$conn\" && nmcli connection up \"$conn\"; done"]
running: false
onExited: function(exitCode) {
console.log("WiFi route metric set to 50, ethernet to 200, connections restarted, exit code:", exitCode)
// Don't reset changingPreference here - let network status check handle it
delayedRefreshNetworkStatus()
}
}
Process {
id: ethernetPriorityChanger
command: ["sh", "-c", "nmcli -t -f NAME,TYPE connection show | grep 802-3-ethernet | cut -d: -f1 | while read conn; do nmcli connection modify \"$conn\" ipv4.route-metric 50; done; nmcli -t -f NAME,TYPE connection show | grep 802-11-wireless | cut -d: -f1 | while read conn; do nmcli connection modify \"$conn\" ipv4.route-metric 200; done; nmcli -t -f NAME,TYPE connection show --active | grep -E \"(802-11-wireless|802-3-ethernet)\" | cut -d: -f1 | while read conn; do nmcli connection down \"$conn\" && nmcli connection up \"$conn\"; done"]
running: false
onExited: function(exitCode) {
console.log("Ethernet route metric set to 50, WiFi to 200, connections restarted, exit code:", exitCode)
// Don't reset changingPreference here - let network status check handle it
delayedRefreshNetworkStatus()
}
}
function toggleNetworkConnection(type) {
if (type === "ethernet") {
// Toggle ethernet connection
if (root.networkStatus === "ethernet") {
// Disconnect ethernet
console.log("Disconnecting ethernet...")
ethernetDisconnector.running = true
} else {
// Connect ethernet and set higher priority
console.log("Connecting ethernet...")
ethernetConnector.running = true
}
} else if (type === "wifi") {
// Connect to WiFi if disconnected
if (root.networkStatus !== "wifi" && root.wifiEnabled) {
console.log("Connecting to WiFi device...")
wifiDeviceConnector.running = true
}
}
}
function switchToWifi() {
console.log("Switching to WiFi")
// Disconnect ethernet first, then try to connect to a known WiFi network
wifiSwitcher.running = true
}
function switchToEthernet() {
console.log("Switching to Ethernet")
// Disconnect WiFi first, then connect ethernet
ethernetSwitcher.running = true
}
function toggleWifiRadio() {
if (root.wifiToggling) return
root.wifiToggling = true
wifiRadioToggler.command = ["nmcli", "radio", "wifi", root.wifiEnabled ? "off" : "on"]
wifiRadioToggler.running = true
}
function refreshNetworkStatus() {
console.log("Refreshing network status...")
networkStatusChecker.running = true
}
function delayedRefreshNetworkStatus() {
console.log("Refreshing network status immediately...")
refreshNetworkStatus()
}
function setNetworkPreference(preference) {
console.log("Setting network preference to:", preference)
root.userPreference = preference
root.changingPreference = true
root.targetPreference = preference
Prefs.setNetworkPreference(preference)
if (preference === "wifi") {
// Set WiFi to low route metric (high priority), ethernet to high route metric (low priority)
wifiPriorityChanger.running = true
} else if (preference === "ethernet") {
// Set ethernet to low route metric (high priority), WiFi to high route metric (low priority)
ethernetPriorityChanger.running = true
}
}
function connectToWifiAndSetPreference(ssid, password) {
console.log("Connecting to WiFi and setting preference:", ssid)
if (!root.wifiEnabled) {
console.log("WiFi is disabled, cannot connect to network")
return
}
root.userPreference = "wifi"
Prefs.setNetworkPreference("wifi")
WifiService.connectToWifiWithPassword(ssid, password)
}
}