1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-10 07:25:37 -05:00

nm: updates for NM agent in DMS API v7

This commit is contained in:
bbedward
2025-10-21 14:27:42 -04:00
parent 50ce5cf257
commit 9b6fb29d46
6 changed files with 319 additions and 67 deletions

View File

@@ -197,17 +197,19 @@ Item {
}
}
LazyLoader {
id: wifiPasswordModalLoader
WifiPasswordModal {
id: wifiPasswordModal
active: false
Component.onCompleted: {
PopoutService.wifiPasswordModal = wifiPasswordModal
}
}
WifiPasswordModal {
id: wifiPasswordModal
Connections {
target: NetworkService
Component.onCompleted: {
PopoutService.wifiPasswordModal = wifiPasswordModal
}
function onCredentialsNeeded(token, ssid, setting, fields, hints, reason) {
wifiPasswordModal.showFromPrompt(token, ssid, setting, fields, hints, reason)
}
}

View File

@@ -15,12 +15,23 @@ DankModal {
property string wifiAnonymousIdentityInput: ""
property string wifiDomainInput: ""
property bool isPromptMode: false
property string promptToken: ""
property string promptReason: ""
property var promptFields: []
property string promptSetting: ""
function show(ssid) {
wifiPasswordSSID = ssid
wifiPasswordInput = ""
wifiUsernameInput = ""
wifiAnonymousIdentityInput = ""
wifiDomainInput = ""
isPromptMode = false
promptToken = ""
promptReason = ""
promptFields = []
promptSetting = ""
const network = NetworkService.wifiNetworks.find(n => n.ssid === ssid)
requiresEnterprise = network?.enterprise || false
@@ -37,6 +48,41 @@ DankModal {
})
}
function showFromPrompt(token, ssid, setting, fields, hints, reason) {
wifiPasswordSSID = ssid
isPromptMode = true
promptToken = token
promptReason = reason
promptFields = fields || []
promptSetting = setting || "802-11-wireless-security"
requiresEnterprise = setting === "802-1x"
if (reason === "wrong-password") {
wifiPasswordInput = ""
wifiUsernameInput = ""
} else {
wifiPasswordInput = ""
wifiUsernameInput = ""
wifiAnonymousIdentityInput = ""
wifiDomainInput = ""
}
open()
Qt.callLater(() => {
if (contentLoader.item) {
if (reason === "wrong-password" && contentLoader.item.passwordInput) {
contentLoader.item.passwordInput.text = ""
contentLoader.item.passwordInput.forceActiveFocus()
} else if (requiresEnterprise && contentLoader.item.usernameInput) {
contentLoader.item.usernameInput.forceActiveFocus()
} else if (contentLoader.item.passwordInput) {
contentLoader.item.passwordInput.forceActiveFocus()
}
}
})
}
shouldBeVisible: false
width: 420
height: requiresEnterprise ? 430 : 230
@@ -60,6 +106,9 @@ DankModal {
})
}
onBackgroundClicked: () => {
if (isPromptMode) {
NetworkService.cancelCredentials(promptToken)
}
close()
wifiPasswordInput = ""
wifiUsernameInput = ""
@@ -90,6 +139,9 @@ DankModal {
anchors.fill: parent
focus: true
Keys.onEscapePressed: event => {
if (isPromptMode) {
NetworkService.cancelCredentials(promptToken)
}
close()
wifiPasswordInput = ""
wifiUsernameInput = ""
@@ -117,12 +169,28 @@ DankModal {
font.weight: Font.Medium
}
StyledText {
text: requiresEnterprise ? I18n.tr("Enter credentials for ") + wifiPasswordSSID : I18n.tr("Enter password for ") + wifiPasswordSSID
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceTextMedium
Column {
width: parent.width
elide: Text.ElideRight
spacing: Theme.spacingXS
StyledText {
text: {
const prefix = requiresEnterprise ? I18n.tr("Enter credentials for ") : I18n.tr("Enter password for ")
return prefix + wifiPasswordSSID
}
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceTextMedium
width: parent.width
elide: Text.ElideRight
}
StyledText {
visible: isPromptMode && promptReason === "wrong-password"
text: I18n.tr("Incorrect password")
font.pixelSize: Theme.fontSizeSmall
color: Theme.error
width: parent.width
}
}
}
@@ -131,6 +199,9 @@ DankModal {
iconSize: Theme.iconSize - 4
iconColor: Theme.surfaceText
onClicked: () => {
if (isPromptMode) {
NetworkService.cancelCredentials(promptToken)
}
close()
wifiPasswordInput = ""
wifiUsernameInput = ""
@@ -208,14 +279,26 @@ DankModal {
wifiPasswordInput = text
}
onAccepted: () => {
const username = requiresEnterprise ? usernameInput.text : ""
NetworkService.connectToWifi(
wifiPasswordSSID,
passwordInput.text,
username,
wifiAnonymousIdentityInput,
wifiDomainInput
)
if (isPromptMode) {
const secrets = {}
if (promptSetting === "802-11-wireless-security") {
secrets["psk"] = passwordInput.text
} else if (promptSetting === "802-1x") {
if (usernameInput.text) secrets["identity"] = usernameInput.text
if (passwordInput.text) secrets["password"] = passwordInput.text
if (wifiAnonymousIdentityInput) secrets["anonymous-identity"] = wifiAnonymousIdentityInput
}
NetworkService.submitCredentials(promptToken, secrets, true)
} else {
const username = requiresEnterprise ? usernameInput.text : ""
NetworkService.connectToWifi(
wifiPasswordSSID,
passwordInput.text,
username,
wifiAnonymousIdentityInput,
wifiDomainInput
)
}
close()
wifiPasswordInput = ""
wifiUsernameInput = ""
@@ -395,6 +478,9 @@ DankModal {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: () => {
if (isPromptMode) {
NetworkService.cancelCredentials(promptToken)
}
close()
wifiPasswordInput = ""
wifiUsernameInput = ""
@@ -430,14 +516,26 @@ DankModal {
cursorShape: Qt.PointingHandCursor
enabled: parent.enabled
onClicked: () => {
const username = requiresEnterprise ? usernameInput.text : ""
NetworkService.connectToWifi(
wifiPasswordSSID,
passwordInput.text,
username,
wifiAnonymousIdentityInput,
wifiDomainInput
)
if (isPromptMode) {
const secrets = {}
if (promptSetting === "802-11-wireless-security") {
secrets["psk"] = passwordInput.text
} else if (promptSetting === "802-1x") {
if (usernameInput.text) secrets["identity"] = usernameInput.text
if (passwordInput.text) secrets["password"] = passwordInput.text
if (wifiAnonymousIdentityInput) secrets["anonymous-identity"] = wifiAnonymousIdentityInput
}
NetworkService.submitCredentials(promptToken, secrets, true)
} else {
const username = requiresEnterprise ? usernameInput.text : ""
NetworkService.connectToWifi(
wifiPasswordSSID,
passwordInput.text,
username,
wifiAnonymousIdentityInput,
wifiDomainInput
)
}
close()
wifiPasswordInput = ""
wifiUsernameInput = ""

View File

@@ -509,7 +509,11 @@ Rectangle {
onClicked: function(event) {
if (modelData.ssid !== NetworkService.currentWifiSSID) {
if (modelData.secured && !modelData.saved) {
wifiPasswordModal.show(modelData.ssid)
if (DMSService.apiVersion >= 7) {
NetworkService.connectToWifi(modelData.ssid)
} else if (PopoutService.wifiPasswordModal) {
PopoutService.wifiPasswordModal.show(modelData.ssid)
}
} else {
NetworkService.connectToWifi(modelData.ssid)
}
@@ -563,7 +567,11 @@ Rectangle {
NetworkService.disconnectWifi()
} else {
if (networkContextMenu.currentSecured && !networkContextMenu.currentSaved) {
wifiPasswordModal.show(networkContextMenu.currentSSID)
if (DMSService.apiVersion >= 7) {
NetworkService.connectToWifi(networkContextMenu.currentSSID)
} else if (PopoutService.wifiPasswordModal) {
PopoutService.wifiPasswordModal.show(networkContextMenu.currentSSID)
}
} else {
NetworkService.connectToWifi(networkContextMenu.currentSSID)
}
@@ -618,10 +626,6 @@ Rectangle {
}
}
WifiPasswordModal {
id: wifiPasswordModal
}
NetworkInfoModal {
id: networkInfoModal
}

View File

@@ -41,6 +41,7 @@ Singleton {
signal loginctlStateUpdate(var data)
signal loginctlEvent(var event)
signal capabilitiesReceived()
signal credentialsRequest(var data)
Component.onCompleted: {
if (socketPath && socketPath.length > 0) {
@@ -261,6 +262,8 @@ Singleton {
capabilitiesReceived()
} else if (service === "network") {
networkStateUpdate(data)
} else if (service === "network.credentials") {
credentialsRequest(data)
} else if (service === "loginctl") {
if (data.event) {
loginctlEvent(data)

View File

@@ -79,8 +79,21 @@ Singleton {
property int refCount: 0
property bool stateInitialized: false
property string credentialsToken: ""
property string credentialsSSID: ""
property string credentialsSetting: ""
property var credentialsFields: []
property var credentialsHints: []
property string credentialsReason: ""
property bool credentialsRequested: false
property string pendingConnectionSSID: ""
property var pendingConnectionStartTime: 0
property bool wasConnecting: false
signal networksUpdated
signal connectionChanged
signal credentialsNeeded(string token, string ssid, string setting, var fields, var hints, string reason)
readonly property string socketPath: Quickshell.env("DMS_SOCKET")
@@ -120,6 +133,10 @@ Singleton {
function onCapabilitiesChanged() {
checkDMSCapabilities()
}
function onCredentialsRequest(data) {
handleCredentialsRequest(data)
}
}
function checkDMSCapabilities() {
@@ -143,6 +160,18 @@ Singleton {
}
}
function handleCredentialsRequest(data) {
credentialsToken = data.token || ""
credentialsSSID = data.ssid || ""
credentialsSetting = data.setting || "802-11-wireless-security"
credentialsFields = data.fields || ["psk"]
credentialsHints = data.hints || []
credentialsReason = data.reason || "Credentials required"
credentialsRequested = true
credentialsNeeded(credentialsToken, credentialsSSID, credentialsSetting, credentialsFields, credentialsHints, credentialsReason)
}
function addRef() {
refCount++
if (refCount === 1 && networkAvailable) {
@@ -177,6 +206,9 @@ Singleton {
}
function updateState(state) {
const previousConnecting = isConnecting
const previousConnectingSSID = connectingSSID
networkStatus = state.networkStatus || "disconnected"
primaryConnection = state.primaryConnection || ""
@@ -225,6 +257,45 @@ Singleton {
connectionError = state.lastError || ""
lastConnectionError = state.lastError || ""
if (pendingConnectionSSID) {
if (wifiConnected && currentWifiSSID === pendingConnectionSSID && wifiIP) {
if (DMSService.verboseLogs) {
const elapsed = Date.now() - pendingConnectionStartTime
console.log("NetworkManagerService: Successfully connected to", pendingConnectionSSID, "in", elapsed, "ms")
}
ToastService.showInfo(`Connected to ${pendingConnectionSSID}`)
if (userPreference === "wifi" || userPreference === "auto") {
setConnectionPriority("wifi")
}
pendingConnectionSSID = ""
connectionStatus = "connected"
} else if (previousConnecting && !isConnecting && !wifiConnected) {
const elapsed = Date.now() - pendingConnectionStartTime
if (elapsed < 5000) {
if (DMSService.verboseLogs) {
console.log("NetworkManagerService: Quick connection failure, likely authentication error")
}
connectionStatus = "invalid_password"
} else {
if (DMSService.verboseLogs) {
console.log("NetworkManagerService: Connection failed for", pendingConnectionSSID)
}
if (connectionError === "connection-failed") {
ToastService.showError(I18n.tr("Connection failed. Check password and try again."))
} else if (connectionError) {
ToastService.showError(I18n.tr("Failed to connect to ") + pendingConnectionSSID)
}
connectionStatus = "failed"
pendingConnectionSSID = ""
}
}
}
wasConnecting = isConnecting
connectionChanged()
}
@@ -242,11 +313,11 @@ Singleton {
connectionError = response.error
lastConnectionError = response.error
connectionStatus = "failed"
ToastService.showError(`Failed to activate configuration`)
ToastService.showError(I18n.tr("Failed to activate configuration"))
} else {
connectionError = ""
connectionStatus = "connected"
ToastService.showInfo(`Configuration activated`)
ToastService.showInfo(I18n.tr("Configuration activated"))
}
isConnecting = false
@@ -280,42 +351,47 @@ Singleton {
function connectToWifi(ssid, password = "", username = "", anonymousIdentity = "", domainSuffixMatch = "") {
if (!networkAvailable || isConnecting) return
connectingSSID = ssid
pendingConnectionSSID = ssid
pendingConnectionStartTime = Date.now()
connectionError = ""
connectionStatus = "connecting"
credentialsRequested = false
const params = { ssid: ssid }
if (password) params.password = password
if (username) params.username = username
if (anonymousIdentity) params.anonymousIdentity = anonymousIdentity
if (domainSuffixMatch) params.domainSuffixMatch = domainSuffixMatch
if (DMSService.apiVersion >= 7) {
if (password || username) {
params.password = password
if (username) params.username = username
if (anonymousIdentity) params.anonymousIdentity = anonymousIdentity
if (domainSuffixMatch) params.domainSuffixMatch = domainSuffixMatch
params.interactive = false
} else {
params.interactive = true
}
} else {
if (password) params.password = password
if (username) params.username = username
if (anonymousIdentity) params.anonymousIdentity = anonymousIdentity
if (domainSuffixMatch) params.domainSuffixMatch = domainSuffixMatch
}
DMSService.sendRequest("network.wifi.connect", params, response => {
if (response.error) {
if (DMSService.verboseLogs) {
console.log("NetworkManagerService: Connection request failed:", response.error)
}
connectionError = response.error
lastConnectionError = response.error
connectionStatus = response.error.includes("password") || response.error.includes("authentication")
? "invalid_password"
: "failed"
if (connectionStatus === "invalid_password") {
passwordDialogShouldReopen = true
ToastService.showError(`Invalid password for ${ssid}`)
} else {
ToastService.showError(`Failed to connect to ${ssid}`)
}
pendingConnectionSSID = ""
connectionStatus = "failed"
ToastService.showError(I18n.tr("Failed to start connection to ") + ssid)
} else {
connectionError = ""
connectionStatus = "connected"
ToastService.showInfo(`Connected to ${ssid}`)
if (userPreference === "wifi" || userPreference === "auto") {
setConnectionPriority("wifi")
if (DMSService.verboseLogs) {
console.log("NetworkManagerService: Connection request sent for", ssid)
}
}
isConnecting = false
connectingSSID = ""
})
}
@@ -324,15 +400,60 @@ Singleton {
DMSService.sendRequest("network.wifi.disconnect", null, response => {
if (response.error) {
ToastService.showError("Failed to disconnect WiFi")
ToastService.showError(I18n.tr("Failed to disconnect WiFi"))
} else {
ToastService.showInfo("Disconnected from WiFi")
ToastService.showInfo(I18n.tr("Disconnected from WiFi"))
currentWifiSSID = ""
connectionStatus = ""
}
})
}
function submitCredentials(token, secrets, save) {
if (!networkAvailable || DMSService.apiVersion < 7) return
const params = {
token: token,
secrets: secrets,
save: save || false
}
if (DMSService.verboseLogs) {
console.log("NetworkManagerService: Submitting credentials for token", token)
}
credentialsRequested = false
DMSService.sendRequest("network.credentials.submit", params, response => {
if (response.error) {
console.warn("NetworkManagerService: Failed to submit credentials:", response.error)
}
})
}
function cancelCredentials(token) {
if (!networkAvailable || DMSService.apiVersion < 7) return
const params = {
token: token,
cancel: true
}
if (DMSService.verboseLogs) {
console.log("NetworkManagerService: Cancelling credentials for token", token)
}
credentialsRequested = false
pendingConnectionSSID = ""
connectionStatus = "cancelled"
DMSService.sendRequest("network.credentials.submit", params, response => {
if (response.error) {
console.warn("NetworkManagerService: Failed to cancel credentials:", response.error)
}
})
}
function forgetWifiNetwork(ssid) {
if (!networkAvailable) return
@@ -341,7 +462,7 @@ Singleton {
if (response.error) {
console.warn("Failed to forget network:", response.error)
} else {
ToastService.showInfo(`Forgot network ${ssid}`)
ToastService.showInfo(I18n.tr("Forgot network ") + ssid)
savedConnections = savedConnections.filter(s => s.ssid !== ssid)
savedWifiNetworks = savedWifiNetworks.filter(s => s.ssid !== ssid)
@@ -374,7 +495,7 @@ Singleton {
console.warn("Failed to toggle WiFi:", response.error)
} else if (response.result) {
wifiEnabled = response.result.enabled
ToastService.showInfo(wifiEnabled ? "WiFi enabled" : "WiFi disabled")
ToastService.showInfo(wifiEnabled ? I18n.tr("WiFi enabled") : I18n.tr("WiFi disabled"))
}
})
}
@@ -384,9 +505,9 @@ Singleton {
DMSService.sendRequest("network.wifi.enable", null, response => {
if (response.error) {
ToastService.showError("Failed to enable WiFi")
ToastService.showError(I18n.tr("Failed to enable WiFi"))
} else {
ToastService.showInfo("WiFi enabled")
ToastService.showInfo(I18n.tr("WiFi enabled"))
}
})
}

View File

@@ -69,8 +69,17 @@ Singleton {
property bool subscriptionConnected: activeService?.subscriptionConnected ?? false
property string credentialsToken: activeService?.credentialsToken ?? ""
property string credentialsSSID: activeService?.credentialsSSID ?? ""
property string credentialsSetting: activeService?.credentialsSetting ?? ""
property var credentialsFields: activeService?.credentialsFields ?? []
property var credentialsHints: activeService?.credentialsHints ?? []
property string credentialsReason: activeService?.credentialsReason ?? ""
property bool credentialsRequested: activeService?.credentialsRequested ?? false
signal networksUpdated
signal connectionChanged
signal credentialsNeeded(string token, string ssid, string setting, var fields, var hints, string reason)
property bool usingLegacy: false
property var activeService: null
@@ -122,6 +131,9 @@ Singleton {
if (activeService.connectionChanged) {
activeService.connectionChanged.connect(root.connectionChanged)
}
if (activeService.credentialsNeeded) {
activeService.credentialsNeeded.connect(root.credentialsNeeded)
}
}
}
@@ -258,4 +270,16 @@ Singleton {
activeService.connectToSpecificWiredConfig(uuid)
}
}
function submitCredentials(token, secrets, save) {
if (activeService && activeService.submitCredentials) {
activeService.submitCredentials(token, secrets, save)
}
}
function cancelCredentials(token) {
if (activeService && activeService.cancelCredentials) {
activeService.cancelCredentials(token)
}
}
}