cleanup: trailing whitespace removeal (entire project)

This commit is contained in:
ATMDA 2025-11-13 14:41:14 -05:00
parent e9113a1710
commit 1da9c68be8
11 changed files with 137 additions and 137 deletions

View file

@ -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

View file

@ -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;
} }

View file

@ -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) {

View file

@ -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,

View file

@ -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,

View file

@ -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) {

View file

@ -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)

View file

@ -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) {

View file

@ -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+/);

View file

@ -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"],

View file

@ -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")