nmcli: migrated all of wireless controlcenter

This commit is contained in:
ATMDA 2025-11-13 19:52:24 -05:00
parent 36a91213b1
commit 7799ec67fd
4 changed files with 84 additions and 110 deletions

View file

@ -28,28 +28,23 @@ Item {
} }
function checkSavedProfile(): void { function checkSavedProfile(): void {
// Refresh saved connections list to ensure it's up to date
// This ensures the "Forget Network" button visibility is accurate
if (network && network.ssid) { if (network && network.ssid) {
// Always refresh to ensure we have the latest saved connections Nmcli.loadSavedConnections(() => {});
// This is important when networks are selected or changed
Network.listConnectionsProc.running = true;
} }
} }
Connections { Connections {
target: Network target: Nmcli
function onActiveChanged() { function onActiveChanged() {
updateDeviceDetails(); updateDeviceDetails();
} }
} }
function updateDeviceDetails(): void { function updateDeviceDetails(): void {
// Only update details if the selected network is currently active if (network && Nmcli.active && Nmcli.active.ssid === network.ssid) {
if (network && Network.active && Network.active.ssid === network.ssid) { Nmcli.getWirelessDeviceDetails("", () => {});
Network.updateWirelessDeviceDetails();
} else { } else {
Network.wirelessDeviceDetails = null; Nmcli.wirelessDeviceDetails = null;
} }
} }
@ -84,7 +79,7 @@ Item {
if (checked) { if (checked) {
handleConnect(); handleConnect();
} else { } else {
Network.disconnectFromNetwork(); Nmcli.disconnectFromNetwork();
} }
} }
} }
@ -96,8 +91,7 @@ Item {
if (!root.network || !root.network.ssid) { if (!root.network || !root.network.ssid) {
return false; return false;
} }
// Check if profile exists - this will update reactively when savedConnectionSsids changes return Nmcli.hasSavedProfile(root.network.ssid);
return Network.hasSavedProfile(root.network.ssid);
} }
color: Colours.palette.m3errorContainer color: Colours.palette.m3errorContainer
onColor: Colours.palette.m3onErrorContainer onColor: Colours.palette.m3onErrorContainer
@ -105,12 +99,10 @@ Item {
onClicked: { onClicked: {
if (root.network && root.network.ssid) { if (root.network && root.network.ssid) {
// Disconnect first if connected
if (root.network.active) { if (root.network.active) {
Network.disconnectFromNetwork(); Nmcli.disconnectFromNetwork();
} }
// Delete the connection profile Nmcli.forgetNetwork(root.network.ssid, () => {});
Network.forgetNetwork(root.network.ssid);
} }
} }
} }
@ -161,7 +153,7 @@ Item {
SectionContainer { SectionContainer {
ConnectionInfoSection { ConnectionInfoSection {
deviceDetails: Network.wirelessDeviceDetails deviceDetails: Nmcli.wirelessDeviceDetails
} }
} }
@ -169,9 +161,8 @@ Item {
} }
function handleConnect(): void { function handleConnect(): void {
// If already connected to a different network, disconnect first if (Nmcli.active && Nmcli.active.ssid !== root.network.ssid) {
if (Network.active && Network.active.ssid !== root.network.ssid) { Nmcli.disconnectFromNetwork();
Network.disconnectFromNetwork();
Qt.callLater(() => { Qt.callLater(() => {
connectToNetwork(); connectToNetwork();
}); });
@ -182,29 +173,31 @@ Item {
function connectToNetwork(): void { function connectToNetwork(): void {
if (root.network.isSecure) { if (root.network.isSecure) {
// Check if we have a saved connection profile for this network (by SSID) const hasSavedProfile = Nmcli.hasSavedProfile(root.network.ssid);
const hasSavedProfile = Network.hasSavedProfile(root.network.ssid);
if (hasSavedProfile) { if (hasSavedProfile) {
// Try connecting with saved password - don't show dialog if it fails Nmcli.connectToNetwork(root.network.ssid, "", root.network.bssid, null);
// The saved password should work, but if connection fails for other reasons,
// we'll let the user try manually later
Network.connectToNetwork(root.network.ssid, "", root.network.bssid, null);
} else { } else {
// No saved profile, try connecting without password first Nmcli.connectToNetworkWithPasswordCheck(
Network.connectToNetworkWithPasswordCheck(
root.network.ssid, root.network.ssid,
root.network.isSecure, root.network.isSecure,
() => { (result) => {
// Callback: connection failed, show password dialog if (result.needsPassword) {
root.session.network.showPasswordDialog = true; if (Nmcli.pendingConnection) {
root.session.network.pendingNetwork = root.network; Nmcli.connectionCheckTimer.stop();
Nmcli.immediateCheckTimer.stop();
Nmcli.immediateCheckTimer.checkCount = 0;
Nmcli.pendingConnection = null;
}
root.session.network.showPasswordDialog = true;
root.session.network.pendingNetwork = root.network;
}
}, },
root.network.bssid root.network.bssid
); );
} }
} else { } else {
Network.connectToNetwork(root.network.ssid, "", root.network.bssid, null); Nmcli.connectToNetwork(root.network.ssid, "", root.network.bssid, null);
} }
} }
} }

