cleanup: trailing whitespace removeal (entire project)
This commit is contained in:
parent
e9113a1710
commit
1da9c68be8
11 changed files with 137 additions and 137 deletions
|
|
@ -12,7 +12,7 @@ ColumnLayout {
|
||||||
required property string title
|
required property string title
|
||||||
property string description: ""
|
property string description: ""
|
||||||
property bool expanded: false
|
property bool expanded: false
|
||||||
|
|
||||||
signal toggleRequested
|
signal toggleRequested
|
||||||
|
|
||||||
spacing: Appearance.spacing.small / 2
|
spacing: Appearance.spacing.small / 2
|
||||||
|
|
|
||||||
|
|
@ -310,20 +310,20 @@ RowLayout {
|
||||||
StateLayer {
|
StateLayer {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
const variant = modelData.variant;
|
const variant = modelData.variant;
|
||||||
|
|
||||||
// Optimistic update - set immediately
|
// Optimistic update - set immediately
|
||||||
Schemes.currentVariant = variant;
|
Schemes.currentVariant = variant;
|
||||||
|
|
||||||
// Execute the command
|
// Execute the command
|
||||||
Quickshell.execDetached(["caelestia", "scheme", "set", "-v", variant]);
|
Quickshell.execDetached(["caelestia", "scheme", "set", "-v", variant]);
|
||||||
|
|
||||||
// Reload after a delay to confirm
|
// Reload after a delay to confirm
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
reloadTimer.restart();
|
reloadTimer.restart();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: reloadTimer
|
id: reloadTimer
|
||||||
interval: 300
|
interval: 300
|
||||||
|
|
@ -410,20 +410,20 @@ RowLayout {
|
||||||
const name = modelData.name;
|
const name = modelData.name;
|
||||||
const flavour = modelData.flavour;
|
const flavour = modelData.flavour;
|
||||||
const schemeKey = `${name} ${flavour}`;
|
const schemeKey = `${name} ${flavour}`;
|
||||||
|
|
||||||
// Optimistic update - set immediately
|
// Optimistic update - set immediately
|
||||||
Schemes.currentScheme = schemeKey;
|
Schemes.currentScheme = schemeKey;
|
||||||
|
|
||||||
// Execute the command
|
// Execute the command
|
||||||
Quickshell.execDetached(["caelestia", "scheme", "set", "-n", name, "-f", flavour]);
|
Quickshell.execDetached(["caelestia", "scheme", "set", "-n", name, "-f", flavour]);
|
||||||
|
|
||||||
// Reload after a delay to confirm
|
// Reload after a delay to confirm
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
reloadTimer.restart();
|
reloadTimer.restart();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: reloadTimer
|
id: reloadTimer
|
||||||
interval: 300
|
interval: 300
|
||||||
|
|
@ -1053,7 +1053,7 @@ RowLayout {
|
||||||
columns: Math.max(1, Math.floor(parent.width / 200))
|
columns: Math.max(1, Math.floor(parent.width / 200))
|
||||||
rowSpacing: Appearance.spacing.normal
|
rowSpacing: Appearance.spacing.normal
|
||||||
columnSpacing: Appearance.spacing.normal
|
columnSpacing: Appearance.spacing.normal
|
||||||
|
|
||||||
// Center the grid content
|
// Center the grid content
|
||||||
Layout.maximumWidth: {
|
Layout.maximumWidth: {
|
||||||
const cols = columns;
|
const cols = columns;
|
||||||
|
|
@ -1100,16 +1100,16 @@ RowLayout {
|
||||||
|
|
||||||
path: modelData.path
|
path: modelData.path
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
// Ensure sourceSize is always set to valid dimensions
|
// Ensure sourceSize is always set to valid dimensions
|
||||||
sourceSize: Qt.size(
|
sourceSize: Qt.size(
|
||||||
Math.max(1, Math.floor(parent.width)),
|
Math.max(1, Math.floor(parent.width)),
|
||||||
Math.max(1, Math.floor(parent.height))
|
Math.max(1, Math.floor(parent.height))
|
||||||
)
|
)
|
||||||
|
|
||||||
// Show when ready, hide if fallback is showing
|
// Show when ready, hide if fallback is showing
|
||||||
opacity: status === Image.Ready && !fallbackImage.visible ? 1 : 0
|
opacity: status === Image.Ready && !fallbackImage.visible ? 1 : 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: 200
|
duration: 200
|
||||||
|
|
@ -1129,11 +1129,11 @@ RowLayout {
|
||||||
Math.max(1, Math.floor(parent.width)),
|
Math.max(1, Math.floor(parent.width)),
|
||||||
Math.max(1, Math.floor(parent.height))
|
Math.max(1, Math.floor(parent.height))
|
||||||
)
|
)
|
||||||
|
|
||||||
// Show if caching image hasn't loaded after a delay
|
// Show if caching image hasn't loaded after a delay
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: fallbackTimer
|
id: fallbackTimer
|
||||||
interval: 500
|
interval: 500
|
||||||
|
|
@ -1144,7 +1144,7 @@ RowLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also check status changes
|
// Also check status changes
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
if (status === Image.Ready && cachingImage.status !== Image.Ready) {
|
if (status === Image.Ready && cachingImage.status !== Image.Ready) {
|
||||||
|
|
@ -1155,7 +1155,7 @@ RowLayout {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: 200
|
duration: 200
|
||||||
|
|
@ -1182,26 +1182,26 @@ RowLayout {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
height: filenameText.implicitHeight + Appearance.padding.normal * 2
|
height: filenameText.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
// Match the parent's rounded corners at the bottom
|
// Match the parent's rounded corners at the bottom
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
|
|
||||||
gradient: Gradient {
|
gradient: Gradient {
|
||||||
GradientStop { position: 0.0; color: Qt.rgba(0, 0, 0, 0) }
|
GradientStop { position: 0.0; color: Qt.rgba(0, 0, 0, 0) }
|
||||||
GradientStop { position: 0.3; color: Qt.rgba(0, 0, 0, 0.3) }
|
GradientStop { position: 0.3; color: Qt.rgba(0, 0, 0, 0.3) }
|
||||||
GradientStop { position: 0.7; color: Qt.rgba(0, 0, 0, 0.75) }
|
GradientStop { position: 0.7; color: Qt.rgba(0, 0, 0, 0.75) }
|
||||||
GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.85) }
|
GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.85) }
|
||||||
}
|
}
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: 200
|
duration: 200
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
opacity = 1;
|
opacity = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1228,20 +1228,20 @@ RowLayout {
|
||||||
color: isCurrent ? Colours.palette.m3primary : "#FFFFFF"
|
color: isCurrent ? Colours.palette.m3primary : "#FFFFFF"
|
||||||
elide: Text.ElideMiddle
|
elide: Text.ElideMiddle
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
|
|
||||||
// Text shadow for better readability
|
// Text shadow for better readability
|
||||||
style: Text.Outline
|
style: Text.Outline
|
||||||
styleColor: Qt.rgba(0, 0, 0, 0.6)
|
styleColor: Qt.rgba(0, 0, 0, 0.6)
|
||||||
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: 200
|
duration: 200
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
opacity = 1;
|
opacity = 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ RowLayout {
|
||||||
try {
|
try {
|
||||||
const config = JSON.parse(configFile.text());
|
const config = JSON.parse(configFile.text());
|
||||||
const appId = root.selectedApp.id || root.selectedApp.entry?.id;
|
const appId = root.selectedApp.id || root.selectedApp.entry?.id;
|
||||||
|
|
||||||
if (config.launcher && config.launcher.hiddenApps) {
|
if (config.launcher && config.launcher.hiddenApps) {
|
||||||
root.hideFromLauncherChecked = config.launcher.hiddenApps.includes(appId);
|
root.hideFromLauncherChecked = config.launcher.hiddenApps.includes(appId);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -72,12 +72,12 @@ RowLayout {
|
||||||
try {
|
try {
|
||||||
const config = JSON.parse(configFile.text());
|
const config = JSON.parse(configFile.text());
|
||||||
const appId = root.selectedApp.id || root.selectedApp.entry?.id;
|
const appId = root.selectedApp.id || root.selectedApp.entry?.id;
|
||||||
|
|
||||||
if (!config.launcher) config.launcher = {};
|
if (!config.launcher) config.launcher = {};
|
||||||
if (!config.launcher.hiddenApps) config.launcher.hiddenApps = [];
|
if (!config.launcher.hiddenApps) config.launcher.hiddenApps = [];
|
||||||
|
|
||||||
const hiddenApps = config.launcher.hiddenApps;
|
const hiddenApps = config.launcher.hiddenApps;
|
||||||
|
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
// Add to hiddenApps if not already there
|
// Add to hiddenApps if not already there
|
||||||
if (!hiddenApps.includes(appId)) {
|
if (!hiddenApps.includes(appId)) {
|
||||||
|
|
@ -90,7 +90,7 @@ RowLayout {
|
||||||
hiddenApps.splice(index, 1);
|
hiddenApps.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const jsonString = JSON.stringify(config, null, 4);
|
const jsonString = JSON.stringify(config, null, 4);
|
||||||
configFile.setText(jsonString);
|
configFile.setText(jsonString);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ Item {
|
||||||
updateDeviceDetails();
|
updateDeviceDetails();
|
||||||
checkSavedProfile();
|
checkSavedProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSavedProfile(): void {
|
function checkSavedProfile(): void {
|
||||||
// Refresh saved connections list to ensure it's up to date
|
// Refresh saved connections list to ensure it's up to date
|
||||||
// This ensures the "Forget Network" button visibility is accurate
|
// This ensures the "Forget Network" button visibility is accurate
|
||||||
|
|
@ -102,7 +102,7 @@ Item {
|
||||||
color: Colours.palette.m3errorContainer
|
color: Colours.palette.m3errorContainer
|
||||||
onColor: Colours.palette.m3onErrorContainer
|
onColor: Colours.palette.m3onErrorContainer
|
||||||
text: qsTr("Forget Network")
|
text: qsTr("Forget Network")
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.network && root.network.ssid) {
|
if (root.network && root.network.ssid) {
|
||||||
// Disconnect first if connected
|
// Disconnect first if connected
|
||||||
|
|
@ -184,7 +184,7 @@ Item {
|
||||||
if (root.network.isSecure) {
|
if (root.network.isSecure) {
|
||||||
// Check if we have a saved connection profile for this network (by SSID)
|
// Check if we have a saved connection profile for this network (by SSID)
|
||||||
const hasSavedProfile = Network.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
|
// Try connecting with saved password - don't show dialog if it fails
|
||||||
// The saved password should work, but if connection fails for other reasons,
|
// The saved password should work, but if connection fails for other reasons,
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ ColumnLayout {
|
||||||
if (network.isSecure) {
|
if (network.isSecure) {
|
||||||
// Check if we have a saved connection profile for this network (by SSID)
|
// Check if we have a saved connection profile for this network (by SSID)
|
||||||
const hasSavedProfile = Network.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
|
// Try connecting with saved password - don't show dialog if it fails
|
||||||
// The saved password should work, but if connection fails for other reasons,
|
// The saved password should work, but if connection fails for other reasons,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property Session session
|
required property Session session
|
||||||
|
|
||||||
readonly property var network: {
|
readonly property var network: {
|
||||||
// Prefer pendingNetwork, then active network
|
// Prefer pendingNetwork, then active network
|
||||||
if (session.network.pendingNetwork) {
|
if (session.network.pendingNetwork) {
|
||||||
|
|
@ -105,7 +105,7 @@ Item {
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: statusText
|
id: statusText
|
||||||
|
|
||||||
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: Network.connectionStatus.length > 0 || connectButton.connecting
|
||||||
|
|
@ -251,15 +251,15 @@ Item {
|
||||||
// Check connection status message for success indicators
|
// Check connection status message for success indicators
|
||||||
const status = Network.connectionStatus;
|
const status = Network.connectionStatus;
|
||||||
const statusLower = status.toLowerCase();
|
const statusLower = status.toLowerCase();
|
||||||
|
|
||||||
// Check for success indicators in status message
|
// Check for success indicators in status message
|
||||||
const hasSuccessIndicator = statusLower.includes("connection activated") ||
|
const hasSuccessIndicator = statusLower.includes("connection activated") ||
|
||||||
statusLower.includes("successfully") ||
|
statusLower.includes("successfully") ||
|
||||||
statusLower.includes("connected successfully") ||
|
statusLower.includes("connected successfully") ||
|
||||||
(statusLower.includes("connected") && !statusLower.includes("error") && !statusLower.includes("failed"));
|
(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 && Network.active && Network.active.ssid &&
|
||||||
Network.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
|
Network.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
|
||||||
|
|
||||||
if (isConnected || hasSuccessIndicator) {
|
if (isConnected || hasSuccessIndicator) {
|
||||||
|
|
|
||||||
|
|
@ -120,13 +120,13 @@ RowLayout {
|
||||||
if (!configFile.loaded) {
|
if (!configFile.loaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const config = JSON.parse(configFile.text());
|
const config = JSON.parse(configFile.text());
|
||||||
|
|
||||||
// Ensure bar object exists
|
// Ensure bar object exists
|
||||||
if (!config.bar) config.bar = {};
|
if (!config.bar) config.bar = {};
|
||||||
|
|
||||||
// Update clock setting
|
// Update clock setting
|
||||||
if (!config.bar.clock) config.bar.clock = {};
|
if (!config.bar.clock) config.bar.clock = {};
|
||||||
config.bar.clock.showIcon = clockShowIconSwitch.checked;
|
config.bar.clock.showIcon = clockShowIconSwitch.checked;
|
||||||
|
|
@ -163,7 +163,7 @@ RowLayout {
|
||||||
// Update entries from the model (same approach as clock - use provided value if available)
|
// Update entries from the model (same approach as clock - use provided value if available)
|
||||||
if (!config.bar.entries) config.bar.entries = [];
|
if (!config.bar.entries) config.bar.entries = [];
|
||||||
config.bar.entries = [];
|
config.bar.entries = [];
|
||||||
|
|
||||||
for (let i = 0; i < entriesModel.count; i++) {
|
for (let i = 0; i < entriesModel.count; i++) {
|
||||||
const entry = entriesModel.get(i);
|
const entry = entriesModel.get(i);
|
||||||
// If this is the entry being updated, use the provided value (same as clock toggle reads from switch)
|
// If this is the entry being updated, use the provided value (same as clock toggle reads from switch)
|
||||||
|
|
|
||||||
|
|
@ -204,18 +204,18 @@ CustomMouseArea {
|
||||||
const panelWidth = panels.notifications.width || panels.notifications.implicitWidth || Config.notifs.sizes.width;
|
const panelWidth = panels.notifications.width || panels.notifications.implicitWidth || Config.notifs.sizes.width;
|
||||||
const panelX = bar.implicitWidth + panels.notifications.x;
|
const panelX = bar.implicitWidth + panels.notifications.x;
|
||||||
const isPanelCollapsed = panelHeight < 10; // Consider collapsed if height is very small
|
const isPanelCollapsed = panelHeight < 10; // Consider collapsed if height is very small
|
||||||
|
|
||||||
let showNotifications = inTopPanel(panels.notifications, x, y);
|
let showNotifications = inTopPanel(panels.notifications, x, y);
|
||||||
|
|
||||||
// Only use fallback corner detection when panel is collapsed
|
// Only use fallback corner detection when panel is collapsed
|
||||||
if (!showNotifications && isPanelCollapsed) {
|
if (!showNotifications && isPanelCollapsed) {
|
||||||
// Use panel's actual width and position for fallback, with some padding
|
// Use panel's actual width and position for fallback, with some padding
|
||||||
const cornerPadding = Config.border.rounding || 20;
|
const cornerPadding = Config.border.rounding || 20;
|
||||||
showNotifications = x >= panelX - cornerPadding &&
|
showNotifications = x >= panelX - cornerPadding &&
|
||||||
x <= panelX + panelWidth + cornerPadding &&
|
x <= panelX + panelWidth + cornerPadding &&
|
||||||
y < Config.border.thickness + cornerPadding;
|
y < Config.border.thickness + cornerPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if mouse is over the clear all button area
|
// Check if mouse is over the clear all button area
|
||||||
// Button is positioned to the left of the notification panel
|
// Button is positioned to the left of the notification panel
|
||||||
if (!showNotifications && panels.notifications.height > 0 && panels.clearAllButton && panels.clearAllButton.visible) {
|
if (!showNotifications && panels.notifications.height > 0 && panels.clearAllButton && panels.clearAllButton.visible) {
|
||||||
|
|
@ -223,17 +223,17 @@ CustomMouseArea {
|
||||||
const buttonY = Config.border.thickness + panels.clearAllButton.y;
|
const buttonY = Config.border.thickness + panels.clearAllButton.y;
|
||||||
const buttonWidth = panels.clearAllButton.width;
|
const buttonWidth = panels.clearAllButton.width;
|
||||||
const buttonHeight = panels.clearAllButton.height;
|
const buttonHeight = panels.clearAllButton.height;
|
||||||
|
|
||||||
const inButtonArea = x >= buttonX &&
|
const inButtonArea = x >= buttonX &&
|
||||||
x <= buttonX + buttonWidth &&
|
x <= buttonX + buttonWidth &&
|
||||||
y >= buttonY &&
|
y >= buttonY &&
|
||||||
y <= buttonY + buttonHeight;
|
y <= buttonY + buttonHeight;
|
||||||
|
|
||||||
if (inButtonArea) {
|
if (inButtonArea) {
|
||||||
showNotifications = true;
|
showNotifications = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show or hide notification panel based on hover
|
// Show or hide notification panel based on hover
|
||||||
if (panels.notifications.content) {
|
if (panels.notifications.content) {
|
||||||
if (showNotifications) {
|
if (showNotifications) {
|
||||||
|
|
|
||||||
|
|
@ -30,17 +30,17 @@ Singleton {
|
||||||
property var wirelessDeviceDetails: null
|
property var wirelessDeviceDetails: null
|
||||||
property string connectionStatus: ""
|
property string connectionStatus: ""
|
||||||
property string connectionDebug: ""
|
property string connectionDebug: ""
|
||||||
|
|
||||||
function clearConnectionStatus(): void {
|
function clearConnectionStatus(): void {
|
||||||
connectionStatus = "";
|
connectionStatus = "";
|
||||||
// Don't clear debug - keep it for reference
|
// Don't clear debug - keep it for reference
|
||||||
// connectionDebug = "";
|
// connectionDebug = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function setConnectionStatus(status: string): void {
|
function setConnectionStatus(status: string): void {
|
||||||
connectionStatus = status;
|
connectionStatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addDebugInfo(info: string): void {
|
function addDebugInfo(info: string): void {
|
||||||
const timestamp = new Date().toLocaleTimeString();
|
const timestamp = new Date().toLocaleTimeString();
|
||||||
const newInfo = "[" + timestamp + "] " + info;
|
const newInfo = "[" + timestamp + "] " + info;
|
||||||
|
|
@ -79,23 +79,23 @@ Singleton {
|
||||||
// When no password, use SSID (will use saved password if available)
|
// When no password, use SSID (will use saved password if available)
|
||||||
const hasBssid = bssid !== undefined && bssid !== null && bssid.length > 0;
|
const hasBssid = bssid !== undefined && bssid !== null && bssid.length > 0;
|
||||||
let cmd = [];
|
let cmd = [];
|
||||||
|
|
||||||
// Set up pending connection tracking if callback provided
|
// Set up pending connection tracking if callback provided
|
||||||
if (callback) {
|
if (callback) {
|
||||||
root.pendingConnection = { ssid: ssid, bssid: hasBssid ? bssid : "", callback: callback };
|
root.pendingConnection = { ssid: ssid, bssid: hasBssid ? bssid : "", callback: callback };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password && password.length > 0) {
|
if (password && password.length > 0) {
|
||||||
// When password is provided, try BSSID first if available, otherwise use SSID
|
// When password is provided, try BSSID first if available, otherwise use SSID
|
||||||
if (hasBssid) {
|
if (hasBssid) {
|
||||||
// Use BSSID when password is provided - ensure BSSID is uppercase
|
// Use BSSID when password is provided - ensure BSSID is uppercase
|
||||||
const bssidUpper = bssid.toUpperCase();
|
const bssidUpper = bssid.toUpperCase();
|
||||||
|
|
||||||
// Check if a connection with this SSID already exists
|
// Check if a connection with this SSID already exists
|
||||||
const existingConnection = root.savedConnections.find(conn =>
|
const existingConnection = root.savedConnections.find(conn =>
|
||||||
conn && conn.toLowerCase().trim() === ssid.toLowerCase().trim()
|
conn && conn.toLowerCase().trim() === ssid.toLowerCase().trim()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingConnection) {
|
if (existingConnection) {
|
||||||
// Connection already exists - delete it first, then create new one with updated password
|
// Connection already exists - delete it first, then create new one with updated password
|
||||||
root.addDebugInfo(qsTr("Connection '%1' already exists, deleting it first...").arg(existingConnection));
|
root.addDebugInfo(qsTr("Connection '%1' already exists, deleting it first...").arg(existingConnection));
|
||||||
|
|
@ -122,7 +122,7 @@ Singleton {
|
||||||
root.setConnectionStatus(qsTr("Connecting to %1 (using saved password)...").arg(ssid));
|
root.setConnectionStatus(qsTr("Connecting to %1 (using saved password)...").arg(ssid));
|
||||||
root.addDebugInfo(qsTr("Using saved password for: %1").arg(ssid));
|
root.addDebugInfo(qsTr("Using saved password for: %1").arg(ssid));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the exact command being executed
|
// Show the exact command being executed
|
||||||
const cmdStr = cmd.join(" ");
|
const cmdStr = cmd.join(" ");
|
||||||
root.addDebugInfo(qsTr("=== COMMAND TO EXECUTE ==="));
|
root.addDebugInfo(qsTr("=== COMMAND TO EXECUTE ==="));
|
||||||
|
|
@ -130,17 +130,17 @@ Singleton {
|
||||||
root.addDebugInfo(qsTr("Command array: [%1]").arg(cmd.map((arg, i) => `"${arg}"`).join(", ")));
|
root.addDebugInfo(qsTr("Command array: [%1]").arg(cmd.map((arg, i) => `"${arg}"`).join(", ")));
|
||||||
root.addDebugInfo(qsTr("Command array length: %1").arg(cmd.length));
|
root.addDebugInfo(qsTr("Command array length: %1").arg(cmd.length));
|
||||||
root.addDebugInfo(qsTr("==========================="));
|
root.addDebugInfo(qsTr("==========================="));
|
||||||
|
|
||||||
// Set command and start process
|
// Set command and start process
|
||||||
root.addDebugInfo(qsTr("Setting command property..."));
|
root.addDebugInfo(qsTr("Setting command property..."));
|
||||||
connectProc.command = cmd;
|
connectProc.command = cmd;
|
||||||
const setCmdStr = connectProc.command ? connectProc.command.join(" ") : "null";
|
const setCmdStr = connectProc.command ? connectProc.command.join(" ") : "null";
|
||||||
root.addDebugInfo(qsTr("Command property set, value: %1").arg(setCmdStr));
|
root.addDebugInfo(qsTr("Command property set, value: %1").arg(setCmdStr));
|
||||||
root.addDebugInfo(qsTr("Command property verified: %1").arg(setCmdStr === cmdStr ? "Match" : "MISMATCH"));
|
root.addDebugInfo(qsTr("Command property verified: %1").arg(setCmdStr === cmdStr ? "Match" : "MISMATCH"));
|
||||||
|
|
||||||
// If we're creating a connection profile, we need to activate it after creation
|
// If we're creating a connection profile, we need to activate it after creation
|
||||||
const isConnectionAdd = cmd.length > 0 && cmd[0] === "nmcli" && cmd[1] === "connection" && cmd[2] === "add";
|
const isConnectionAdd = cmd.length > 0 && cmd[0] === "nmcli" && cmd[1] === "connection" && cmd[2] === "add";
|
||||||
|
|
||||||
// Wait a moment before starting to ensure command is set
|
// Wait a moment before starting to ensure command is set
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
root.addDebugInfo(qsTr("=== STARTING PROCESS ==="));
|
root.addDebugInfo(qsTr("=== STARTING PROCESS ==="));
|
||||||
|
|
@ -150,7 +150,7 @@ Singleton {
|
||||||
connectProc.running = true;
|
connectProc.running = true;
|
||||||
root.addDebugInfo(qsTr("Process running set to: %1").arg(connectProc.running));
|
root.addDebugInfo(qsTr("Process running set to: %1").arg(connectProc.running));
|
||||||
root.addDebugInfo(qsTr("========================"));
|
root.addDebugInfo(qsTr("========================"));
|
||||||
|
|
||||||
// Check if process actually started after a short delay
|
// Check if process actually started after a short delay
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
root.addDebugInfo(qsTr("Process status check (100ms later):"));
|
root.addDebugInfo(qsTr("Process status check (100ms later):"));
|
||||||
|
|
@ -162,7 +162,7 @@ Singleton {
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start connection check timer if we have a callback
|
// Start connection check timer if we have a callback
|
||||||
if (callback) {
|
if (callback) {
|
||||||
root.addDebugInfo(qsTr("Starting connection check timer (4 second interval)"));
|
root.addDebugInfo(qsTr("Starting connection check timer (4 second interval)"));
|
||||||
|
|
@ -171,25 +171,25 @@ Singleton {
|
||||||
root.addDebugInfo(qsTr("No callback provided - not starting connection check timer"));
|
root.addDebugInfo(qsTr("No callback provided - not starting connection check timer"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createConnectionWithPassword(ssid: string, bssidUpper: string, password: string): void {
|
function createConnectionWithPassword(ssid: string, bssidUpper: string, password: string): void {
|
||||||
// Create connection profile with all required properties for BSSID + password
|
// Create connection profile with all required properties for BSSID + password
|
||||||
const cmd = ["nmcli", "connection", "add",
|
const cmd = ["nmcli", "connection", "add",
|
||||||
"type", "wifi",
|
"type", "wifi",
|
||||||
"con-name", ssid,
|
"con-name", ssid,
|
||||||
"ifname", "*",
|
"ifname", "*",
|
||||||
"ssid", ssid,
|
"ssid", ssid,
|
||||||
"802-11-wireless.bssid", bssidUpper,
|
"802-11-wireless.bssid", bssidUpper,
|
||||||
"802-11-wireless-security.key-mgmt", "wpa-psk",
|
"802-11-wireless-security.key-mgmt", "wpa-psk",
|
||||||
"802-11-wireless-security.psk", password];
|
"802-11-wireless-security.psk", password];
|
||||||
|
|
||||||
root.setConnectionStatus(qsTr("Connecting to %1 (BSSID: %2)...").arg(ssid).arg(bssidUpper));
|
root.setConnectionStatus(qsTr("Connecting to %1 (BSSID: %2)...").arg(ssid).arg(bssidUpper));
|
||||||
root.addDebugInfo(qsTr("Using BSSID: %1 for SSID: %2").arg(bssidUpper).arg(ssid));
|
root.addDebugInfo(qsTr("Using BSSID: %1 for SSID: %2").arg(bssidUpper).arg(ssid));
|
||||||
root.addDebugInfo(qsTr("Creating connection profile with password and key-mgmt"));
|
root.addDebugInfo(qsTr("Creating connection profile with password and key-mgmt"));
|
||||||
|
|
||||||
// Set command and start process
|
// Set command and start process
|
||||||
connectProc.command = cmd;
|
connectProc.command = cmd;
|
||||||
|
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
connectProc.running = true;
|
connectProc.running = true;
|
||||||
});
|
});
|
||||||
|
|
@ -198,7 +198,7 @@ Singleton {
|
||||||
function connectToNetworkWithPasswordCheck(ssid: string, isSecure: bool, callback: var, bssid: string): void {
|
function connectToNetworkWithPasswordCheck(ssid: string, isSecure: bool, callback: var, bssid: string): void {
|
||||||
root.addDebugInfo(qsTr("=== connectToNetworkWithPasswordCheck ==="));
|
root.addDebugInfo(qsTr("=== connectToNetworkWithPasswordCheck ==="));
|
||||||
root.addDebugInfo(qsTr("SSID: %1, isSecure: %2").arg(ssid).arg(isSecure));
|
root.addDebugInfo(qsTr("SSID: %1, isSecure: %2").arg(ssid).arg(isSecure));
|
||||||
|
|
||||||
// For secure networks, try connecting without password first
|
// For secure networks, try connecting without password first
|
||||||
// If connection succeeds (saved password exists), we're done
|
// If connection succeeds (saved password exists), we're done
|
||||||
// If it fails with password error, callback will be called to show password dialog
|
// If it fails with password error, callback will be called to show password dialog
|
||||||
|
|
@ -228,7 +228,7 @@ Singleton {
|
||||||
disconnectProc.exec(["nmcli", "device", "disconnect", "wifi"]);
|
disconnectProc.exec(["nmcli", "device", "disconnect", "wifi"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function forgetNetwork(ssid: string): void {
|
function forgetNetwork(ssid: string): void {
|
||||||
// Delete the connection profile for this network
|
// Delete the connection profile for this network
|
||||||
// This will remove the saved password and connection settings
|
// This will remove the saved password and connection settings
|
||||||
|
|
@ -240,7 +240,7 @@ Singleton {
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasConnectionProfile(ssid: string): bool {
|
function hasConnectionProfile(ssid: string): bool {
|
||||||
// Check if a connection profile exists for this SSID
|
// Check if a connection profile exists for this SSID
|
||||||
// This is synchronous check - returns true if connection exists
|
// This is synchronous check - returns true if connection exists
|
||||||
|
|
@ -252,12 +252,12 @@ Singleton {
|
||||||
// The actual check will be done asynchronously
|
// The actual check will be done asynchronously
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
property list<string> savedConnections: []
|
property list<string> savedConnections: []
|
||||||
property list<string> savedConnectionSsids: []
|
property list<string> savedConnectionSsids: []
|
||||||
property var wifiConnectionQueue: []
|
property var wifiConnectionQueue: []
|
||||||
property int currentSsidQueryIndex: 0
|
property int currentSsidQueryIndex: 0
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: listConnectionsProc
|
id: listConnectionsProc
|
||||||
command: ["nmcli", "-t", "-f", "NAME,TYPE", "connection", "show"]
|
command: ["nmcli", "-t", "-f", "NAME,TYPE", "connection", "show"]
|
||||||
|
|
@ -276,12 +276,12 @@ Singleton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseConnectionList(output: string): void {
|
function parseConnectionList(output: string): void {
|
||||||
const lines = output.trim().split("\n").filter(line => line.length > 0);
|
const lines = output.trim().split("\n").filter(line => line.length > 0);
|
||||||
const wifiConnections = [];
|
const wifiConnections = [];
|
||||||
const connections = [];
|
const connections = [];
|
||||||
|
|
||||||
// First pass: identify WiFi connections
|
// First pass: identify WiFi connections
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const parts = line.split(":");
|
const parts = line.split(":");
|
||||||
|
|
@ -289,15 +289,15 @@ Singleton {
|
||||||
const name = parts[0];
|
const name = parts[0];
|
||||||
const type = parts[1];
|
const type = parts[1];
|
||||||
connections.push(name);
|
connections.push(name);
|
||||||
|
|
||||||
if (type === "802-11-wireless") {
|
if (type === "802-11-wireless") {
|
||||||
wifiConnections.push(name);
|
wifiConnections.push(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root.savedConnections = connections;
|
root.savedConnections = connections;
|
||||||
|
|
||||||
// Second pass: get SSIDs for WiFi connections
|
// Second pass: get SSIDs for WiFi connections
|
||||||
if (wifiConnections.length > 0) {
|
if (wifiConnections.length > 0) {
|
||||||
root.wifiConnectionQueue = wifiConnections;
|
root.wifiConnectionQueue = wifiConnections;
|
||||||
|
|
@ -310,10 +310,10 @@ Singleton {
|
||||||
root.wifiConnectionQueue = [];
|
root.wifiConnectionQueue = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: getSsidProc
|
id: getSsidProc
|
||||||
|
|
||||||
environment: ({
|
environment: ({
|
||||||
LANG: "C.UTF-8",
|
LANG: "C.UTF-8",
|
||||||
LC_ALL: "C.UTF-8"
|
LC_ALL: "C.UTF-8"
|
||||||
|
|
@ -332,7 +332,7 @@ Singleton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function processSsidOutput(output: string): void {
|
function processSsidOutput(output: string): void {
|
||||||
// Parse "802-11-wireless.ssid:SSID_NAME" format
|
// Parse "802-11-wireless.ssid:SSID_NAME" format
|
||||||
const lines = output.trim().split("\n");
|
const lines = output.trim().split("\n");
|
||||||
|
|
@ -351,11 +351,11 @@ Singleton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query next connection
|
// Query next connection
|
||||||
queryNextSsid();
|
queryNextSsid();
|
||||||
}
|
}
|
||||||
|
|
||||||
function queryNextSsid(): void {
|
function queryNextSsid(): void {
|
||||||
if (root.currentSsidQueryIndex < root.wifiConnectionQueue.length) {
|
if (root.currentSsidQueryIndex < root.wifiConnectionQueue.length) {
|
||||||
const connectionName = root.wifiConnectionQueue[root.currentSsidQueryIndex];
|
const connectionName = root.wifiConnectionQueue[root.currentSsidQueryIndex];
|
||||||
|
|
@ -368,13 +368,13 @@ Singleton {
|
||||||
root.currentSsidQueryIndex = 0;
|
root.currentSsidQueryIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasSavedProfile(ssid: string): bool {
|
function hasSavedProfile(ssid: string): bool {
|
||||||
if (!ssid || ssid.length === 0) {
|
if (!ssid || ssid.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const ssidLower = ssid.toLowerCase().trim();
|
const ssidLower = ssid.toLowerCase().trim();
|
||||||
|
|
||||||
// If currently connected to this network, it definitely has a saved profile
|
// If currently connected to this network, it definitely has a saved profile
|
||||||
if (root.active && root.active.ssid) {
|
if (root.active && root.active.ssid) {
|
||||||
const activeSsidLower = root.active.ssid.toLowerCase().trim();
|
const activeSsidLower = root.active.ssid.toLowerCase().trim();
|
||||||
|
|
@ -382,21 +382,21 @@ Singleton {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if SSID is in saved connections (case-insensitive comparison)
|
// Check if SSID is in saved connections (case-insensitive comparison)
|
||||||
const hasSsid = root.savedConnectionSsids.some(savedSsid =>
|
const hasSsid = root.savedConnectionSsids.some(savedSsid =>
|
||||||
savedSsid && savedSsid.toLowerCase().trim() === ssidLower
|
savedSsid && savedSsid.toLowerCase().trim() === ssidLower
|
||||||
);
|
);
|
||||||
|
|
||||||
if (hasSsid) {
|
if (hasSsid) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback: also check if connection name matches SSID (some connections use SSID as name)
|
// Fallback: also check if connection name matches SSID (some connections use SSID as name)
|
||||||
const hasConnectionName = root.savedConnections.some(connName =>
|
const hasConnectionName = root.savedConnections.some(connName =>
|
||||||
connName && connName.toLowerCase().trim() === ssidLower
|
connName && connName.toLowerCase().trim() === ssidLower
|
||||||
);
|
);
|
||||||
|
|
||||||
return hasConnectionName;
|
return hasConnectionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,7 +442,7 @@ Singleton {
|
||||||
if (isNaN(cidrNum) || cidrNum < 0 || cidrNum > 32) {
|
if (isNaN(cidrNum) || cidrNum < 0 || cidrNum > 32) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const mask = (0xffffffff << (32 - cidrNum)) >>> 0;
|
const mask = (0xffffffff << (32 - cidrNum)) >>> 0;
|
||||||
const octets = [
|
const octets = [
|
||||||
(mask >>> 24) & 0xff,
|
(mask >>> 24) & 0xff,
|
||||||
|
|
@ -450,7 +450,7 @@ Singleton {
|
||||||
(mask >>> 8) & 0xff,
|
(mask >>> 8) & 0xff,
|
||||||
mask & 0xff
|
mask & 0xff
|
||||||
];
|
];
|
||||||
|
|
||||||
return octets.join(".");
|
return octets.join(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -510,7 +510,7 @@ Singleton {
|
||||||
root.addDebugInfo(qsTr(" Pending SSID: %1").arg(root.pendingConnection.ssid));
|
root.addDebugInfo(qsTr(" Pending SSID: %1").arg(root.pendingConnection.ssid));
|
||||||
root.addDebugInfo(qsTr(" Active SSID: %1").arg(root.active ? root.active.ssid : "None"));
|
root.addDebugInfo(qsTr(" Active SSID: %1").arg(root.active ? root.active.ssid : "None"));
|
||||||
root.addDebugInfo(qsTr(" Connected: %1").arg(connected));
|
root.addDebugInfo(qsTr(" Connected: %1").arg(connected));
|
||||||
|
|
||||||
if (!connected && root.pendingConnection.callback) {
|
if (!connected && root.pendingConnection.callback) {
|
||||||
// Connection didn't succeed after multiple checks, show password dialog
|
// Connection didn't succeed after multiple checks, show password dialog
|
||||||
root.addDebugInfo(qsTr("Connection failed - calling password dialog callback"));
|
root.addDebugInfo(qsTr("Connection failed - calling password dialog callback"));
|
||||||
|
|
@ -543,19 +543,19 @@ Singleton {
|
||||||
repeat: true
|
repeat: true
|
||||||
triggeredOnStart: false
|
triggeredOnStart: false
|
||||||
property int checkCount: 0
|
property int checkCount: 0
|
||||||
|
|
||||||
onRunningChanged: {
|
onRunningChanged: {
|
||||||
if (running) {
|
if (running) {
|
||||||
root.addDebugInfo(qsTr("Immediate check timer started (checks every 500ms)"));
|
root.addDebugInfo(qsTr("Immediate check timer started (checks every 500ms)"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (root.pendingConnection) {
|
if (root.pendingConnection) {
|
||||||
checkCount++;
|
checkCount++;
|
||||||
const connected = root.active && root.active.ssid === root.pendingConnection.ssid;
|
const connected = root.active && root.active.ssid === root.pendingConnection.ssid;
|
||||||
root.addDebugInfo(qsTr("Immediate check #%1: Connected=%2").arg(checkCount).arg(connected));
|
root.addDebugInfo(qsTr("Immediate check #%1: Connected=%2").arg(checkCount).arg(connected));
|
||||||
|
|
||||||
if (connected) {
|
if (connected) {
|
||||||
// Connection succeeded, stop timers and clear pending
|
// Connection succeeded, stop timers and clear pending
|
||||||
root.addDebugInfo(qsTr("Connection succeeded on check #%1!").arg(checkCount));
|
root.addDebugInfo(qsTr("Connection succeeded on check #%1!").arg(checkCount));
|
||||||
|
|
@ -586,32 +586,32 @@ Singleton {
|
||||||
onRunningChanged: {
|
onRunningChanged: {
|
||||||
root.addDebugInfo(qsTr("Process running changed to: %1").arg(running));
|
root.addDebugInfo(qsTr("Process running changed to: %1").arg(running));
|
||||||
}
|
}
|
||||||
|
|
||||||
onStarted: {
|
onStarted: {
|
||||||
root.addDebugInfo(qsTr("Process started successfully"));
|
root.addDebugInfo(qsTr("Process started successfully"));
|
||||||
}
|
}
|
||||||
|
|
||||||
onExited: {
|
onExited: {
|
||||||
root.addDebugInfo(qsTr("=== PROCESS EXITED ==="));
|
root.addDebugInfo(qsTr("=== PROCESS EXITED ==="));
|
||||||
root.addDebugInfo(qsTr("Exit code: %1").arg(exitCode));
|
root.addDebugInfo(qsTr("Exit code: %1").arg(exitCode));
|
||||||
root.addDebugInfo(qsTr("(Exit code 0 = success, non-zero = error)"));
|
root.addDebugInfo(qsTr("(Exit code 0 = success, non-zero = error)"));
|
||||||
|
|
||||||
// Check if this was a "connection add" command - if so, we need to activate it
|
// Check if this was a "connection add" command - if so, we need to activate it
|
||||||
const wasConnectionAdd = connectProc.command && connectProc.command.length > 0
|
const wasConnectionAdd = connectProc.command && connectProc.command.length > 0
|
||||||
&& connectProc.command[0] === "nmcli"
|
&& connectProc.command[0] === "nmcli"
|
||||||
&& connectProc.command[1] === "connection"
|
&& connectProc.command[1] === "connection"
|
||||||
&& connectProc.command[2] === "add";
|
&& connectProc.command[2] === "add";
|
||||||
|
|
||||||
if (wasConnectionAdd && root.pendingConnection) {
|
if (wasConnectionAdd && root.pendingConnection) {
|
||||||
const ssid = root.pendingConnection.ssid;
|
const ssid = root.pendingConnection.ssid;
|
||||||
|
|
||||||
// Check for duplicate connection warning in stderr text
|
// Check for duplicate connection warning in stderr text
|
||||||
const stderrText = connectProc.stderr ? connectProc.stderr.text : "";
|
const stderrText = connectProc.stderr ? connectProc.stderr.text : "";
|
||||||
const hasDuplicateWarning = stderrText && (
|
const hasDuplicateWarning = stderrText && (
|
||||||
stderrText.includes("another connection with the name") ||
|
stderrText.includes("another connection with the name") ||
|
||||||
stderrText.includes("Reference the connection by its uuid")
|
stderrText.includes("Reference the connection by its uuid")
|
||||||
);
|
);
|
||||||
|
|
||||||
// Even with duplicate warning (or if connection already exists), we should try to activate it
|
// Even with duplicate warning (or if connection already exists), we should try to activate it
|
||||||
// Also try if exit code is non-zero but small (might be a warning, not a real error)
|
// Also try if exit code is non-zero but small (might be a warning, not a real error)
|
||||||
if (exitCode === 0 || hasDuplicateWarning || (exitCode > 0 && exitCode < 10)) {
|
if (exitCode === 0 || hasDuplicateWarning || (exitCode > 0 && exitCode < 10)) {
|
||||||
|
|
@ -622,10 +622,10 @@ Singleton {
|
||||||
root.addDebugInfo(qsTr("Connection profile created successfully, now activating: %1").arg(ssid));
|
root.addDebugInfo(qsTr("Connection profile created successfully, now activating: %1").arg(ssid));
|
||||||
root.setConnectionStatus(qsTr("Activating connection..."));
|
root.setConnectionStatus(qsTr("Activating connection..."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update saved connections list
|
// Update saved connections list
|
||||||
listConnectionsProc.running = true;
|
listConnectionsProc.running = true;
|
||||||
|
|
||||||
// Try to activate the connection by SSID (connection name)
|
// Try to activate the connection by SSID (connection name)
|
||||||
connectProc.command = ["nmcli", "connection", "up", ssid];
|
connectProc.command = ["nmcli", "connection", "up", ssid];
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
|
|
@ -644,7 +644,7 @@ Singleton {
|
||||||
password = connectProc.command[pskIndex + 1];
|
password = connectProc.command[pskIndex + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password && password.length > 0) {
|
if (password && password.length > 0) {
|
||||||
root.addDebugInfo(qsTr("Using device wifi connect with password as fallback"));
|
root.addDebugInfo(qsTr("Using device wifi connect with password as fallback"));
|
||||||
connectProc.command = ["nmcli", "device", "wifi", "connect", ssid, "password", password];
|
connectProc.command = ["nmcli", "device", "wifi", "connect", ssid, "password", password];
|
||||||
|
|
@ -655,10 +655,10 @@ Singleton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh network list after connection attempt
|
// Refresh network list after connection attempt
|
||||||
getNetworks.running = true;
|
getNetworks.running = true;
|
||||||
|
|
||||||
// Check if connection succeeded after a short delay (network list needs to update)
|
// Check if connection succeeded after a short delay (network list needs to update)
|
||||||
if (root.pendingConnection) {
|
if (root.pendingConnection) {
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
|
|
@ -704,10 +704,10 @@ Singleton {
|
||||||
root.addDebugInfo(qsTr("STDERR: %1").arg(line));
|
root.addDebugInfo(qsTr("STDERR: %1").arg(line));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for specific errors that indicate password is needed
|
// Check for specific errors that indicate password is needed
|
||||||
// Be careful not to match success messages
|
// Be careful not to match success messages
|
||||||
const needsPassword = (error.includes("Secrets were required") ||
|
const needsPassword = (error.includes("Secrets were required") ||
|
||||||
error.includes("No secrets provided") ||
|
error.includes("No secrets provided") ||
|
||||||
error.includes("802-11-wireless-security.psk") ||
|
error.includes("802-11-wireless-security.psk") ||
|
||||||
(error.includes("password") && !error.includes("Connection activated")) ||
|
(error.includes("password") && !error.includes("Connection activated")) ||
|
||||||
|
|
@ -715,7 +715,7 @@ Singleton {
|
||||||
(error.includes("802.11") && !error.includes("Connection activated"))) &&
|
(error.includes("802.11") && !error.includes("Connection activated"))) &&
|
||||||
!error.includes("Connection activated") &&
|
!error.includes("Connection activated") &&
|
||||||
!error.includes("successfully");
|
!error.includes("successfully");
|
||||||
|
|
||||||
if (needsPassword && root.pendingConnection && root.pendingConnection.callback) {
|
if (needsPassword && root.pendingConnection && root.pendingConnection.callback) {
|
||||||
// Connection failed because password is needed - show dialog immediately
|
// Connection failed because password is needed - show dialog immediately
|
||||||
connectionCheckTimer.stop();
|
connectionCheckTimer.stop();
|
||||||
|
|
@ -784,7 +784,7 @@ Singleton {
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: deleteConnectionProc
|
id: deleteConnectionProc
|
||||||
|
|
||||||
// Delete connection profile - refresh network list and saved connections after deletion
|
// Delete connection profile - refresh network list and saved connections after deletion
|
||||||
onExited: {
|
onExited: {
|
||||||
// Refresh network list and saved connections after deletion
|
// Refresh network list and saved connections after deletion
|
||||||
|
|
@ -924,12 +924,12 @@ Singleton {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
const output = text.trim();
|
const output = text.trim();
|
||||||
root.ethernetDebugInfo = "Output received in onStreamFinished! Length: " + output.length + ", First 100 chars: " + output.substring(0, 100);
|
root.ethernetDebugInfo = "Output received in onStreamFinished! Length: " + output.length + ", First 100 chars: " + output.substring(0, 100);
|
||||||
|
|
||||||
if (!output || output.length === 0) {
|
if (!output || output.length === 0) {
|
||||||
root.ethernetDebugInfo = "No output received (empty)";
|
root.ethernetDebugInfo = "No output received (empty)";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
root.processEthernetOutput(output);
|
root.processEthernetOutput(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -942,7 +942,7 @@ Singleton {
|
||||||
|
|
||||||
const lines = output.split("\n");
|
const lines = output.split("\n");
|
||||||
root.ethernetDebugInfo = "Processing " + lines.length + " lines";
|
root.ethernetDebugInfo = "Processing " + lines.length + " lines";
|
||||||
|
|
||||||
const allDevices = lines.map(d => {
|
const allDevices = lines.map(d => {
|
||||||
const dev = d.replace(rep, PLACEHOLDER).split(":");
|
const dev = d.replace(rep, PLACEHOLDER).split(":");
|
||||||
return {
|
return {
|
||||||
|
|
@ -952,9 +952,9 @@ Singleton {
|
||||||
connection: dev[3]?.replace(rep2, ":") ?? ""
|
connection: dev[3]?.replace(rep2, ":") ?? ""
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
root.ethernetDebugInfo = "All devices: " + allDevices.length + ", Types: " + allDevices.map(d => d.type).join(", ");
|
root.ethernetDebugInfo = "All devices: " + allDevices.length + ", Types: " + allDevices.map(d => d.type).join(", ");
|
||||||
|
|
||||||
const ethernetOnly = allDevices.filter(d => d.type === "ethernet");
|
const ethernetOnly = allDevices.filter(d => d.type === "ethernet");
|
||||||
root.ethernetDebugInfo = "Ethernet devices found: " + ethernetOnly.length;
|
root.ethernetDebugInfo = "Ethernet devices found: " + ethernetOnly.length;
|
||||||
|
|
||||||
|
|
@ -975,7 +975,7 @@ Singleton {
|
||||||
speed: ""
|
speed: ""
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
root.ethernetDebugInfo = "Ethernet devices processed: " + ethernetDevices.length + ", First device: " + (ethernetDevices[0]?.interface || "none");
|
root.ethernetDebugInfo = "Ethernet devices processed: " + ethernetDevices.length + ", First device: " + (ethernetDevices[0]?.interface || "none");
|
||||||
|
|
||||||
// Update the list - replace the entire array to ensure QML detects the change
|
// Update the list - replace the entire array to ensure QML detects the change
|
||||||
|
|
@ -984,13 +984,13 @@ Singleton {
|
||||||
for (let i = 0; i < ethernetDevices.length; i++) {
|
for (let i = 0; i < ethernetDevices.length; i++) {
|
||||||
newDevices.push(ethernetDevices[i]);
|
newDevices.push(ethernetDevices[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the entire list
|
// Replace the entire list
|
||||||
root.ethernetDevices = newDevices;
|
root.ethernetDevices = newDevices;
|
||||||
|
|
||||||
// Force QML to detect the change by updating a property
|
// Force QML to detect the change by updating a property
|
||||||
root.ethernetDeviceCount = ethernetDevices.length;
|
root.ethernetDeviceCount = ethernetDevices.length;
|
||||||
|
|
||||||
// Force QML to re-evaluate the list by accessing it
|
// Force QML to re-evaluate the list by accessing it
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
const count = root.ethernetDevices.length;
|
const count = root.ethernetDevices.length;
|
||||||
|
|
@ -1130,7 +1130,7 @@ const line = lines[i];
|
||||||
// Find the connected wifi interface from device status
|
// Find the connected wifi interface from device status
|
||||||
const lines = output.split("\n");
|
const lines = output.split("\n");
|
||||||
let wifiInterface = "";
|
let wifiInterface = "";
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
const parts = line.split(/\s+/);
|
const parts = line.split(/\s+/);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ Singleton {
|
||||||
const name = providerName;
|
const name = providerName;
|
||||||
const iface = interfaceName;
|
const iface = interfaceName;
|
||||||
const defaults = getBuiltinDefaults(name, iface);
|
const defaults = getBuiltinDefaults(name, iface);
|
||||||
|
|
||||||
if (isCustomProvider) {
|
if (isCustomProvider) {
|
||||||
const custom = providerInput;
|
const custom = providerInput;
|
||||||
return {
|
return {
|
||||||
|
|
@ -31,7 +31,7 @@ Singleton {
|
||||||
displayName: custom.displayName || defaults.displayName
|
displayName: custom.displayName || defaults.displayName
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaults;
|
return defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ Singleton {
|
||||||
displayName: "Tailscale"
|
displayName: "Tailscale"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return builtins[name] || {
|
return builtins[name] || {
|
||||||
connectCmd: [name, "up"],
|
connectCmd: [name, "up"],
|
||||||
disconnectCmd: [name, "down"],
|
disconnectCmd: [name, "down"],
|
||||||
|
|
|
||||||
|
|
@ -194,13 +194,13 @@ Singleton {
|
||||||
|
|
||||||
function getSpecialWsIcon(name: string): string {
|
function getSpecialWsIcon(name: string): string {
|
||||||
name = name.toLowerCase().slice("special:".length);
|
name = name.toLowerCase().slice("special:".length);
|
||||||
|
|
||||||
for (const iconConfig of Config.bar.workspaces.specialWorkspaceIcons) {
|
for (const iconConfig of Config.bar.workspaces.specialWorkspaceIcons) {
|
||||||
if (iconConfig.name === name) {
|
if (iconConfig.name === name) {
|
||||||
return iconConfig.icon;
|
return iconConfig.icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === "special")
|
if (name === "special")
|
||||||
return "star";
|
return "star";
|
||||||
if (name === "communication")
|
if (name === "communication")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue