summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/dms/Common/Proc.qml
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-hyprland-theme/theme-data/dms/Common/Proc.qml')
-rw-r--r--raveos-hyprland-theme/theme-data/dms/Common/Proc.qml141
1 files changed, 141 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/dms/Common/Proc.qml b/raveos-hyprland-theme/theme-data/dms/Common/Proc.qml
new file mode 100644
index 0000000..813f938
--- /dev/null
+++ b/raveos-hyprland-theme/theme-data/dms/Common/Proc.qml
@@ -0,0 +1,141 @@
+pragma Singleton
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import Quickshell
+
+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 : 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
+ };
+ } else {
+ _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();
+ }
+
+ function _launchProc(id, isRandomId) {
+ 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);
+
+ 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;
+
+ timeoutTimer.interval = entry.timeoutMs;
+ timeoutTimer.triggered.connect(function () {
+ if (!exitSeen) {
+ timedOut = true;
+ proc.running = false;
+ exitSeen = true;
+ exitCodeValue = 124;
+ maybeComplete();
+ }
+ });
+
+ out.streamFinished.connect(function () {
+ try {
+ capturedOut = out.text || "";
+ } catch (e) {
+ capturedOut = "";
+ }
+ outSeen = true;
+ maybeComplete();
+ });
+
+ err.streamFinished.connect(function () {
+ try {
+ capturedErr = err.text || "";
+ } catch (e) {
+ capturedErr = "";
+ }
+ errSeen = true;
+ maybeComplete();
+ });
+
+ proc.exited.connect(function (code) {
+ timeoutTimer.stop();
+ exitSeen = true;
+ exitCodeValue = code;
+ maybeComplete();
+ });
+
+ function maybeComplete() {
+ 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);
+ } catch (e) {
+ console.warn("runCommand callback error for command:", entry.command, "Error:", e);
+ }
+ }
+ 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];
+ }
+ });
+ }
+ }
+
+ proc.running = true;
+ if (entry.timeoutMs !== noTimeout)
+ timeoutTimer.start();
+ }
+}