summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/DgopService.qml
diff options
context:
space:
mode:
authorAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
committerAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
commit70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch)
treeab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/DgopService.qml
parent5d94c0a7d44a2255b81815a52a7056a94a39842d (diff)
downloadRaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz
RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/DgopService.qml')
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/DgopService.qml778
1 files changed, 778 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/DgopService.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/DgopService.qml
new file mode 100644
index 0000000..e63c5c5
--- /dev/null
+++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/DgopService.qml
@@ -0,0 +1,778 @@
+pragma Singleton
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import Quickshell
+import Quickshell.Io
+import qs.Common
+
+Singleton {
+ id: root
+
+ property int refCount: 0
+ property int updateInterval: refCount > 0 ? 3000 : 30000
+ property bool isUpdating: false
+ property bool dgopAvailable: false
+
+ property var moduleRefCounts: ({})
+ property var enabledModules: []
+ property var gpuPciIds: []
+ property var gpuPciIdRefCounts: ({})
+ property int processLimit: 20
+ property string processSort: "cpu"
+ property bool noCpu: false
+ property int dgopProcessPid: 0
+
+ // Cursor data for accurate CPU calculations
+ property string cpuCursor: ""
+ property string procCursor: ""
+ property int cpuSampleCount: 0
+ property int processSampleCount: 0
+
+ property real cpuUsage: 0
+ property real cpuFrequency: 0
+ property real cpuTemperature: 0
+ property int cpuCores: 1
+ property string cpuModel: ""
+ property var perCoreCpuUsage: []
+
+ property real memoryUsage: 0
+ property real totalMemoryMB: 0
+ property real usedMemoryMB: 0
+ property real freeMemoryMB: 0
+ property real availableMemoryMB: 0
+ property int totalMemoryKB: 0
+ property int usedMemoryKB: 0
+ property int totalSwapKB: 0
+ property int usedSwapKB: 0
+
+ property real networkRxRate: 0
+ property real networkTxRate: 0
+ property var lastNetworkStats: null
+ property var networkInterfaces: []
+
+ property real diskReadRate: 0
+ property real diskWriteRate: 0
+ property var lastDiskStats: null
+ property var diskMounts: []
+ property var diskDevices: []
+
+ property var processes: []
+ property var allProcesses: []
+ property string currentSort: "cpu"
+ property bool sortAscending: false
+ property var availableGpus: []
+
+ property string kernelVersion: ""
+ property string distribution: ""
+ property string hostname: ""
+ property string architecture: ""
+ property string loadAverage: ""
+ property int processCount: 0
+ property int threadCount: 0
+ property string bootTime: ""
+ property string motherboard: ""
+ property string biosVersion: ""
+ property string uptime: ""
+ property string shortUptime: ""
+
+ property int historySize: 60
+ property var cpuHistory: []
+ property var memoryHistory: []
+ property var networkHistory: ({
+ "rx": [],
+ "tx": []
+ })
+ property var diskHistory: ({
+ "read": [],
+ "write": []
+ })
+
+ function addRef(modules = null) {
+ refCount++;
+ let modulesChanged = false;
+
+ if (modules) {
+ const modulesToAdd = Array.isArray(modules) ? modules : [modules];
+ for (const module of modulesToAdd) {
+ const currentCount = moduleRefCounts[module] || 0;
+ moduleRefCounts[module] = currentCount + 1;
+
+ // Add to enabled modules if not already there
+ if (enabledModules.indexOf(module) === -1) {
+ enabledModules.push(module);
+ modulesChanged = true;
+ }
+ }
+ }
+
+ if (modulesChanged || refCount === 1) {
+ enabledModules = enabledModules.slice(); // Force property change
+ moduleRefCounts = Object.assign({}, moduleRefCounts); // Force property change
+ updateAllStats();
+ } else if (gpuPciIds.length > 0 && refCount > 0) {
+ // If we have GPU PCI IDs and active modules, make sure to update
+ // This handles the case where PCI IDs were loaded after modules were added
+ updateAllStats();
+ }
+ }
+
+ function removeRef(modules = null) {
+ refCount = Math.max(0, refCount - 1);
+ let modulesChanged = false;
+
+ if (modules) {
+ const modulesToRemove = Array.isArray(modules) ? modules : [modules];
+ for (const module of modulesToRemove) {
+ const currentCount = moduleRefCounts[module] || 0;
+ if (currentCount > 1) {
+ moduleRefCounts[module] = currentCount - 1;
+ } else if (currentCount === 1) {
+ delete moduleRefCounts[module];
+ const index = enabledModules.indexOf(module);
+ if (index > -1) {
+ enabledModules.splice(index, 1);
+ modulesChanged = true;
+ }
+ }
+ }
+ }
+
+ if (modulesChanged) {
+ enabledModules = enabledModules.slice(); // Force property change
+ moduleRefCounts = Object.assign({}, moduleRefCounts); // Force property change
+
+ // Clear cursor data when CPU or process modules are no longer active
+ if (!enabledModules.includes("cpu")) {
+ cpuCursor = "";
+ cpuSampleCount = 0;
+ }
+ if (!enabledModules.includes("processes")) {
+ procCursor = "";
+ processSampleCount = 0;
+ }
+ }
+ }
+
+ function setGpuPciIds(pciIds) {
+ gpuPciIds = Array.isArray(pciIds) ? pciIds : [];
+ }
+
+ function addGpuPciId(pciId) {
+ const currentCount = gpuPciIdRefCounts[pciId] || 0;
+ gpuPciIdRefCounts[pciId] = currentCount + 1;
+
+ // Add to gpuPciIds array if not already there
+ if (!gpuPciIds.includes(pciId)) {
+ gpuPciIds = gpuPciIds.concat([pciId]);
+ }
+
+ gpuPciIdRefCounts = Object.assign({}, gpuPciIdRefCounts);
+ }
+
+ function removeGpuPciId(pciId) {
+ const currentCount = gpuPciIdRefCounts[pciId] || 0;
+ if (currentCount > 1) {
+ gpuPciIdRefCounts[pciId] = currentCount - 1;
+ } else if (currentCount === 1) {
+ // Remove completely when count reaches 0
+ delete gpuPciIdRefCounts[pciId];
+ const index = gpuPciIds.indexOf(pciId);
+ if (index > -1) {
+ gpuPciIds = gpuPciIds.slice();
+ gpuPciIds.splice(index, 1);
+ }
+
+ // Clear temperature data for this GPU when no longer monitored
+ if (availableGpus && availableGpus.length > 0) {
+ const updatedGpus = availableGpus.slice();
+ for (var i = 0; i < updatedGpus.length; i++) {
+ if (updatedGpus[i].pciId === pciId) {
+ updatedGpus[i] = Object.assign({}, updatedGpus[i], {
+ "temperature": 0
+ });
+ }
+ }
+ availableGpus = updatedGpus;
+ }
+ }
+
+ // Force property change notification
+ gpuPciIdRefCounts = Object.assign({}, gpuPciIdRefCounts);
+ }
+
+ function setProcessOptions(limit = 20, sort = "cpu", disableCpu = false) {
+ processLimit = limit;
+ processSort = sort;
+ noCpu = disableCpu;
+ }
+
+ function updateAllStats() {
+ if (dgopAvailable && refCount > 0 && enabledModules.length > 0) {
+ isUpdating = true;
+ dgopProcess.running = true;
+ } else {
+ isUpdating = false;
+ }
+ }
+
+ function initializeGpuMetadata() {
+ if (!dgopAvailable)
+ return;
+ gpuInitProcess.running = true;
+ }
+
+ function initializeSystemMetadata() {
+ if (!dgopAvailable)
+ return;
+ systemInitProcess.running = true;
+ }
+
+ function buildDgopCommand() {
+ const cmd = ["dgop", "meta", "--json"];
+
+ if (enabledModules.length === 0) {
+ // Don't run if no modules are needed
+ return [];
+ }
+
+ // Replace 'gpu' with 'gpu-temp' when we have PCI IDs to monitor
+ const finalModules = [];
+ for (const module of enabledModules) {
+ if (module === "gpu" && gpuPciIds.length > 0) {
+ finalModules.push("gpu-temp");
+ } else if (module !== "gpu") {
+ finalModules.push(module);
+ }
+ }
+
+ // Add gpu-temp module automatically when we have PCI IDs to monitor
+ if (gpuPciIds.length > 0 && finalModules.indexOf("gpu-temp") === -1) {
+ finalModules.push("gpu-temp");
+ }
+
+ if (enabledModules.indexOf("all") !== -1) {
+ cmd.push("--modules", "all");
+ } else if (finalModules.length > 0) {
+ const moduleList = finalModules.join(",");
+ cmd.push("--modules", moduleList);
+ } else {
+ return [];
+ }
+
+ // Add cursor data if available for accurate CPU percentages
+ if ((enabledModules.includes("cpu") || enabledModules.includes("all")) && cpuCursor) {
+ cmd.push("--cpu-cursor", cpuCursor);
+ }
+ if ((enabledModules.includes("processes") || enabledModules.includes("all")) && procCursor) {
+ cmd.push("--proc-cursor", procCursor);
+ }
+
+ if (gpuPciIds.length > 0) {
+ cmd.push("--gpu-pci-ids", gpuPciIds.join(","));
+ }
+
+ if (enabledModules.indexOf("processes") !== -1 || enabledModules.indexOf("all") !== -1) {
+ cmd.push("--limit", "100"); // Get more data for client sorting
+ cmd.push("--sort", "cpu"); // Always get CPU sorted data
+ if (noCpu) {
+ cmd.push("--no-cpu");
+ }
+ }
+
+ return cmd;
+ }
+
+ function parseData(data) {
+ if (data.cpu) {
+ const cpu = data.cpu;
+ cpuSampleCount++;
+
+ cpuUsage = Math.round((cpu.usage || 0) * 10) / 10;
+ cpuFrequency = Math.round(cpu.frequency || 0);
+ cpuTemperature = Math.round(cpu.temperature || 0);
+ cpuCores = cpu.count || 1;
+ cpuModel = cpu.model || "";
+ perCoreCpuUsage = cpu.coreUsage || [];
+ addToHistory(cpuHistory, cpuUsage);
+
+ if (cpu.cursor) {
+ cpuCursor = cpu.cursor;
+ }
+ }
+
+ if (data.memory) {
+ const mem = data.memory;
+ const totalKB = mem.total || 0;
+ const availableKB = mem.available || 0;
+ const freeKB = mem.free || 0;
+ const usedKB = mem.used !== undefined ? mem.used : (totalKB - availableKB);
+
+ totalMemoryMB = Math.round(totalKB / 1024);
+ availableMemoryMB = Math.round(availableKB / 1024);
+ freeMemoryMB = Math.round(freeKB / 1024);
+ usedMemoryMB = Math.round(usedKB / 1024);
+ const rawMemUsage = mem.usedPercent !== undefined ? mem.usedPercent : (totalKB > 0 ? ((totalKB - availableKB) / totalKB) * 100 : 0);
+ memoryUsage = Math.round(rawMemUsage * 10) / 10;
+
+ totalMemoryKB = totalKB;
+ usedMemoryKB = usedKB;
+ totalSwapKB = mem.swaptotal || 0;
+ usedSwapKB = (mem.swaptotal || 0) - (mem.swapfree || 0);
+
+ addToHistory(memoryHistory, memoryUsage);
+ }
+
+ if (data.network && Array.isArray(data.network)) {
+ networkInterfaces = data.network;
+
+ let totalRx = 0;
+ let totalTx = 0;
+ for (const iface of data.network) {
+ totalRx += iface.rx || 0;
+ totalTx += iface.tx || 0;
+ }
+
+ if (lastNetworkStats) {
+ const timeDiff = updateInterval / 1000;
+ const rxDiff = totalRx - lastNetworkStats.rx;
+ const txDiff = totalTx - lastNetworkStats.tx;
+ networkRxRate = Math.max(0, rxDiff / timeDiff);
+ networkTxRate = Math.max(0, txDiff / timeDiff);
+ addToHistory(networkHistory.rx, networkRxRate / 1024);
+ addToHistory(networkHistory.tx, networkTxRate / 1024);
+ }
+ lastNetworkStats = {
+ "rx": totalRx,
+ "tx": totalTx
+ };
+ }
+
+ if (data.disk && Array.isArray(data.disk)) {
+ diskDevices = data.disk;
+
+ let totalRead = 0;
+ let totalWrite = 0;
+ for (const disk of data.disk) {
+ totalRead += (disk.read || 0) * 512;
+ totalWrite += (disk.write || 0) * 512;
+ }
+
+ if (lastDiskStats) {
+ const timeDiff = updateInterval / 1000;
+ const readDiff = totalRead - lastDiskStats.read;
+ const writeDiff = totalWrite - lastDiskStats.write;
+ diskReadRate = Math.max(0, readDiff / timeDiff);
+ diskWriteRate = Math.max(0, writeDiff / timeDiff);
+ addToHistory(diskHistory.read, diskReadRate / (1024 * 1024));
+ addToHistory(diskHistory.write, diskWriteRate / (1024 * 1024));
+ }
+ lastDiskStats = {
+ "read": totalRead,
+ "write": totalWrite
+ };
+ }
+
+ if (data.diskmounts) {
+ diskMounts = data.diskmounts || [];
+ }
+
+ if (data.processes && Array.isArray(data.processes)) {
+ const newProcesses = [];
+ processSampleCount++;
+ const ourPid = dgopProcessPid;
+
+ for (const proc of data.processes) {
+ if (ourPid > 0 && proc.pid === ourPid)
+ continue;
+
+ const cpuUsage = processSampleCount >= 2 ? (proc.cpu || 0) : 0;
+
+ newProcesses.push({
+ "pid": proc.pid || 0,
+ "ppid": proc.ppid || 0,
+ "cpu": cpuUsage,
+ "memoryPercent": proc.memoryPercent || proc.pssPercent || 0,
+ "memoryKB": proc.memoryKB || proc.pssKB || 0,
+ "command": proc.command || "",
+ "fullCommand": proc.fullCommand || "",
+ "username": proc.username || "",
+ "displayName": (proc.command && proc.command.length > 15) ? proc.command.substring(0, 15) + "..." : (proc.command || "")
+ });
+ }
+ allProcesses = newProcesses;
+ applySorting();
+
+ if (data.cursor) {
+ procCursor = data.cursor;
+ }
+ }
+
+ const gpuData = (data.gpu && data.gpu.gpus) || data.gpus;
+ if (gpuData && Array.isArray(gpuData)) {
+ // Check if this is temperature update data (has PCI IDs being monitored)
+ if (gpuPciIds.length > 0 && availableGpus && availableGpus.length > 0) {
+ // This is temperature data - merge with existing GPU metadata
+ const updatedGpus = availableGpus.slice();
+ for (var i = 0; i < updatedGpus.length; i++) {
+ const existingGpu = updatedGpus[i];
+ const tempGpu = gpuData.find(g => g.pciId === existingGpu.pciId);
+ // Only update temperature if this GPU's PCI ID is being monitored
+ if (tempGpu && gpuPciIds.includes(existingGpu.pciId)) {
+ updatedGpus[i] = Object.assign({}, existingGpu, {
+ "temperature": tempGpu.temperature || 0
+ });
+ }
+ }
+ availableGpus = updatedGpus;
+ } else {
+ // This is initial GPU metadata - set the full list
+ const gpuList = [];
+ for (const gpu of gpuData) {
+ let displayName = gpu.displayName || gpu.name || "Unknown GPU";
+ let fullName = gpu.fullName || gpu.name || "Unknown GPU";
+
+ gpuList.push({
+ "driver": gpu.driver || "",
+ "vendor": gpu.vendor || "",
+ "displayName": displayName,
+ "fullName": fullName,
+ "pciId": gpu.pciId || "",
+ "temperature": gpu.temperature || 0
+ });
+ }
+ availableGpus = gpuList;
+ }
+ }
+
+ if (data.system) {
+ const sys = data.system;
+ loadAverage = sys.loadavg || "";
+ processCount = sys.processes || 0;
+ threadCount = sys.threads || 0;
+ bootTime = sys.boottime || "";
+ updateUptime();
+ }
+
+ const hwData = data.hardware || (data.hostname || data.kernel || data.distro || data.arch) ? data : null;
+ if (hwData) {
+ hostname = hwData.hostname || "";
+ kernelVersion = hwData.kernel || "";
+ distribution = hwData.distro || "";
+ architecture = hwData.arch || "";
+ motherboard = (hwData.bios && hwData.bios.motherboard) || "";
+ biosVersion = (hwData.bios && hwData.bios.version) || "";
+ }
+
+ isUpdating = false;
+ }
+
+ function addToHistory(array, value) {
+ array.push(value);
+ if (array.length > historySize) {
+ array.shift();
+ }
+ }
+
+ function getProcessIcon(command) {
+ const cmd = command.toLowerCase();
+ if (cmd.includes("firefox") || cmd.includes("chrome") || cmd.includes("browser") || cmd.includes("chromium")) {
+ return "web";
+ }
+ if (cmd.includes("code") || cmd.includes("editor") || cmd.includes("vim")) {
+ return "code";
+ }
+ if (cmd.includes("terminal") || cmd.includes("bash") || cmd.includes("zsh")) {
+ return "terminal";
+ }
+ if (cmd.includes("music") || cmd.includes("audio") || cmd.includes("spotify")) {
+ return "music_note";
+ }
+ if (cmd.includes("video") || cmd.includes("vlc") || cmd.includes("mpv")) {
+ return "play_circle";
+ }
+ if (cmd.includes("systemd") || cmd.includes("elogind") || cmd.includes("kernel") || cmd.includes("kthread") || cmd.includes("kworker")) {
+ return "settings";
+ }
+ return "memory";
+ }
+
+ function formatCpuUsage(cpu) {
+ return (cpu || 0).toFixed(1) + "%";
+ }
+
+ function formatMemoryUsage(memoryKB) {
+ const mem = memoryKB || 0;
+ if (mem < 1024) {
+ return mem.toFixed(0) + " KB";
+ } else if (mem < 1024 * 1024) {
+ return (mem / 1024).toFixed(1) + " MB";
+ } else {
+ return (mem / (1024 * 1024)).toFixed(1) + " GB";
+ }
+ }
+
+ function formatSystemMemory(memoryKB) {
+ const mem = memoryKB || 0;
+ if (mem === 0) {
+ return "--";
+ }
+ if (mem < 1024 * 1024) {
+ return (mem / 1024).toFixed(0) + " MB";
+ } else {
+ return (mem / (1024 * 1024)).toFixed(1) + " GB";
+ }
+ }
+
+ function killProcess(pid) {
+ if (pid > 0) {
+ Quickshell.execDetached("kill", [pid.toString()]);
+ }
+ }
+
+ function updateUptime() {
+ if (!bootTime) {
+ uptime = "";
+ shortUptime = "";
+ return;
+ }
+
+ const bootDate = new Date(bootTime.replace(" ", "T"));
+ if (isNaN(bootDate.getTime())) {
+ uptime = "";
+ shortUptime = "";
+ return;
+ }
+
+ const now = new Date();
+ const seconds = Math.floor((now - bootDate) / 1000);
+ const days = Math.floor(seconds / 86400);
+ const hours = Math.floor((seconds % 86400) / 3600);
+ const minutes = Math.floor((seconds % 3600) / 60);
+
+ const parts = [];
+ if (days > 0)
+ parts.push(`${days} day${days === 1 ? "" : "s"}`);
+ if (hours > 0)
+ parts.push(`${hours} hour${hours === 1 ? "" : "s"}`);
+ if (minutes > 0)
+ parts.push(`${minutes} minute${minutes === 1 ? "" : "s"}`);
+
+ uptime = parts.length > 0 ? `up ${parts.join(", ")}` : `up ${seconds} seconds`;
+
+ var shortStr = "up";
+ if (days > 0)
+ shortStr += ` ${days}d`;
+ if (hours > 0)
+ shortStr += ` ${hours}h`;
+ if (minutes > 0)
+ shortStr += ` ${minutes}m`;
+ shortUptime = shortStr;
+ }
+
+ function setSortBy(newSortBy) {
+ if (newSortBy !== currentSort) {
+ currentSort = newSortBy;
+ sortAscending = false;
+ applySorting();
+ }
+ }
+
+ function toggleSort(column) {
+ if (column === currentSort) {
+ sortAscending = !sortAscending;
+ } else {
+ currentSort = column;
+ sortAscending = false;
+ }
+ applySorting();
+ }
+
+ function applySorting() {
+ if (!allProcesses || allProcesses.length === 0)
+ return;
+
+ const asc = sortAscending;
+ const sorted = allProcesses.slice();
+ sorted.sort((a, b) => {
+ let valueA, valueB, result;
+
+ switch (currentSort) {
+ case "cpu":
+ valueA = a.cpu || 0;
+ valueB = b.cpu || 0;
+ result = valueB - valueA;
+ break;
+ case "memory":
+ valueA = a.memoryKB || 0;
+ valueB = b.memoryKB || 0;
+ result = valueB - valueA;
+ break;
+ case "name":
+ valueA = (a.command || "").toLowerCase();
+ valueB = (b.command || "").toLowerCase();
+ result = valueA.localeCompare(valueB);
+ break;
+ case "pid":
+ valueA = a.pid || 0;
+ valueB = b.pid || 0;
+ result = valueA - valueB;
+ break;
+ default:
+ return 0;
+ }
+ return asc ? -result : result;
+ });
+
+ processes = sorted.slice(0, processLimit);
+ }
+
+ Timer {
+ id: updateTimer
+ interval: root.updateInterval
+ running: root.dgopAvailable && root.refCount > 0 && root.enabledModules.length > 0
+ repeat: true
+ triggeredOnStart: true
+ onTriggered: root.updateAllStats()
+ }
+
+ Process {
+ id: dgopProcess
+ command: root.buildDgopCommand()
+ running: false
+ onStarted: dgopProcessPid = processId ?? 0
+ onExited: exitCode => {
+ if (exitCode !== 0) {
+ console.warn("Dgop process failed with exit code:", exitCode);
+ isUpdating = false;
+ }
+ }
+ stdout: StdioCollector {
+ onStreamFinished: {
+ if (text.trim()) {
+ try {
+ const data = JSON.parse(text.trim());
+ parseData(data);
+ } catch (e) {
+ console.warn("Failed to parse dgop JSON:", e);
+ console.warn("Raw text was:", text.substring(0, 200));
+ isUpdating = false;
+ }
+ }
+ }
+ }
+ }
+
+ Process {
+ id: gpuInitProcess
+ command: ["dgop", "gpu", "--json"]
+ running: false
+ onExited: exitCode => {
+ if (exitCode !== 0) {
+ console.warn("GPU init process failed with exit code:", exitCode);
+ }
+ }
+ stdout: StdioCollector {
+ onStreamFinished: {
+ if (text.trim()) {
+ try {
+ const data = JSON.parse(text.trim());
+ parseData(data);
+ } catch (e) {
+ console.warn("Failed to parse GPU init JSON:", e);
+ }
+ }
+ }
+ }
+ }
+
+ Process {
+ id: systemInitProcess
+ command: ["dgop", "hardware", "--json"]
+ running: false
+ onExited: exitCode => {
+ if (exitCode !== 0) {
+ console.warn("System init process failed with exit code:", exitCode);
+ }
+ }
+ stdout: StdioCollector {
+ onStreamFinished: {
+ if (text.trim()) {
+ try {
+ const data = JSON.parse(text.trim());
+ parseData(data);
+ } catch (e) {
+ console.warn("Failed to parse system init JSON:", e);
+ }
+ }
+ }
+ }
+ }
+
+ Process {
+ id: dgopCheckProcess
+ command: ["which", "dgop"]
+ running: false
+ onExited: exitCode => {
+ dgopAvailable = (exitCode === 0);
+ if (dgopAvailable) {
+ initializeGpuMetadata();
+ initializeSystemMetadata();
+ if (SessionData.enabledGpuPciIds && SessionData.enabledGpuPciIds.length > 0) {
+ for (const pciId of SessionData.enabledGpuPciIds) {
+ addGpuPciId(pciId);
+ }
+ if (refCount > 0 && enabledModules.length > 0) {
+ updateAllStats();
+ }
+ }
+ } else {
+ console.warn("dgop is not installed or not in PATH");
+ }
+ }
+ }
+
+ Process {
+ id: osReleaseProcess
+ command: ["cat", "/etc/os-release"]
+ running: false
+ onExited: exitCode => {
+ if (exitCode !== 0) {
+ console.warn("Failed to read /etc/os-release");
+ }
+ }
+ stdout: StdioCollector {
+ onStreamFinished: {
+ if (text.trim()) {
+ try {
+ const lines = text.trim().split('\n');
+ let prettyName = "";
+ let name = "";
+
+ for (const line of lines) {
+ const trimmedLine = line.trim();
+ if (trimmedLine.startsWith('PRETTY_NAME=')) {
+ prettyName = trimmedLine.substring(12).replace(/^["']|["']$/g, '');
+ } else if (trimmedLine.startsWith('NAME=')) {
+ name = trimmedLine.substring(5).replace(/^["']|["']$/g, '');
+ }
+ }
+
+ // Prefer PRETTY_NAME, fallback to NAME
+ const distroName = prettyName || name || "Linux";
+ distribution = distroName;
+ console.info("Detected distribution:", distroName);
+ } catch (e) {
+ console.warn("Failed to parse /etc/os-release:", e);
+ distribution = "Linux";
+ }
+ }
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ dgopCheckProcess.running = true;
+ osReleaseProcess.running = true;
+ }
+}