mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-29 07:52:50 -05:00
common: add Proc.runCommand helper
This commit is contained in:
69
Common/Proc.qml
Normal file
69
Common/Proc.qml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
pragma Singleton
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int defaultDebounceMs: 50
|
||||||
|
property var _procDebouncers: ({}) // id -> { timer, command, callback, waitMs }
|
||||||
|
|
||||||
|
function runCommand(id, command, callback, debounceMs) {
|
||||||
|
const wait = (typeof debounceMs === "number" && debounceMs >= 0) ? debounceMs : defaultDebounceMs
|
||||||
|
|
||||||
|
if (!_procDebouncers[id]) {
|
||||||
|
const t = Qt.createQmlObject('import QtQuick; Timer { repeat: false }', root)
|
||||||
|
t.triggered.connect(function() { _launchProc(id) })
|
||||||
|
_procDebouncers[id] = { timer: t, command: command, callback: callback, waitMs: wait }
|
||||||
|
} else {
|
||||||
|
_procDebouncers[id].command = command
|
||||||
|
_procDebouncers[id].callback = callback
|
||||||
|
_procDebouncers[id].waitMs = wait
|
||||||
|
}
|
||||||
|
|
||||||
|
const entry = _procDebouncers[id]
|
||||||
|
entry.timer.interval = entry.waitMs
|
||||||
|
entry.timer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
function _launchProc(id) {
|
||||||
|
const entry = _procDebouncers[id]
|
||||||
|
if (!entry) return
|
||||||
|
|
||||||
|
const proc = Qt.createQmlObject('import Quickshell.Io; Process { running: false }', root)
|
||||||
|
const out = Qt.createQmlObject('import Quickshell.Io; StdioCollector {}', proc)
|
||||||
|
const err = Qt.createQmlObject('import Quickshell.Io; StdioCollector {}', proc)
|
||||||
|
|
||||||
|
proc.stdout = out
|
||||||
|
proc.stderr = err
|
||||||
|
proc.command = entry.command
|
||||||
|
|
||||||
|
let capturedOut = ""
|
||||||
|
let exitSeen = false
|
||||||
|
let exitCodeValue = -1
|
||||||
|
|
||||||
|
out.streamFinished.connect(function() {
|
||||||
|
capturedOut = out.text || ""
|
||||||
|
maybeComplete()
|
||||||
|
})
|
||||||
|
|
||||||
|
proc.exited.connect(function(code) {
|
||||||
|
exitSeen = true
|
||||||
|
exitCodeValue = code
|
||||||
|
maybeComplete()
|
||||||
|
})
|
||||||
|
|
||||||
|
function maybeComplete() {
|
||||||
|
if (!exitSeen) return
|
||||||
|
if (typeof entry.callback === "function") {
|
||||||
|
try { entry.callback(capturedOut, exitCodeValue) } catch (e) { console.warn("runCommand callback error:", e) }
|
||||||
|
}
|
||||||
|
try { proc.destroy() } catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc.running = true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,33 +59,6 @@ Singleton {
|
|||||||
onTriggered: root.doGenerateNiriLayoutConfig()
|
onTriggered: root.doGenerateNiriLayoutConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
|
||||||
id: outputsProcess
|
|
||||||
command: ["niri", "msg", "-j", "outputs"]
|
|
||||||
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
try {
|
|
||||||
const outputsData = JSON.parse(text)
|
|
||||||
outputs = outputsData
|
|
||||||
console.log("NiriService: Loaded", Object.keys(outputsData).length, "outputs")
|
|
||||||
updateDisplayScales()
|
|
||||||
if (windows.length > 0) {
|
|
||||||
windows = sortWindowsByLayout(windows)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("NiriService: Failed to parse outputs:", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: exitCode => {
|
|
||||||
if (exitCode !== 0) {
|
|
||||||
console.warn("NiriService: Failed to fetch outputs, exit code:", exitCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: validateProcess
|
id: validateProcess
|
||||||
command: ["niri", "validate"]
|
command: ["niri", "validate"]
|
||||||
@@ -168,7 +141,23 @@ Singleton {
|
|||||||
|
|
||||||
function fetchOutputs() {
|
function fetchOutputs() {
|
||||||
if (!CompositorService.isNiri) return
|
if (!CompositorService.isNiri) return
|
||||||
outputsProcess.running = true
|
Proc.runCommand("niri-fetch-outputs", ["niri", "msg", "-j", "outputs"], (output, exitCode) => {
|
||||||
|
if (exitCode !== 0) {
|
||||||
|
console.warn("NiriService: Failed to fetch outputs, exit code:", exitCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const outputsData = JSON.parse(output)
|
||||||
|
outputs = outputsData
|
||||||
|
console.log("NiriService: Loaded", Object.keys(outputsData).length, "outputs")
|
||||||
|
updateDisplayScales()
|
||||||
|
if (windows.length > 0) {
|
||||||
|
windows = sortWindowsByLayout(windows)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("NiriService: Failed to parse outputs:", e)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDisplayScales() {
|
function updateDisplayScales() {
|
||||||
|
|||||||
Reference in New Issue
Block a user