feat: 添加GPU切换模式检测和主副显标识

- C++后端:GpuInfo添加isPrimary字段,读取boot_vga判断主副显
- C++后端:detectGpuMode()检测PRIME/Bumblebee/Solo/Hybrid模式
- C++后端:新增gpuMode和gpuPrimary属性
- QML前端:卡片显示绿色主显标签(boot_vga=1的GPU)
- QML前端:弹窗显示GPU模式标签(PRIME等)和帮助图标
- 帮助图标悬停显示模式说明文字
- 翻译更新:主显/主顯 + 四种模式的中文说明
This commit is contained in:
2026-07-14 00:19:56 +08:00
parent 403ae8a69b
commit d5a2c380ab
5 changed files with 216 additions and 6 deletions
+66
View File
@@ -63,6 +63,16 @@ QStringList GraphicsDriverApplet::gpuStats() const
return m_gpuStats;
}
QString GraphicsDriverApplet::gpuMode() const
{
return m_gpuMode;
}
QStringList GraphicsDriverApplet::gpuPrimary() const
{
return m_gpuPrimary;
}
void GraphicsDriverApplet::refreshDeviceInfo()
{
detectGpus();
@@ -87,6 +97,7 @@ void GraphicsDriverApplet::detectGpus()
GpuInfo gpu;
// 初始化统计字段
gpu.drmCard = -1;
gpu.isPrimary = false;
gpu.temperature = -1;
gpu.gpuUsage = -1;
gpu.memUsage = -1;
@@ -119,6 +130,12 @@ void GraphicsDriverApplet::detectGpus()
// 查找 DRM 卡号
gpu.drmCard = findDrmCard(gpu.pciId);
// 读取 boot_vga 判断主副显
QFile bootVgaFile("/sys/bus/pci/devices/0000:" + gpu.pciId + "/boot_vga");
if (bootVgaFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
gpu.isPrimary = QTextStream(&bootVgaFile).readAll().trimmed() == "1";
}
m_gpus.append(gpu);
}
}
@@ -146,16 +163,27 @@ void GraphicsDriverApplet::detectGpus()
m_gpuSummary = parts.join(" | ");
m_ready = !m_gpus.isEmpty();
// 生成主副显标识
m_gpuPrimary.clear();
for (const GpuInfo &gpu : m_gpus) {
m_gpuPrimary << (gpu.isPrimary ? "true" : "false");
}
qDebug() << "Detected GPUs:" << m_deviceInfo;
qDebug() << "Current drivers:" << m_currentDriver;
emit deviceInfoChanged();
emit currentDriverChanged();
emit gpuSummaryChanged();
emit gpuStatsChanged();
emit gpuPrimaryChanged();
emit readyChanged();
// 读取实时统计信息
readGpuStats();
// 检测 GPU 切换模式
detectGpuMode();
}
QStringList GraphicsDriverApplet::runCommand(const QString &cmd, const QStringList &args)
@@ -238,6 +266,44 @@ QString GraphicsDriverApplet::readDriverVersion(const QString &driverName)
return QString();
}
void GraphicsDriverApplet::detectGpuMode()
{
// 单 GPU
if (m_gpus.size() <= 1) {
m_gpuMode = "Solo";
emit gpuModeChanged();
return;
}
// 多 GPU:检测 PRIME / Bumblebee
// PRIME: nvidia-drm-outputclass.conf 存在
if (QFile::exists("/usr/share/X11/xorg.conf.d/nvidia-drm-outputclass.conf") ||
QFile::exists("/etc/X11/xorg.conf.d/70-nvidia.conf")) {
m_gpuMode = "PRIME";
emit gpuModeChanged();
return;
}
// Bumblebee: 检查 bumblebeed 服务
QStringList lsmod = runCommand("lsmod", {});
bool bumblebeeLoaded = false;
for (const QString &line : lsmod) {
if (line.contains("bumblebee", Qt::CaseInsensitive)) {
bumblebeeLoaded = true;
break;
}
}
if (bumblebeeLoaded || QFile::exists("/usr/sbin/bumblebeed")) {
m_gpuMode = "Bumblebee";
emit gpuModeChanged();
return;
}
// 多 GPU 但无已知切换方案
m_gpuMode = "Hybrid";
emit gpuModeChanged();
}
int GraphicsDriverApplet::findDrmCard(const QString &pciId)
{
// 扫描 /sys/bus/pci/devices/0000:XX:XX.X/drm/ 目录,找到 cardN 条目