View file

@ -31,22 +31,22 @@ ColumnLayout {
} }
ToggleButton { ToggleButton {
toggled: Network.wifiEnabled toggled: Nmcli.wifiEnabled
icon: "wifi" icon: "wifi"
accent: "Tertiary" accent: "Tertiary"
onClicked: { onClicked: {
Network.toggleWifi(); Nmcli.toggleWifi(null);
} }
} }
ToggleButton { ToggleButton {
toggled: Network.scanning toggled: Nmcli.scanning
icon: "wifi_find" icon: "wifi_find"
accent: "Secondary" accent: "Secondary"
onClicked: { onClicked: {
Network.rescanWifi(); Nmcli.rescanWifi();
} }
} }
@ -70,13 +70,13 @@ ColumnLayout {
spacing: Appearance.spacing.small spacing: Appearance.spacing.small
StyledText { StyledText {
text: qsTr("Networks (%1)").arg(Network.networks.length) text: qsTr("Networks (%1)").arg(Nmcli.networks.length)
font.pointSize: Appearance.font.size.large font.pointSize: Appearance.font.size.large
font.weight: 500 font.weight: 500
} }
StyledText { StyledText {
visible: Network.scanning visible: Nmcli.scanning
text: qsTr("Scanning...") text: qsTr("Scanning...")
color: Colours.palette.m3primary color: Colours.palette.m3primary
font.pointSize: Appearance.font.size.small font.pointSize: Appearance.font.size.small
@ -94,7 +94,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
model: Network.networks model: Nmcli.networks
spacing: Appearance.spacing.small / 2 spacing: Appearance.spacing.small / 2
clip: true clip: true
@ -183,7 +183,7 @@ ColumnLayout {
StateLayer { StateLayer {
function onClicked(): void { function onClicked(): void {
if (modelData.active) { if (modelData.active) {
Network.disconnectFromNetwork(); Nmcli.disconnectFromNetwork();
} else { } else {
handleConnect(modelData); handleConnect(modelData);
} }
@ -205,19 +205,14 @@ ColumnLayout {
} }
function checkSavedProfileForNetwork(ssid: string): void { function checkSavedProfileForNetwork(ssid: string): void {
// Refresh saved connections list to ensure it's up to date
// This ensures accurate profile detection when selecting networks
if (ssid && ssid.length > 0) { if (ssid && ssid.length > 0) {
// Always refresh to ensure we have the latest saved connections Nmcli.loadSavedConnections(() => {});
// This is important when a network is selected from the list
Network.listConnectionsProc.running = true;
} }
} }
function handleConnect(network): void { function handleConnect(network): void {
// If already connected to a different network, disconnect first if (Nmcli.active && Nmcli.active.ssid !== network.ssid) {
if (Network.active && Network.active.ssid !== network.ssid) { Nmcli.disconnectFromNetwork();
Network.disconnectFromNetwork();
Qt.callLater(() => { Qt.callLater(() => {
connectToNetwork(network); connectToNetwork(network);
}); });
@ -228,29 +223,31 @@ ColumnLayout {
function connectToNetwork(network): void { function connectToNetwork(network): void {
if (network.isSecure) { if (network.isSecure) {
// Check if we have a saved connection profile for this network (by SSID) const hasSavedProfile = Nmcli.hasSavedProfile(network.ssid);
const hasSavedProfile = Network.hasSavedProfile(network.ssid);
if (hasSavedProfile) { if (hasSavedProfile) {
// Try connecting with saved password - don't show dialog if it fails Nmcli.connectToNetwork(network.ssid, "", network.bssid, null);
// The saved password should work, but if connection fails for other reasons,
// we'll let the user try manually later
Network.connectToNetwork(network.ssid, "", network.bssid, null);
} else { } else {
// No saved profile, try connecting without password first Nmcli.connectToNetworkWithPasswordCheck(
Network.connectToNetworkWithPasswordCheck(
network.ssid, network.ssid,
network.isSecure, network.isSecure,
() => { (result) => {
// Callback: connection failed, show password dialog if (result.needsPassword) {
root.session.network.showPasswordDialog = true; if (Nmcli.pendingConnection) {
root.session.network.pendingNetwork = network; Nmcli.connectionCheckTimer.stop();
Nmcli.immediateCheckTimer.stop();
Nmcli.immediateCheckTimer.checkCount = 0;
Nmcli.pendingConnection = null;
}
root.session.network.showPasswordDialog = true;
root.session.network.pendingNetwork = network;
}
}, },
network.bssid network.bssid
); );
} }
} else { } else {
Network.connectToNetwork(network.ssid, "", network.bssid, null); Nmcli.connectToNetwork(network.ssid, "", network.bssid, null);
} }
} }
} }

View file

@ -108,26 +108,16 @@ Item {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Appearance.spacing.small Layout.topMargin: Appearance.spacing.small
visible: Network.connectionStatus.length > 0 || connectButton.connecting visible: connectButton.connecting
text: { text: {
if (Network.connectionStatus.length > 0) { if (connectButton.connecting) {
return Network.connectionStatus;
} else if (connectButton.connecting) {
return qsTr("Connecting..."); return qsTr("Connecting...");
} }
return ""; return "";
} }
color: { color: Colours.palette.m3onSurfaceVariant
const status = Network.connectionStatus;
if (status.includes("Error") || status.includes("error") || status.includes("failed")) {
return Colours.palette.m3error;
} else if (status.includes("successful") || status.includes("Connected") || status.includes("success")) {
return Colours.palette.m3primary;
}
return Colours.palette.m3onSurfaceVariant;
}
font.pointSize: Appearance.font.size.small font.pointSize: Appearance.font.size.small
font.weight: (Network.connectionStatus.includes("Error") || Network.connectionStatus.includes("error")) ? 500 : 400 font.weight: 400
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
Layout.maximumWidth: parent.width - Appearance.padding.large * 2 Layout.maximumWidth: parent.width - Appearance.padding.large * 2
} }
@ -166,7 +156,6 @@ Item {
if (root.visible) { if (root.visible) {
passwordField.forceActiveFocus(); passwordField.forceActiveFocus();
passwordField.text = ""; passwordField.text = "";
Network.clearConnectionStatus();
} }
} }
} }
@ -225,10 +214,9 @@ Item {
connecting = true; connecting = true;
enabled = false; enabled = false;
text = qsTr("Connecting..."); text = qsTr("Connecting...");
Network.clearConnectionStatus();
// Connect to network // Connect to network
Network.connectToNetwork( Nmcli.connectToNetwork(
root.network.ssid, root.network.ssid,
password, password,
root.network.bssid || "", root.network.bssid || "",
@ -248,27 +236,17 @@ Item {
return; return;
} }
// Check connection status message for success indicators
const status = Network.connectionStatus;
const statusLower = status.toLowerCase();
// Check for success indicators in status message
const hasSuccessIndicator = statusLower.includes("connection activated") ||
statusLower.includes("successfully") ||
statusLower.includes("connected successfully") ||
(statusLower.includes("connected") && !statusLower.includes("error") && !statusLower.includes("failed"));
// Check if we're connected to the target network (case-insensitive SSID comparison) // Check if we're connected to the target network (case-insensitive SSID comparison)
const isConnected = root.network && Network.active && Network.active.ssid && const isConnected = root.network && Nmcli.active && Nmcli.active.ssid &&
Network.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim(); Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
if (isConnected || hasSuccessIndicator) { if (isConnected) {
// Successfully connected - give it a moment for network list to update // Successfully connected - give it a moment for network list to update
Qt.callLater(() => { Qt.callLater(() => {
// Double-check connection is still active // Double-check connection is still active
if (root.visible && Network.active && Network.active.ssid) { if (root.visible && Nmcli.active && Nmcli.active.ssid) {
const stillConnected = Network.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim(); const stillConnected = Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
if (stillConnected || hasSuccessIndicator) { if (stillConnected) {
connectionMonitor.stop(); connectionMonitor.stop();
connectButton.connecting = false; connectButton.connecting = false;
connectButton.text = qsTr("Connect"); connectButton.text = qsTr("Connect");
@ -279,11 +257,10 @@ Item {
return; return;
} }
// Check for connection errors (but not warnings about duplicate names) // Check for connection failures - if pending connection was cleared but we're not connected
if (status.includes("Error") || (status.includes("error") && !status.includes("Warning"))) { if (Nmcli.pendingConnection === null && connectButton.connecting) {
// Only treat as error if it's not just a warning about duplicate names // Wait a bit more before giving up (allow time for connection to establish)
if (!status.includes("another connection with the name") && !status.includes("Reference the connection by its uuid")) { if (connectionMonitor.repeatCount > 10) {
// Connection failed
connectionMonitor.stop(); connectionMonitor.stop();
connectButton.connecting = false; connectButton.connecting = false;
connectButton.enabled = true; connectButton.enabled = true;
@ -297,14 +274,22 @@ Item {
interval: 1000 interval: 1000
repeat: true repeat: true
triggeredOnStart: false triggeredOnStart: false
property int repeatCount: 0
onTriggered: { onTriggered: {
repeatCount++;
checkConnectionStatus(); checkConnectionStatus();
} }
onRunningChanged: {
if (!running) {
repeatCount = 0;
}
}
} }
Connections { Connections {
target: Network target: Nmcli
function onActiveChanged() { function onActiveChanged() {
if (root.visible) { if (root.visible) {
checkConnectionStatus(); checkConnectionStatus();
@ -318,6 +303,5 @@ Item {
connectButton.connecting = false; connectButton.connecting = false;
connectButton.text = qsTr("Connect"); connectButton.text = qsTr("Connect");
connectionMonitor.stop(); connectionMonitor.stop();
Network.clearConnectionStatus();
} }
} }

View file

@ -39,9 +39,9 @@ ColumnLayout {
SectionContainer { SectionContainer {
ToggleRow { ToggleRow {
label: qsTr("WiFi enabled") label: qsTr("WiFi enabled")
checked: Network.wifiEnabled checked: Nmcli.wifiEnabled
toggle.onToggled: { toggle.onToggled: {
Network.enableWifi(checked); Nmcli.enableWifi(checked);
} }
} }
} }
@ -57,25 +57,25 @@ ColumnLayout {
PropertyRow { PropertyRow {
label: qsTr("Connected network") label: qsTr("Connected network")
value: Network.active ? Network.active.ssid : qsTr("Not connected") value: Nmcli.active ? Nmcli.active.ssid : qsTr("Not connected")
} }
PropertyRow { PropertyRow {
showTopMargin: true showTopMargin: true
label: qsTr("Signal strength") label: qsTr("Signal strength")
value: Network.active ? qsTr("%1%").arg(Network.active.strength) : qsTr("N/A") value: Nmcli.active ? qsTr("%1%").arg(Nmcli.active.strength) : qsTr("N/A")
} }
PropertyRow { PropertyRow {
showTopMargin: true showTopMargin: true
label: qsTr("Security") label: qsTr("Security")
value: Network.active ? (Network.active.isSecure ? qsTr("Secured") : qsTr("Open")) : qsTr("N/A") value: Nmcli.active ? (Nmcli.active.isSecure ? qsTr("Secured") : qsTr("Open")) : qsTr("N/A")
} }
PropertyRow { PropertyRow {
showTopMargin: true showTopMargin: true
label: qsTr("Frequency") label: qsTr("Frequency")
value: Network.active ? qsTr("%1 MHz").arg(Network.active.frequency) : qsTr("N/A") value: Nmcli.active ? qsTr("%1 MHz").arg(Nmcli.active.frequency) : qsTr("N/A")
} }
} }
} }