1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
//
// 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
import Quickshell.Networking
import Quickshell.Io
import QtQuick
import "../.."
// Always active: the backends push and there is no poll to gate, so the
// state the tile shows is live from launch. Referencing Networking here is
// also what instantiates the singleton at shell start.
Module {
id: mod
name: "network"
label: "Network"
alwaysActive: true
// .values on the device ObjectModel; empty until the backend is ready,
// roughly two seconds in. Bindings repaint when it arrives.
readonly property var devices: Networking.devices ? Networking.devices.values : []
readonly property var wiredDevices: devices.filter(d => d.type === DeviceType.Wired)
readonly property var wifiDevice: devices.find(d => d.type === DeviceType.Wifi) ?? null
readonly property bool wiredUp: wiredDevices.some(d => d.connected)
readonly property bool wifiUp: wifiDevice ? wifiDevice.connected : false
readonly property bool wifiOn: Networking.wifiEnabled
readonly property var wifiNetworks: wifiDevice && wifiDevice.networks ? wifiDevice.networks.values : []
readonly property string wifiSsid: {
const n = wifiNetworks.find(x => x.connected);
return n ? n.name : "";
}
readonly property string wiredName: {
const d = wiredDevices.find(x => x.connected);
return d ? d.name : "";
}
// Connected first, then known, then strongest. Kept here so both the
// tile and the page read the same order.
readonly property var wifiNetworksSorted: {
const arr = wifiNetworks.slice();
arr.sort((a, b) =>
((b.connected ? 1 : 0) - (a.connected ? 1 : 0)) ||
((b.known ? 1 : 0) - (a.known ? 1 : 0)) ||
((b.signalStrength ?? 0) - (a.signalStrength ?? 0)));
return arr;
}
// The icon follows the active link, live, with no contract change: the
// drawer reads this property like any other.
icon: mod.wiredUp ? "\uf796" : (mod.wifiUp ? "\uf1eb" : "\uf05e")
// Active while any link is up.
active: mod.wiredUp || mod.wifiUp
// The network a connect is pending on, so connectionFailed can be caught.
property var pendingNetwork: null
property string error: ""
function connect(net) {
mod.pendingNetwork = net;
mod.error = "";
net.connect();
}
function connectWithPsk(net, psk) {
mod.pendingNetwork = net;
mod.error = "";
net.connectWithPsk(psk);
}
function disconnectNetwork(net) { mod.error = ""; if (net) net.disconnect(); }
function forget(net) { mod.error = ""; if (net) net.forget(); }
// A failure after the drawer closed would otherwise go unseen, so it also
// raises a notification. Same cached-Process shape as VmModule.
function notify(title, body) {
notifyProc.command = ["notify-send", "--app-name=network",
"--urgency=critical", "--icon=error", title, body];
notifyProc.running = false;
notifyProc.running = true;
}
property Process notifyProc: Process {}
property Connections conn: Connections {
target: mod.pendingNetwork
function onConnectionFailed(reason) {
mod.error = "Could not connect to " + (mod.pendingNetwork?.name ?? "network");
mod.notify("Network", mod.error);
mod.pendingNetwork = null;
}
function onConnectedChanged() {
if (mod.pendingNetwork && mod.pendingNetwork.connected)
mod.pendingNetwork = null;
}
}
tileContent: Component { NetworkTile { net: mod } }
page: Component {
Page {
title: "Network"
NetworkPage { width: parent.width; net: mod }
}
}
}
|