Skip to content

Commit 5ca6d70

Browse files
committed
fix: improve monitor data and simplify install flow
1 parent fbd363f commit 5ca6d70

7 files changed

Lines changed: 260 additions & 147 deletions

File tree

src/backend/monitor/gpumonitor.cpp

Lines changed: 157 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "gpumonitor.h"
22
#include "system/commandrunner.h"
33

4+
#include <QDir>
5+
#include <QFile>
46
#include <QRegularExpression>
57
#include <algorithm>
68

@@ -37,6 +39,119 @@ bool parseMetricInt(const QString &field, int *value) {
3739
return true;
3840
}
3941

42+
QString drmRootPath() {
43+
const QString overridePath =
44+
qEnvironmentVariable("RO_CONTROL_DRM_ROOT").trimmed();
45+
return overridePath.isEmpty() ? QStringLiteral("/sys/class/drm")
46+
: overridePath;
47+
}
48+
49+
QString readFileText(const QString &path) {
50+
QFile file(path);
51+
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
52+
return {};
53+
}
54+
55+
return QString::fromUtf8(file.readAll()).trimmed();
56+
}
57+
58+
bool readIntegerFile(const QString &path, qint64 *value) {
59+
if (value == nullptr) {
60+
return false;
61+
}
62+
63+
bool ok = false;
64+
const qint64 parsedValue = readFileText(path).toLongLong(&ok);
65+
if (!ok) {
66+
return false;
67+
}
68+
69+
*value = parsedValue;
70+
return true;
71+
}
72+
73+
bool readFirstTemperatureFromHwmon(const QString &basePath, int *value) {
74+
const QFileInfoList hwmonEntries =
75+
QDir(basePath).entryInfoList({QStringLiteral("hwmon*")},
76+
QDir::Dirs | QDir::NoDotAndDotDot,
77+
QDir::Name);
78+
for (const QFileInfo &entry : hwmonEntries) {
79+
const QFileInfoList inputs = QDir(entry.absoluteFilePath())
80+
.entryInfoList({QStringLiteral("temp*_input")},
81+
QDir::Files, QDir::Name);
82+
for (const QFileInfo &input : inputs) {
83+
qint64 milliC = 0;
84+
if (readIntegerFile(input.absoluteFilePath(), &milliC) && milliC > 0) {
85+
*value = static_cast<int>(milliC / 1000);
86+
return true;
87+
}
88+
}
89+
}
90+
91+
return false;
92+
}
93+
94+
bool readGenericLinuxGpuMetrics(int *temperatureC, int *utilizationPercent,
95+
int *memoryUsedMiB, int *memoryTotalMiB) {
96+
const QFileInfoList cardEntries =
97+
QDir(drmRootPath()).entryInfoList({QStringLiteral("card*")},
98+
QDir::Dirs | QDir::NoDotAndDotDot,
99+
QDir::Name);
100+
101+
bool anyMetric = false;
102+
for (const QFileInfo &cardEntry : cardEntries) {
103+
const QString devicePath =
104+
cardEntry.absoluteFilePath() + QStringLiteral("/device");
105+
if (!QFile::exists(devicePath)) {
106+
continue;
107+
}
108+
109+
int tempValue = 0;
110+
if (temperatureC != nullptr &&
111+
readFirstTemperatureFromHwmon(devicePath, &tempValue)) {
112+
*temperatureC = tempValue;
113+
anyMetric = true;
114+
}
115+
116+
qint64 busyPercent = 0;
117+
if (utilizationPercent != nullptr &&
118+
readIntegerFile(devicePath + QStringLiteral("/gpu_busy_percent"),
119+
&busyPercent)) {
120+
*utilizationPercent =
121+
std::clamp(static_cast<int>(busyPercent), 0, 100);
122+
anyMetric = true;
123+
}
124+
125+
qint64 usedBytes = 0;
126+
qint64 totalBytes = 0;
127+
const bool usedOk =
128+
readIntegerFile(devicePath + QStringLiteral("/mem_info_vram_used"),
129+
&usedBytes);
130+
const bool totalOk =
131+
readIntegerFile(devicePath + QStringLiteral("/mem_info_vram_total"),
132+
&totalBytes);
133+
if (usedOk && totalOk && totalBytes > 0) {
134+
if (memoryUsedMiB != nullptr) {
135+
*memoryUsedMiB =
136+
std::max(0, static_cast<int>(static_cast<qint64>(usedBytes) /
137+
(1024 * 1024)));
138+
}
139+
if (memoryTotalMiB != nullptr) {
140+
*memoryTotalMiB =
141+
std::max(0, static_cast<int>(static_cast<qint64>(totalBytes) /
142+
(1024 * 1024)));
143+
}
144+
anyMetric = true;
145+
}
146+
147+
if (anyMetric) {
148+
return true;
149+
}
150+
}
151+
152+
return false;
153+
}
154+
40155
} // namespace
41156

