mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
- Scrap janky NetworkService in favor of, dms' native NM integration socket - Scrap all gdbus usage in favor of native dbus bindings in dms (loginctl, freedesktop) It means that - some features won't work if running without dms wrapper. But the trade off is certainly worth it, in the long-run for efficiency improvements.
244 lines
6.6 KiB
QML
244 lines
6.6 KiB
QML
pragma Singleton
|
|
|
|
pragma ComponentBehavior: Bound
|
|
|
|
import QtCore
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Common
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
property bool dmsAvailable: false
|
|
property var capabilities: []
|
|
property var availablePlugins: []
|
|
property var installedPlugins: []
|
|
property bool isConnected: false
|
|
property bool isConnecting: false
|
|
|
|
readonly property string socketPath: Quickshell.env("DMS_SOCKET")
|
|
|
|
property var pendingRequests: ({})
|
|
property int requestIdCounter: 0
|
|
|
|
signal pluginsListReceived(var plugins)
|
|
signal installedPluginsReceived(var plugins)
|
|
signal searchResultsReceived(var plugins)
|
|
signal operationSuccess(string message)
|
|
signal operationError(string error)
|
|
signal connectionStateChanged()
|
|
|
|
Component.onCompleted: {
|
|
if (socketPath && socketPath.length > 0) {
|
|
checkSocket()
|
|
}
|
|
}
|
|
|
|
function checkSocket() {
|
|
testProcess.running = true
|
|
}
|
|
|
|
Process {
|
|
id: testProcess
|
|
command: ["test", "-S", root.socketPath]
|
|
|
|
onExited: exitCode => {
|
|
if (exitCode === 0) {
|
|
root.dmsAvailable = true
|
|
connectSocket()
|
|
} else {
|
|
root.dmsAvailable = false
|
|
}
|
|
}
|
|
}
|
|
|
|
function connectSocket() {
|
|
if (!dmsAvailable || isConnected || isConnecting) {
|
|
return
|
|
}
|
|
|
|
isConnecting = true
|
|
socket.connected = true
|
|
}
|
|
|
|
DankSocket {
|
|
id: socket
|
|
path: root.socketPath
|
|
connected: false
|
|
|
|
onConnectionStateChanged: {
|
|
if (connected) {
|
|
root.isConnected = true
|
|
root.isConnecting = false
|
|
root.connectionStateChanged()
|
|
} else {
|
|
root.isConnected = false
|
|
root.isConnecting = false
|
|
root.connectionStateChanged()
|
|
}
|
|
}
|
|
|
|
parser: SplitParser {
|
|
onRead: line => {
|
|
if (!line || line.length === 0) {
|
|
return
|
|
}
|
|
|
|
try {
|
|
const response = JSON.parse(line)
|
|
|
|
if (response.capabilities) {
|
|
root.capabilities = response.capabilities
|
|
return
|
|
}
|
|
|
|
handleResponse(response)
|
|
} catch (e) {
|
|
console.warn("DMSService: Failed to parse response:", line, e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function sendRequest(method, params, callback) {
|
|
if (!isConnected) {
|
|
if (callback) {
|
|
callback({
|
|
"error": "not connected to DMS socket"
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
requestIdCounter++
|
|
const id = Date.now() + requestIdCounter
|
|
const request = {
|
|
"id": id,
|
|
"method": method
|
|
}
|
|
|
|
if (params) {
|
|
request.params = params
|
|
}
|
|
|
|
if (callback) {
|
|
pendingRequests[id] = callback
|
|
}
|
|
|
|
socket.send(request)
|
|
}
|
|
|
|
property var networkUpdateCallback: null
|
|
|
|
function handleResponse(response) {
|
|
if (response.id === undefined && response.result) {
|
|
if (response.result.type === "state_changed" && response.result.data) {
|
|
if (networkUpdateCallback) {
|
|
networkUpdateCallback(response.result.data)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
const callback = pendingRequests[response.id]
|
|
|
|
if (callback) {
|
|
delete pendingRequests[response.id]
|
|
callback(response)
|
|
}
|
|
}
|
|
|
|
function ping(callback) {
|
|
sendRequest("ping", null, callback)
|
|
}
|
|
|
|
function listPlugins(callback) {
|
|
sendRequest("plugins.list", null, response => {
|
|
if (response.result) {
|
|
availablePlugins = response.result
|
|
pluginsListReceived(response.result)
|
|
}
|
|
if (callback) {
|
|
callback(response)
|
|
}
|
|
})
|
|
}
|
|
|
|
function listInstalled(callback) {
|
|
sendRequest("plugins.listInstalled", null, response => {
|
|
if (response.result) {
|
|
installedPlugins = response.result
|
|
installedPluginsReceived(response.result)
|
|
}
|
|
if (callback) {
|
|
callback(response)
|
|
}
|
|
})
|
|
}
|
|
|
|
function search(query, category, compositor, capability, callback) {
|
|
const params = {
|
|
"query": query
|
|
}
|
|
if (category) {
|
|
params.category = category
|
|
}
|
|
if (compositor) {
|
|
params.compositor = compositor
|
|
}
|
|
if (capability) {
|
|
params.capability = capability
|
|
}
|
|
|
|
sendRequest("plugins.search", params, response => {
|
|
if (response.result) {
|
|
searchResultsReceived(response.result)
|
|
}
|
|
if (callback) {
|
|
callback(response)
|
|
}
|
|
})
|
|
}
|
|
|
|
function install(pluginName, callback) {
|
|
sendRequest("plugins.install", {
|
|
"name": pluginName
|
|
}, response => {
|
|
if (callback) {
|
|
callback(response)
|
|
}
|
|
if (!response.error) {
|
|
listInstalled()
|
|
}
|
|
})
|
|
}
|
|
|
|
function uninstall(pluginName, callback) {
|
|
sendRequest("plugins.uninstall", {
|
|
"name": pluginName
|
|
}, response => {
|
|
if (callback) {
|
|
callback(response)
|
|
}
|
|
if (!response.error) {
|
|
listInstalled()
|
|
}
|
|
})
|
|
}
|
|
|
|
function update(pluginName, callback) {
|
|
sendRequest("plugins.update", {
|
|
"name": pluginName
|
|
}, response => {
|
|
if (callback) {
|
|
callback(response)
|
|
}
|
|
if (!response.error) {
|
|
listInstalled()
|
|
}
|
|
})
|
|
}
|
|
}
|