mirror of
https://github.com/belsabbagh/dotfiles.git
synced 2026-04-11 09:36:46 +00:00
quickshell and hyprland additions
This commit is contained in:
309
.config/quickshell/nucleus-shell/services/Network.qml
Executable file
309
.config/quickshell/nucleus-shell/services/Network.qml
Executable file
@@ -0,0 +1,309 @@
|
||||
pragma Singleton
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property list<Connection> connections: []
|
||||
readonly property list<string> savedNetworks: []
|
||||
readonly property Connection active: connections.find(c => c.active) ?? null
|
||||
|
||||
property bool wifiEnabled: true
|
||||
readonly property bool scanning: rescanProc.running
|
||||
|
||||
property string lastNetworkAttempt: ""
|
||||
property string lastErrorMessage: ""
|
||||
property string message: ""
|
||||
|
||||
readonly property string icon: {
|
||||
if (!active) return "signal_wifi_off";
|
||||
if (active.type === "ethernet") return "settings_ethernet";
|
||||
|
||||
if (active.strength >= 75) return "network_wifi";
|
||||
else if (active.strength >= 50) return "network_wifi_3_bar";
|
||||
else if (active.strength >= 25) return "network_wifi_2_bar";
|
||||
else return "network_wifi_1_bar";
|
||||
}
|
||||
|
||||
readonly property string wifiLabel: {
|
||||
const activeWifi = connections.find(c => c.active && c.type === "wifi");
|
||||
if (activeWifi) return activeWifi.name;
|
||||
return "Wi-Fi";
|
||||
}
|
||||
|
||||
readonly property string wifiStatus: {
|
||||
const activeWifi = connections.find(c => c.active && c.type === "wifi");
|
||||
if (activeWifi) return "Connected";
|
||||
if (wifiEnabled) return "On";
|
||||
return "Off";
|
||||
}
|
||||
|
||||
readonly property string label: {
|
||||
if (active) return active.name;
|
||||
if (wifiEnabled) return "Wi-Fi";
|
||||
return "Wi-Fi";
|
||||
}
|
||||
|
||||
readonly property string status: {
|
||||
if (active) return "Connected";
|
||||
if (wifiEnabled) return "On";
|
||||
return "Off";
|
||||
}
|
||||
|
||||
function enableWifi(enabled: bool): void {
|
||||
enableWifiProc.exec(["nmcli", "radio", "wifi", enabled ? "on" : "off"]);
|
||||
}
|
||||
|
||||
function toggleWifi(): void {
|
||||
enableWifi(!wifiEnabled);
|
||||
}
|
||||
|
||||
function rescan(): void {
|
||||
rescanProc.running = true;
|
||||
}
|
||||
|
||||
function connect(connection: Connection, password: string): void {
|
||||
if (connection.type === "wifi") {
|
||||
root.lastNetworkAttempt = connection.name;
|
||||
root.lastErrorMessage = "";
|
||||
root.message = "";
|
||||
|
||||
if (password && password.length > 0) {
|
||||
connectProc.exec(["nmcli", "dev", "wifi", "connect", connection.name, "password", password]);
|
||||
} else {
|
||||
connectProc.exec(["nmcli", "dev", "wifi", "connect", connection.name]);
|
||||
}
|
||||
} else if (connection.type === "ethernet") {
|
||||
ethConnectProc.exec(["nmcli", "connection", "up", connection.uuid]);
|
||||
}
|
||||
}
|
||||
|
||||
function disconnect(): void {
|
||||
if (!active) return;
|
||||
|
||||
if (active.type === "wifi") {
|
||||
disconnectProc.exec(["nmcli", "connection", "down", active.name]);
|
||||
} else if (active.type === "ethernet") {
|
||||
ethDisconnectProc.exec(["nmcli", "connection", "down", active.uuid]);
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
running: true
|
||||
command: ["nmcli", "m"]
|
||||
stdout: SplitParser {
|
||||
onRead: {
|
||||
getWifiStatus();
|
||||
updateConnections();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getWifiStatus(): void {
|
||||
wifiStatusProc.running = true;
|
||||
}
|
||||
|
||||
function updateConnections(): void {
|
||||
getWifiNetworks.running = true;
|
||||
getEthConnections.running = true;
|
||||
getSavedNetworks.running = true;
|
||||
}
|
||||
|
||||
Process {
|
||||
id: wifiStatusProc
|
||||
running: true
|
||||
command: ["nmcli", "radio", "wifi"]
|
||||
environment: ({ LANG: "C.UTF-8", LC_ALL: "C.UTF-8" })
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
root.wifiEnabled = text.trim() === "enabled";
|
||||
if (!root.wifiEnabled) {
|
||||
root.lastErrorMessage = "";
|
||||
root.message = "";
|
||||
root.lastNetworkAttempt = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: enableWifiProc
|
||||
onExited: updateConnections()
|
||||
}
|
||||
|
||||
Process {
|
||||
id: rescanProc
|
||||
command: ["nmcli", "dev", "wifi", "list", "--rescan", "yes"]
|
||||
onExited: updateConnections()
|
||||
}
|
||||
|
||||
Process {
|
||||
id: connectProc
|
||||
stdout: StdioCollector { }
|
||||
stderr: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (text.includes("Error") || text.includes("incorrect")) {
|
||||
root.lastErrorMessage = "Incorrect password";
|
||||
}
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (exitCode === 0) {
|
||||
root.message = "ok";
|
||||
root.lastErrorMessage = "";
|
||||
} else {
|
||||
root.message = root.lastErrorMessage !== "" ? root.lastErrorMessage : "Connection failed";
|
||||
}
|
||||
updateConnections();
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: disconnectProc
|
||||
onExited: updateConnections()
|
||||
}
|
||||
|
||||
Process {
|
||||
id: ethConnectProc
|
||||
onExited: updateConnections()
|
||||
}
|
||||
|
||||
Process {
|
||||
id: ethDisconnectProc
|
||||
onExited: updateConnections()
|
||||
}
|
||||
|
||||
Process {
|
||||
id: getSavedNetworks
|
||||
running: true
|
||||
command: ["nmcli", "-g", "NAME,TYPE", "connection", "show"]
|
||||
environment: ({ LANG: "C.UTF-8", LC_ALL: "C.UTF-8" })
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
const lines = text.trim().split("\n");
|
||||
const wifiConnections = lines
|
||||
.map(line => line.split(":"))
|
||||
.filter(parts => parts[1] === "802-11-wireless")
|
||||
.map(parts => parts[0]);
|
||||
root.savedNetworks = wifiConnections;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: getWifiNetworks
|
||||
running: true
|
||||
command: ["nmcli", "-g", "ACTIVE,SIGNAL,FREQ,SSID,BSSID,SECURITY", "d", "w"]
|
||||
environment: ({ LANG: "C.UTF-8", LC_ALL: "C.UTF-8" })
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
const PLACEHOLDER = "STRINGWHICHHOPEFULLYWONTBEUSED";
|
||||
const rep = new RegExp("\\\\:", "g");
|
||||
const rep2 = new RegExp(PLACEHOLDER, "g");
|
||||
|
||||
const allNetworks = text.trim().split("\n").map(n => {
|
||||
const net = n.replace(rep, PLACEHOLDER).split(":");
|
||||
return {
|
||||
type: "wifi",
|
||||
active: net[0] === "yes",
|
||||
strength: parseInt(net[1]),
|
||||
frequency: parseInt(net[2]),
|
||||
name: net[3]?.replace(rep2, ":") ?? "",
|
||||
bssid: net[4]?.replace(rep2, ":") ?? "",
|
||||
security: net[5] ?? "",
|
||||
saved: root.savedNetworks.includes(net[3] ?? ""),
|
||||
uuid: "",
|
||||
device: ""
|
||||
};
|
||||
}).filter(n => n.name && n.name.length > 0);
|
||||
|
||||
const networkMap = new Map();
|
||||
for (const network of allNetworks) {
|
||||
const existing = networkMap.get(network.name);
|
||||
if (!existing) {
|
||||
networkMap.set(network.name, network);
|
||||
} else {
|
||||
if (network.active && !existing.active) {
|
||||
networkMap.set(network.name, network);
|
||||
} else if (!network.active && !existing.active && network.strength > existing.strength) {
|
||||
networkMap.set(network.name, network);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mergeConnections(Array.from(networkMap.values()), "wifi");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: getEthConnections
|
||||
running: true
|
||||
command: ["nmcli", "-g", "NAME,UUID,TYPE,DEVICE,STATE", "connection", "show"]
|
||||
environment: ({ LANG: "C.UTF-8", LC_ALL: "C.UTF-8" })
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
const lines = text.trim().split("\n");
|
||||
const ethConns = lines
|
||||
.map(line => line.split(":"))
|
||||
.filter(parts => parts[2] === "802-3-ethernet" || parts[2] === "gsm" || parts[2] === "bluetooth")
|
||||
.map(parts => ({
|
||||
type: "ethernet",
|
||||
name: parts[0],
|
||||
uuid: parts[1],
|
||||
device: parts[3],
|
||||
active: parts[4] === "activated",
|
||||
strength: 100,
|
||||
frequency: 0,
|
||||
bssid: "",
|
||||
security: "",
|
||||
saved: true
|
||||
}));
|
||||
|
||||
mergeConnections(ethConns, "ethernet");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mergeConnections(newConns: var, connType: string): void {
|
||||
const rConns = root.connections;
|
||||
const destroyed = rConns.filter(rc => rc.type === connType && !newConns.find(nc =>
|
||||
connType === "wifi" ? (nc.frequency === rc.frequency && nc.name === rc.name && nc.bssid === rc.bssid)
|
||||
: nc.uuid === rc.uuid
|
||||
));
|
||||
|
||||
for (const conn of destroyed)
|
||||
rConns.splice(rConns.indexOf(conn), 1).forEach(c => c.destroy());
|
||||
|
||||
for (const conn of newConns) {
|
||||
const match = rConns.find(c =>
|
||||
connType === "wifi" ? (c.frequency === conn.frequency && c.name === conn.name && c.bssid === conn.bssid)
|
||||
: c.uuid === conn.uuid
|
||||
);
|
||||
if (match) {
|
||||
match.lastIpcObject = conn;
|
||||
} else {
|
||||
rConns.push(connComp.createObject(root, { lastIpcObject: conn }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component Connection: QtObject {
|
||||
required property var lastIpcObject
|
||||
readonly property string type: lastIpcObject.type
|
||||
readonly property string name: lastIpcObject.name
|
||||
readonly property string uuid: lastIpcObject.uuid
|
||||
readonly property string device: lastIpcObject.device
|
||||
readonly property bool active: lastIpcObject.active
|
||||
readonly property int strength: lastIpcObject.strength
|
||||
readonly property int frequency: lastIpcObject.frequency
|
||||
readonly property string bssid: lastIpcObject.bssid
|
||||
readonly property string security: lastIpcObject.security
|
||||
readonly property bool isSecure: security.length > 0
|
||||
readonly property bool saved: lastIpcObject.saved
|
||||
}
|
||||
|
||||
Component { id: connComp; Connection { } }
|
||||
}
|
||||
Reference in New Issue
Block a user