42157
GpuMonitor::GpuMonitor(QObject *parent) : QObject(parent) {
@@ -80,8 +195,48 @@ void GpuMonitor::refresh() {
80195
options);
81196

82197
if (!result.success()) {
83-
setAvailable(false);
84-
clearMetrics();
198+
int nextTemp = 0;
199+
int nextUtil = 0;
200+
int nextUsed = 0;
201+
int nextTotal = 0;
202+
203+
if (!readGenericLinuxGpuMetrics(&nextTemp, &nextUtil, &nextUsed,
204+
&nextTotal)) {
205+
setAvailable(false);
206+
clearMetrics();
207+
return;
208+
}
209+
210+
if (m_temperatureC != nextTemp) {
211+
m_temperatureC = nextTemp;
212+
emit temperatureCChanged();
213+
}
214+
if (m_utilizationPercent != nextUtil) {
215+
m_utilizationPercent = nextUtil;
216+
emit utilizationPercentChanged();
217+
}
218+
if (m_memoryUsedMiB != nextUsed) {
219+
m_memoryUsedMiB = nextUsed;
220+
emit memoryUsedMiBChanged();
221+
}
222+
if (m_memoryTotalMiB != nextTotal) {
223+
m_memoryTotalMiB = nextTotal;
224+
emit memoryTotalMiBChanged();
225+
}
226+
227+
const int usagePercent =
228+
nextTotal > 0
229+
? std::clamp(static_cast<int>((static_cast<double>(nextUsed) /
230+
static_cast<double>(nextTotal)) *
231+
100.0),
232+
0, 100)
233+
: 0;
234+
if (m_memoryUsagePercent != usagePercent) {
235+
m_memoryUsagePercent = usagePercent;
236+
emit memoryUsagePercentChanged();
237+
}
238+
239+
setAvailable(true);
85240
return;
86241
}
87242

src/backend/monitor/rammonitor.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,6 @@ void RamMonitor::refresh() {
191191
memAvailableKiB = memFreeKiB + buffersKiB + cachedKiB + reclaimable - shmem;
192192
}
193193

194-
// TR: Tutarsiz veri geldiyse metrikleri sifirla ve "unavailable" olarak isle.
195-
// EN: If metrics are inconsistent, clear values and mark monitor unavailable.
196-
if (memTotalKiB <= 0 || memAvailableKiB < 0 ||
197-
memAvailableKiB > memTotalKiB) {
198-
setAvailable(false);
199-
clearMetrics();
200-
return;
201-
}
202-
203194
RamSnapshot snapshot = buildSnapshot(memTotalKiB, memAvailableKiB);
204195
if (!snapshot.valid) {
205196
snapshot = readSnapshotFromFree();

src/backend/system/systeminfoprovider.cpp

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "commandrunner.h"
44

55
#include <QFile>
6+
#include <QStringList>
67
#include <QRegularExpression>
78
#include <QSysInfo>
89
#include <QTextStream>
@@ -13,6 +14,21 @@
1314

1415
namespace {
1516

17+
QString simplifiedDesktopName(const QString &desktop) {
18+
const QString trimmed = desktop.trimmed();
19+
if (trimmed.compare(QStringLiteral("KDE"), Qt::CaseInsensitive) == 0 ||
20+
trimmed.compare(QStringLiteral("KDE Plasma"), Qt::CaseInsensitive) == 0 ||
21+
trimmed.compare(QStringLiteral("Plasma"), Qt::CaseInsensitive) == 0) {
22+
return QStringLiteral("KDE Plasma");
23+
}
24+
25+
if (trimmed.compare(QStringLiteral("GNOME"), Qt::CaseInsensitive) == 0) {
26+
return QStringLiteral("GNOME");
27+
}
28+
29+
return trimmed;
30+
}
31+
1632
QString valueFromOsRelease(const QString &key) {
1733
QFile file(QStringLiteral("/etc/os-release"));
1834
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
@@ -88,15 +104,44 @@ QString SystemInfoProvider::detectKernelVersion() const {
88104

89105
QString SystemInfoProvider::detectCpuModel() const {
90106
#if defined(Q_OS_LINUX)
107+
CommandRunner runner;
108+
const auto lscpuResult = runner.run(QStringLiteral("lscpu"));
109+
if (lscpuResult.success()) {
110+
const QStringList lines =
111+
lscpuResult.stdout.split(QLatin1Char('\n'), Qt::SkipEmptyParts);
112+
for (const QString &line : lines) {
113+
if (line.startsWith(QStringLiteral("Model name:")) ||
114+
line.startsWith(QStringLiteral("Hardware:")) ||
115+
line.startsWith(QStringLiteral("Processor:"))) {
116+
const int separatorIndex = line.indexOf(QLatin1Char(':'));
117+
if (separatorIndex >= 0) {
118+
const QString value = line.mid(separatorIndex + 1).trimmed();
119+
if (!value.isEmpty() &&
120+
value.compare(QSysInfo::currentCpuArchitecture(),
121+
Qt::CaseInsensitive) != 0) {
122+
return value;
123+
}
124+
}
125+
}
126+
}
127+
}
128+
91129
QFile cpuInfo(QStringLiteral("/proc/cpuinfo"));
92130
if (cpuInfo.open(QIODevice::ReadOnly | QIODevice::Text)) {
93131
QTextStream stream(&cpuInfo);
94132
while (!stream.atEnd()) {
95133
const QString line = stream.readLine();
96-
if (line.startsWith(QStringLiteral("model name"))) {
134+
if (line.startsWith(QStringLiteral("model name")) ||
135+
line.startsWith(QStringLiteral("Hardware")) ||
136+
line.startsWith(QStringLiteral("Processor"))) {
97137
const int separatorIndex = line.indexOf(QLatin1Char(':'));
98138
if (separatorIndex >= 0) {
99-
return line.mid(separatorIndex + 1).trimmed();
139+
const QString value = line.mid(separatorIndex + 1).trimmed();
140+
if (!value.isEmpty() &&
141+
value.compare(QSysInfo::currentCpuArchitecture(),
142+
Qt::CaseInsensitive) != 0) {
143+
return value;
144+
}
100145
}
101146
}
102147
}
@@ -132,16 +177,12 @@ QString SystemInfoProvider::detectDesktopEnvironment() const {
132177
const QStringList parts = desktop.split(QLatin1Char('/'), Qt::SkipEmptyParts);
133178
QStringList normalizedParts;
134179
for (const QString &part : parts) {
135-
const QString trimmed = part.trimmed();
180+
const QString trimmed = simplifiedDesktopName(part);
136181
if (trimmed.isEmpty()) {
137182
continue;
138183
}
139184

140-
if (trimmed.compare(QStringLiteral("KDE"), Qt::CaseInsensitive) == 0) {
141-
normalizedParts << QStringLiteral("KDE Plasma");
142-
} else if (trimmed.compare(QStringLiteral("GNOME"), Qt::CaseInsensitive) == 0) {
143-
normalizedParts << QStringLiteral("GNOME");
144-
} else {
185+
if (!normalizedParts.contains(trimmed, Qt::CaseInsensitive)) {
145186
normalizedParts << trimmed;
146187
}
147188
}

src/qml/Main.qml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ ApplicationWindow {
5353
color: theme.window
5454
property bool languageDialogOpen: false
5555

56+
function navigateToPage(index) {
57+
sidebar.currentIndex = index;
58+
stack.currentIndex = index;
59+
}
60+
5661
function topBarValue(fallback, preferred) {
5762
return preferred && preferred.length > 0 ? preferred : fallback;
5863
}
@@ -212,6 +217,7 @@ ApplicationWindow {
212217
darkMode: root.darkMode
213218
compactMode: root.compactMode
214219
showAdvancedInfo: root.showAdvancedInfo
220+
navigateToPage: function(index) { root.navigateToPage(index); }
215221
}
216222

217223
SettingsPage {

0 commit comments

Comments
 (0)