quickshell: detect NetworkManager down, add restart button

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-09-08 20:00:24 +01:00
parent 220f65064a
commit 1100bd460b

View file

@ -4056,11 +4056,21 @@ in
property string netConn: "" property string netConn: ""
property string netType: "" property string netType: ""
property int netStrength: 0 property int netStrength: 0
// nmcli exits non-zero when NetworkManager itself
// isn't running ("Error: NetworkManager is not
// running.", exit 8). The kernel keeps the link's
// address and routes when the daemon dies, so the
// machine is still online while nmcli reports nothing
// — without this the widget claimed "Not connected"
// over a working ethernet link.
property bool nmDown: false
// Signal strength picks the arc glyph. Lucide draws four // Signal strength picks the arc glyph. Lucide draws four
// wifi levels where Material Symbols drew five, so the // wifi levels where Material Symbols drew five, so the
// bottom two of caelestia's buckets collapse into one. // bottom two of caelestia's buckets collapse into one.
readonly property string netIcon: readonly property string netIcon:
netState !== "connected" nmDown ? "triangle-alert"
: netState !== "connected"
? (netType === "ethernet" ? "unplug" : "wifi-off") ? (netType === "ethernet" ? "unplug" : "wifi-off")
: netType === "ethernet" ? "cable" : netType === "ethernet" ? "cable"
: netStrength >= 80 ? "wifi" : netStrength >= 80 ? "wifi"
@ -4119,6 +4129,7 @@ in
Process { Process {
id: netProc id: netProc
command: [Commands.nmcli, "-t", "-f", "DEVICE,TYPE,STATE,CONNECTION", "device"] command: [Commands.nmcli, "-t", "-f", "DEVICE,TYPE,STATE,CONNECTION", "device"]
onExited: exitCode => netWidget.nmDown = exitCode !== 0
stdout: SplitParser { stdout: SplitParser {
onRead: data => { onRead: data => {
let fields = data.split(":"); let fields = data.split(":");
@ -4215,6 +4226,17 @@ in
command: [Commands.nmcli, "device", "disconnect", targetDevice] command: [Commands.nmcli, "device", "disconnect", targetDevice]
} }
Process {
id: nmRestartProc
command: [Commands.systemctl, "restart", "NetworkManager.service"]
}
Timer {
id: netRestartDelay
interval: 5000
onTriggered: netWidget.refreshNet()
}
function openNetDropdown() { function openNetDropdown() {
bar.toggleDropdown(netDropdown, function() { bar.toggleDropdown(netDropdown, function() {
wifiScanProc.running = true; wifiScanProc.running = true;
@ -5350,7 +5372,8 @@ in
SText { SText {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: parent.width - 22 width: parent.width - 22
text: netWidget.netState === "connected" text: netWidget.nmDown ? "NetworkManager down"
: netWidget.netState === "connected"
? netWidget.netConn : "Not connected" ? netWidget.netConn : "Not connected"
color: Theme.base05 color: Theme.base05
font.pixelSize: 13 font.pixelSize: 13
@ -5360,7 +5383,25 @@ in
} }
HoverRow { HoverRow {
visible: netWidget.netState === "connected" visible: netWidget.nmDown
width: parent.width
height: 28
onClicked: {
nmRestartProc.running = true;
bar.closeAllDropdowns();
netRestartDelay.start();
}
SText {
anchors.centerIn: parent
text: "Restart NetworkManager"
color: Theme.accent
font.pixelSize: 12
}
}
HoverRow {
visible: netWidget.netState === "connected" && !netWidget.nmDown
width: parent.width width: parent.width
height: 28 height: 28
onClicked: { onClicked: {