1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

proc: ability to run command with noTimeout

This commit is contained in:
bbedward
2025-12-04 16:09:38 -05:00
parent 4291cfe82f
commit 63d121b796
2 changed files with 90 additions and 73 deletions

View File

@@ -3,122 +3,139 @@ pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io
Singleton {
id: root
readonly property int noTimeout: -1
property int defaultDebounceMs: 50
property int defaultTimeoutMs: 10000
property var _procDebouncers: ({})
function runCommand(id, command, callback, debounceMs, timeoutMs) {
const wait = (typeof debounceMs === "number" && debounceMs >= 0) ? debounceMs : defaultDebounceMs
const timeout = (typeof timeoutMs === "number" && timeoutMs > 0) ? timeoutMs : defaultTimeoutMs
let procId = id ? id : Math.random()
const isRandomId = !id
const wait = (typeof debounceMs === "number" && debounceMs >= 0) ? debounceMs : defaultDebounceMs;
const timeout = (typeof timeoutMs === "number") ? timeoutMs : defaultTimeoutMs;
let procId = id ? id : Math.random();
const isRandomId = !id;
if (!_procDebouncers[procId]) {
const t = Qt.createQmlObject('import QtQuick; Timer { repeat: false }', root)
t.triggered.connect(function() { _launchProc(procId, isRandomId) })
_procDebouncers[procId] = { timer: t, command: command, callback: callback, waitMs: wait, timeoutMs: timeout, isRandomId: isRandomId }
const t = Qt.createQmlObject('import QtQuick; Timer { repeat: false }', root);
t.triggered.connect(function () {
_launchProc(procId, isRandomId);
});
_procDebouncers[procId] = {
timer: t,
command: command,
callback: callback,
waitMs: wait,
timeoutMs: timeout,
isRandomId: isRandomId
};
} else {
_procDebouncers[procId].command = command
_procDebouncers[procId].callback = callback
_procDebouncers[procId].waitMs = wait
_procDebouncers[procId].timeoutMs = timeout
_procDebouncers[procId].command = command;
_procDebouncers[procId].callback = callback;
_procDebouncers[procId].waitMs = wait;
_procDebouncers[procId].timeoutMs = timeout;
}
const entry = _procDebouncers[procId]
entry.timer.interval = entry.waitMs
entry.timer.restart()
const entry = _procDebouncers[procId];
entry.timer.interval = entry.waitMs;
entry.timer.restart();
}
function _launchProc(id, isRandomId) {
const entry = _procDebouncers[id]
if (!entry) return
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);
const timeoutTimer = Qt.createQmlObject('import QtQuick; Timer { repeat: false }', root);
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)
const timeoutTimer = Qt.createQmlObject('import QtQuick; Timer { repeat: false }', root)
proc.stdout = out;
proc.stderr = err;
proc.command = entry.command;
proc.stdout = out
proc.stderr = err
proc.command = entry.command
let capturedOut = "";
let capturedErr = "";
let exitSeen = false;
let exitCodeValue = -1;
let outSeen = false;
let errSeen = false;
let timedOut = false;
let capturedOut = ""
let capturedErr = ""
let exitSeen = false
let exitCodeValue = -1
let outSeen = false
let errSeen = false
let timedOut = false
timeoutTimer.interval = entry.timeoutMs
timeoutTimer.interval = entry.timeoutMs;
timeoutTimer.triggered.connect(function () {
if (!exitSeen) {
timedOut = true
proc.running = false
exitSeen = true
exitCodeValue = 124
maybeComplete()
timedOut = true;
proc.running = false;
exitSeen = true;
exitCodeValue = 124;
maybeComplete();
}
})
});
out.streamFinished.connect(function () {
try {
capturedOut = out.text || ""
capturedOut = out.text || "";
} catch (e) {
capturedOut = ""
capturedOut = "";
}
outSeen = true
maybeComplete()
})
outSeen = true;
maybeComplete();
});
err.streamFinished.connect(function () {
try {
capturedErr = err.text || ""
capturedErr = err.text || "";
} catch (e) {
capturedErr = ""
capturedErr = "";
}
errSeen = true
maybeComplete()
})
errSeen = true;
maybeComplete();
});
proc.exited.connect(function (code) {
timeoutTimer.stop()
exitSeen = true
exitCodeValue = code
maybeComplete()
})
timeoutTimer.stop();
exitSeen = true;
exitCodeValue = code;
maybeComplete();
});
function maybeComplete() {
if (!exitSeen || !outSeen || !errSeen) return
timeoutTimer.stop()
if (!exitSeen || !outSeen || !errSeen)
return;
timeoutTimer.stop();
if (entry && entry.callback && typeof entry.callback === "function") {
try {
const safeOutput = capturedOut !== null && capturedOut !== undefined ? capturedOut : ""
const safeExitCode = exitCodeValue !== null && exitCodeValue !== undefined ? exitCodeValue : -1
entry.callback(safeOutput, safeExitCode)
const safeOutput = capturedOut !== null && capturedOut !== undefined ? capturedOut : "";
const safeExitCode = exitCodeValue !== null && exitCodeValue !== undefined ? exitCodeValue : -1;
entry.callback(safeOutput, safeExitCode);
} catch (e) {
console.warn("runCommand callback error for command:", entry.command, "Error:", e)
console.warn("runCommand callback error for command:", entry.command, "Error:", e);
}
}
try { proc.destroy() } catch (_) {}
try { timeoutTimer.destroy() } catch (_) {}
try {
proc.destroy();
} catch (_) {}
try {
timeoutTimer.destroy();
} catch (_) {}
if (isRandomId || entry.isRandomId) {
Qt.callLater(function () {
if (_procDebouncers[id]) {
try { _procDebouncers[id].timer.destroy() } catch (_) {}
delete _procDebouncers[id]
try {
_procDebouncers[id].timer.destroy();
} catch (_) {}
delete _procDebouncers[id];
}
})
});
}
}
proc.running = true
timeoutTimer.start()
proc.running = true;
if (entry.timeoutMs !== noTimeout)
timeoutTimer.start();
}
}

View File

@@ -110,7 +110,7 @@ DankModal {
console.warn("Failed to parse dms color pick JSON:", e);
root.show();
}
});
}, 0, Proc.noTimeout);
}
modalWidth: 680