From b440fdf40a898d64bc7ac76210c1a05ec25a6a1c Mon Sep 17 00:00:00 2001 From: jokul Date: Mon, 13 Jul 2026 21:14:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=A7=BB=E9=99=A4D-Bus=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=EF=BC=8C=E6=94=B9=E7=94=A8=20lspci=20=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E6=A3=80=E6=B5=8B=E6=98=BE=E5=8D=A1=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=BC=B9=E7=AA=97UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - C++ 后端:移除 D-Bus 通信,改用 lspci -mm + /sys/bus/pci 直接检测显卡和驱动 - 新增 gpuSummary、ready 属性,通过 /sys/module 和 /proc/driver 读取驱动版本 - QML:使用 DTK 配色,卡片式布局展示 GPU 列表,每张显卡独立卡片 - 移除安装/测试/取消按钮,聚焦显卡信息展示 - 翻译精简为 5 条,同步 zh_CN / zh_TW --- graphicsdriverapplet.cpp | 348 +++++++----------- graphicsdriverapplet.h | 63 ++-- package/driverview.qml | 311 ++++++++++------ .../org.deepin.ds.graphics-driver_zh_CN.ts | 36 +- .../org.deepin.ds.graphics-driver_zh_TW.ts | 36 +- 5 files changed, 376 insertions(+), 418 deletions(-) diff --git a/graphicsdriverapplet.cpp b/graphicsdriverapplet.cpp index d4c07e7..90ce758 100644 --- a/graphicsdriverapplet.cpp +++ b/graphicsdriverapplet.cpp @@ -5,29 +5,20 @@ #include "graphicsdriverapplet.h" #include -#include -#include -#include +#include +#include #include -#include -#include -#include +#include +#include +#include DCORE_USE_NAMESPACE DS_BEGIN_NAMESPACE -static const QString DBUS_SERVICE = "com.deepin.daemon.GraphicsDriver"; -static const QString DBUS_PATH = "/com/deepin/daemon/GraphicsDriver"; -static const QString DBUS_INTERFACE = "com.deepin.daemon.GraphicsDriver"; - GraphicsDriverApplet::GraphicsDriverApplet(QObject *parent) : DApplet(parent) - , m_dbusInterface(nullptr) - , m_progressTimer(new QTimer(this)) - , m_installProgress(0) - , m_isInstalling(false) - , m_dbusAvailable(false) + , m_ready(false) { } @@ -37,233 +28,176 @@ GraphicsDriverApplet::~GraphicsDriverApplet() bool GraphicsDriverApplet::load() { - initDBusConnection(); return DApplet::load(); } bool GraphicsDriverApplet::init() { - if (m_dbusAvailable) { - refreshDeviceInfo(); - } + detectGpus(); return DApplet::init(); } -QString GraphicsDriverApplet::currentDriver() const -{ - return m_currentDriver; -} - QString GraphicsDriverApplet::deviceInfo() const { return m_deviceInfo; } -int GraphicsDriverApplet::installProgress() const +QString GraphicsDriverApplet::currentDriver() const { - return m_installProgress; + return m_currentDriver; } -bool GraphicsDriverApplet::isInstalling() const +QString GraphicsDriverApplet::gpuSummary() const { - return m_isInstalling; + return m_gpuSummary; } -bool GraphicsDriverApplet::dbusAvailable() const +bool GraphicsDriverApplet::ready() const { - return m_dbusAvailable; + return m_ready; } void GraphicsDriverApplet::refreshDeviceInfo() { - if (!m_dbusInterface || !m_dbusInterface->isValid()) { - qWarning() << "DBus interface is not valid"; - return; - } - - // Get device info - QDBusPendingCall deviceCall = m_dbusInterface->asyncCall("GetDevice"); - QDBusPendingCallWatcher *deviceWatcher = new QDBusPendingCallWatcher(deviceCall, this); - connect(deviceWatcher, &QDBusPendingCallWatcher::finished, this, &GraphicsDriverApplet::onGetDeviceReply); - - // Get current driver - QDBusPendingCall currCall = m_dbusInterface->asyncCall("GetCurrDriverName"); - QDBusPendingCallWatcher *currWatcher = new QDBusPendingCallWatcher(currCall, this); - connect(currWatcher, &QDBusPendingCallWatcher::finished, this, &GraphicsDriverApplet::onGetCurrDriverReply); + detectGpus(); } -void GraphicsDriverApplet::prepareInstall(const QString &driverName) +void GraphicsDriverApplet::detectGpus() { - if (!m_dbusInterface || !m_dbusInterface->isValid()) { - emit installFailed("DBus interface is not valid"); - return; - } + m_gpus.clear(); - QLocale locale; - QString language = locale.name(); + // 通过 lspci 检测显卡 + QStringList lines = runCommand("lspci", {"-mm"}); + for (const QString &line : lines) { + if (line.contains("VGA compatible controller", Qt::CaseInsensitive) || + line.contains("3D controller", Qt::CaseInsensitive) || + line.contains("Display controller", Qt::CaseInsensitive)) { - QDBusPendingCall call = m_dbusInterface->asyncCall("PrepareInstall", driverName, language); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); - connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *call) { - QDBusPendingReply<> reply = *call; - if (reply.isError()) { - qWarning() << "Failed to prepare install:" << reply.error().message(); - emit installFailed(reply.error().message()); - } else { - qDebug() << "Prepare install succeeded"; - } - call->deleteLater(); - }); -} + GpuInfo gpu; + // lspci -mm 格式: "Class" "Vendor" "Device" ... + // 提取 PCI ID(行首的 01:00.0 等) + int spaceIdx = line.indexOf(' '); + if (spaceIdx > 0) { + gpu.pciId = line.left(spaceIdx); + } -void GraphicsDriverApplet::testInstall() -{ - if (!m_dbusInterface || !m_dbusInterface->isValid()) { - emit installFailed("DBus interface is not valid"); - return; - } + gpu.name = parseGpuName(line); - setInstalling(true); + // 检测驱动 + QString sysPath = "/sys/bus/pci/devices/0000:" + gpu.pciId + "/driver"; + QDir driverDir(sysPath); + if (driverDir.exists()) { + gpu.driver = driverDir.dirName(); - QDBusPendingCall call = m_dbusInterface->asyncCall("TestInstall"); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); - connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *call) { - QDBusPendingReply<> reply = *call; - if (reply.isError()) { - qWarning() << "Failed to test install:" << reply.error().message(); - emit installFailed(reply.error().message()); - setInstalling(false); - } else { - qDebug() << "Test install succeeded"; - realInstall(); - } - call->deleteLater(); - }); -} + // 读取驱动版本 + gpu.driverVersion = readDriverVersion(gpu.driver); + } else { + gpu.driver = "unknown"; + } -void GraphicsDriverApplet::realInstall() -{ - if (!m_dbusInterface || !m_dbusInterface->isValid()) { - emit installFailed("DBus interface is not valid"); - return; - } - - QDBusPendingCall call = m_dbusInterface->asyncCall("RealInstall"); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); - connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *call) { - QDBusPendingReply<> reply = *call; - if (reply.isError()) { - qWarning() << "Failed to real install:" << reply.error().message(); - emit installFailed(reply.error().message()); - setInstalling(false); - } else { - qDebug() << "Real install succeeded"; - setInstalling(false); - emit installSuccess(); - emit requestReboot(); - } - call->deleteLater(); - }); -} - -void GraphicsDriverApplet::cancelInstall() -{ - if (!m_dbusInterface || !m_dbusInterface->isValid()) { - return; - } - - m_dbusInterface->asyncCall("CancelInstall"); - setInstalling(false); -} - -void GraphicsDriverApplet::onGetDeviceReply(QDBusPendingCallWatcher *call) -{ - QDBusPendingReply reply = *call; - if (reply.isError()) { - qWarning() << "Failed to get device:" << reply.error().message(); - } else { - m_deviceInfo = reply.value(); - qDebug() << "Device info:" << m_deviceInfo; - emit deviceInfoChanged(); - } - call->deleteLater(); -} - -void GraphicsDriverApplet::onGetCurrDriverReply(QDBusPendingCallWatcher *call) -{ - QDBusPendingReply reply = *call; - if (reply.isError()) { - qWarning() << "Failed to get current driver:" << reply.error().message(); - } else { - m_currentDriver = reply.value(); - qDebug() << "Current driver:" << m_currentDriver; - emit currentDriverChanged(); - } - call->deleteLater(); -} - -void GraphicsDriverApplet::onReportProgress(const QString &ratio) -{ - bool ok; - int progress = ratio.toInt(&ok); - if (ok) { - m_installProgress = progress; - emit installProgressChanged(); - } -} - -void GraphicsDriverApplet::initDBusConnection() -{ - QDBusConnection bus = QDBusConnection::sessionBus(); - - if (!bus.isConnected()) { - qWarning() << "Cannot connect to D-Bus session bus"; - return; - } - - // 检查服务是否已注册 - bool registered = bus.interface()->isServiceRegistered(DBUS_SERVICE); - if (!registered) { - qWarning() << "GraphicsDriver D-Bus service is not registered"; - return; - } - - m_dbusInterface = new QDBusInterface( - DBUS_SERVICE, - DBUS_PATH, - DBUS_INTERFACE, - bus, - this - ); - - if (!m_dbusInterface->isValid()) { - qWarning() << "DBus interface is not valid:" << m_dbusInterface->lastError().message(); - return; - } - - m_dbusAvailable = true; - emit dbusAvailableChanged(); - - connect(m_dbusInterface, SIGNAL(ReportProgress(QString)), - this, SLOT(onReportProgress(QString))); - - qDebug() << "GraphicsDriver D-Bus connected successfully"; -} - -void GraphicsDriverApplet::setInstalling(bool installing) -{ - if (m_isInstalling != installing) { - m_isInstalling = installing; - emit isInstallingChanged(); - - if (installing) { - m_progressTimer->start(1000); - } else { - m_progressTimer->stop(); - m_installProgress = 0; - emit installProgressChanged(); + m_gpus.append(gpu); } } + + // 生成摘要信息 + QStringList parts; + QStringList driverParts; + for (const GpuInfo &gpu : m_gpus) { + QString info = gpu.name; + if (!gpu.driver.isEmpty() && gpu.driver != "unknown") { + info += " (" + gpu.driver; + if (!gpu.driverVersion.isEmpty()) { + info += " " + gpu.driverVersion; + } + info += ")"; + } + parts << info; + if (!gpu.driver.isEmpty() && !driverParts.contains(gpu.driver)) { + driverParts << gpu.driver; + } + } + + m_deviceInfo = parts.join("\n"); + m_currentDriver = driverParts.join(", "); + m_gpuSummary = parts.join(" | "); + m_ready = !m_gpus.isEmpty(); + + qDebug() << "Detected GPUs:" << m_deviceInfo; + qDebug() << "Current drivers:" << m_currentDriver; + + emit deviceInfoChanged(); + emit currentDriverChanged(); + emit gpuSummaryChanged(); + emit readyChanged(); +} + +QStringList GraphicsDriverApplet::runCommand(const QString &cmd, const QStringList &args) +{ + QProcess process; + process.start(cmd, args); + process.waitForFinished(5000); + QString output = QString::fromUtf8(process.readAllStandardOutput()); + return output.split('\n', Qt::SkipEmptyParts); +} + +QString GraphicsDriverApplet::parseGpuName(const QString &line) +{ + // lspci -mm 格式示例: + // 01:00.0 "VGA compatible controller" "NVIDIA Corporation" "GA106M [GeForce RTX 3060 Mobile / Max-Q]" "ASUSTeK Computer Inc." "Device 10a2" + // 提取引号中的内容 + QStringList parts; + int pos = 0; + while (pos < line.length()) { + int start = line.indexOf('"', pos); + if (start < 0) break; + int end = line.indexOf('"', start + 1); + if (end < 0) break; + parts << line.mid(start + 1, end - start - 1); + pos = end + 1; + } + + if (parts.size() >= 3) { + // parts[0] = class, parts[1] = vendor, parts[2] = device + QString vendor = parts[1]; + QString device = parts[2]; + // 去掉方括号内的别名,保留主要名称 + int bracket = device.indexOf('['); + if (bracket > 0) { + // 保留完整名称,方括号内是子系统信息 + } + return vendor + " " + device; + } + + return line; +} + +QString GraphicsDriverApplet::readDriverVersion(const QString &driverName) +{ + // 尝试从 /sys/module//version 读取版本 + QString path = "/sys/module/" + driverName + "/version"; + QFile file(path); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QString version = QTextStream(&file).readAll().trimmed(); + if (!version.isEmpty()) { + return version; + } + } + + // nvidia 特殊处理:从 /proc/driver/nvidia/version 读取 + if (driverName == "nvidia") { + QFile nvFile("/proc/driver/nvidia/version"); + if (nvFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + QString content = QTextStream(&nvFile).readAll(); + // 格式: NVRM version: NVIDIA UNIX x86_64 Kernel Module 535.183.01 ... + QRegularExpression re("Kernel Module\\s+(\\d+\\.\\d+\\.\\d+)"); + auto match = re.match(content); + if (match.hasMatch()) { + return match.captured(1); + } + } + } + + return QString(); } D_APPLET_CLASS(GraphicsDriverApplet) diff --git a/graphicsdriverapplet.h b/graphicsdriverapplet.h index 5188e7f..dc00776 100644 --- a/graphicsdriverapplet.h +++ b/graphicsdriverapplet.h @@ -6,23 +6,27 @@ #include -#include -#include +#include +#include #include -#include -#include DS_BEGIN_NAMESPACE +struct GpuInfo { + QString name; // 显卡名称,如 "NVIDIA GeForce RTX 3060" + QString driver; // 驱动模块名,如 "nvidia" + QString driverVersion; // 驱动版本 + QString pciId; // PCI ID,如 "01:00.0" +}; + class GraphicsDriverApplet : public DApplet { Q_OBJECT - Q_PROPERTY(QString currentDriver READ currentDriver NOTIFY currentDriverChanged) Q_PROPERTY(QString deviceInfo READ deviceInfo NOTIFY deviceInfoChanged) - Q_PROPERTY(int installProgress READ installProgress NOTIFY installProgressChanged) - Q_PROPERTY(bool isInstalling READ isInstalling NOTIFY isInstallingChanged) - Q_PROPERTY(bool dbusAvailable READ dbusAvailable NOTIFY dbusAvailableChanged) + Q_PROPERTY(QString currentDriver READ currentDriver NOTIFY currentDriverChanged) + Q_PROPERTY(QString gpuSummary READ gpuSummary NOTIFY gpuSummaryChanged) + Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) public: explicit GraphicsDriverApplet(QObject *parent = nullptr); @@ -31,45 +35,30 @@ public: virtual bool load() override; virtual bool init() override; - QString currentDriver() const; QString deviceInfo() const; - int installProgress() const; - bool isInstalling() const; - bool dbusAvailable() const; + QString currentDriver() const; + QString gpuSummary() const; + bool ready() const; Q_INVOKABLE void refreshDeviceInfo(); - Q_INVOKABLE void prepareInstall(const QString &driverName); - Q_INVOKABLE void testInstall(); - Q_INVOKABLE void realInstall(); - Q_INVOKABLE void cancelInstall(); signals: - void currentDriverChanged(); void deviceInfoChanged(); - void installProgressChanged(); - void isInstallingChanged(); - void installSuccess(); - void installFailed(const QString &error); - void requestReboot(); - void dbusAvailableChanged(); - -private slots: - void onGetDeviceReply(QDBusPendingCallWatcher *call); - void onGetCurrDriverReply(QDBusPendingCallWatcher *call); - void onReportProgress(const QString &ratio); + void currentDriverChanged(); + void gpuSummaryChanged(); + void readyChanged(); private: - void initDBusConnection(); - void setInstalling(bool installing); + void detectGpus(); + static QStringList runCommand(const QString &cmd, const QStringList &args); + static QString parseGpuName(const QString &line); + static QString readDriverVersion(const QString &driverName); - QDBusInterface *m_dbusInterface; - QTimer *m_progressTimer; - bool m_dbusAvailable; - - QString m_currentDriver; + QList m_gpus; QString m_deviceInfo; - int m_installProgress; - bool m_isInstalling; + QString m_currentDriver; + QString m_gpuSummary; + bool m_ready; }; DS_END_NAMESPACE diff --git a/package/driverview.qml b/package/driverview.qml index d42b633..20a5663 100644 --- a/package/driverview.qml +++ b/package/driverview.qml @@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import org.deepin.ds 1.0 import org.deepin.ds.dock 1.0 +import org.deepin.dtk 1.0 AppletItem { id: root @@ -17,24 +18,32 @@ AppletItem { implicitWidth: dockSize implicitHeight: dockSize - // 访问 C++ 后端 readonly property var applet: Applet - readonly property bool dbusAvailable: applet && applet.dbusAvailable - readonly property string currentDriver: applet ? (applet.currentDriver || qsTr("Unknown")) : qsTr("Unknown") + readonly property bool ready: applet ? applet.ready : false + readonly property string gpuSummary: applet ? (applet.gpuSummary || qsTr("No GPU detected")) : qsTr("No GPU detected") readonly property string deviceInfo: applet ? (applet.deviceInfo || qsTr("Unknown")) : qsTr("Unknown") - readonly property bool isInstalling: applet ? applet.isInstalling : false - readonly property int installProgress: applet ? applet.installProgress : 0 + readonly property string currentDriver: applet ? (applet.currentDriver || qsTr("Unknown")) : qsTr("Unknown") + + property Palette basePalette: DockPalette.iconTextPalette + readonly property color primaryText: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.9) + readonly property color secondaryText: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.65) + readonly property color tertiaryText: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.5) + readonly property color cardBackground: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.06) + readonly property color cardBorder: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.1) + readonly property color accentBlue: Qt.rgba(36 / 255, 118 / 255, 220 / 255, 1) + readonly property color accentBlueLight: Qt.rgba(36 / 255, 118 / 255, 220 / 255, 0.15) // 图标区域 Rectangle { anchors.fill: parent - color: "#3498db" + color: accentBlue radius: 8 Text { anchors.centerIn: parent text: "GPU" font.pixelSize: root.dockSize * 0.3 + font.bold: true color: "white" } } @@ -42,7 +51,7 @@ AppletItem { // 悬停提示 PanelToolTip { id: toolTip - text: qsTr("Graphics Driver: ") + root.currentDriver + text: root.ready ? root.gpuSummary : qsTr("No GPU detected") toolTipX: DockPanelPositioner.x toolTipY: DockPanelPositioner.y } @@ -73,8 +82,8 @@ AppletItem { // 弹出窗口 PanelPopup { id: driverPopup - width: 320 - height: 400 + width: 360 + height: 320 popupX: DockPanelPositioner.x popupY: DockPanelPositioner.y @@ -90,114 +99,196 @@ AppletItem { padding: 16 contentItem: ColumnLayout { - spacing: 12 + spacing: 14 - Text { - text: qsTr("Graphics Driver Manager") - font.pixelSize: 16 - font.bold: true + // 标题区域 + RowLayout { Layout.fillWidth: true + spacing: 10 + + Rectangle { + width: 28 + height: 28 + color: accentBlueLight + radius: 8 + + Text { + anchors.centerIn: parent + text: "GPU" + font.pixelSize: 12 + font.bold: true + color: accentBlue + } + } + + Text { + text: qsTr("Graphics Driver Manager") + font.pixelSize: 16 + font.bold: true + color: root.primaryText + Layout.fillWidth: true + } } + // 分隔线 Rectangle { Layout.fillWidth: true Layout.preferredHeight: 1 - color: "#cccccc" + color: root.cardBorder } - // D-Bus 不可用提示 - Rectangle { - Layout.fillWidth: true - height: 40 - visible: !root.dbusAvailable - color: "#fff3cd" - radius: 6 - - Text { - anchors.centerIn: parent - text: qsTr("Driver service is not available") - color: "#856404" - font.pixelSize: 12 - } - } - - // 设备信息 - GroupBox { - Layout.fillWidth: true - title: qsTr("Device Information") - visible: root.dbusAvailable - - ColumnLayout { - anchors.fill: parent - spacing: 8 - - Text { - text: qsTr("Current Driver: ") + root.currentDriver - font.pixelSize: 12 - Layout.fillWidth: true - } - - Text { - text: qsTr("Device: ") + root.deviceInfo - font.pixelSize: 12 - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - } - } - - // 操作按钮 - Button { - text: qsTr("Refresh") - Layout.fillWidth: true - enabled: root.dbusAvailable && !root.isInstalling - onClicked: { - if (root.applet) { - root.applet.refreshDeviceInfo() - } - } - } - - Button { - text: qsTr("Test Install") - Layout.fillWidth: true - enabled: root.dbusAvailable && !root.isInstalling - onClicked: { - if (root.applet) { - root.applet.testInstall() - } - } - } - - // 安装进度 - ColumnLayout { - visible: root.isInstalling + // 当前驱动信息 + RowLayout { Layout.fillWidth: true spacing: 8 + visible: root.ready Text { - text: qsTr("Installing... ") + root.installProgress + "%" + text: qsTr("Current Driver:") font.pixelSize: 12 + color: root.secondaryText } - ProgressBar { + Text { + text: root.currentDriver + font.pixelSize: 12 + font.bold: true + color: root.primaryText Layout.fillWidth: true - value: root.installProgress / 100 + elide: Text.ElideRight + } + } + + // GPU 列表区域 + Flickable { + id: gpuListFlick + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + contentWidth: width + contentHeight: gpuColumn.height + boundsBehavior: Flickable.StopAtBounds + + Column { + id: gpuColumn + width: gpuListFlick.width + spacing: 10 + visible: root.ready + + Repeater { + model: root.ready ? root.deviceInfo.split("\n").filter(function(line) { return line.trim().length > 0 }) : [] + + delegate: Rectangle { + width: gpuColumn.width + height: 72 + color: root.cardBackground + radius: 10 + border.width: 1 + border.color: root.cardBorder + + RowLayout { + anchors.fill: parent + anchors.margins: 12 + spacing: 12 + + // GPU 图标 + Rectangle { + width: 44 + height: 44 + color: root.accentBlueLight + radius: 8 + + Text { + anchors.centerIn: parent + text: "GPU" + font.pixelSize: 14 + font.bold: true + color: root.accentBlue + } + } + + // GPU 信息 + ColumnLayout { + spacing: 4 + Layout.fillWidth: true + + Text { + text: parseGpuName(modelData) + font.pixelSize: 13 + font.bold: true + color: root.primaryText + Layout.fillWidth: true + elide: Text.ElideRight + } + + Text { + text: parseDriverInfo(modelData) + font.pixelSize: 11 + color: root.secondaryText + Layout.fillWidth: true + elide: Text.ElideRight + } + } + } + } + } } - Button { - text: qsTr("Cancel") - Layout.fillWidth: true - onClicked: { - if (root.applet) { - root.applet.cancelInstall() + // 未检测到 GPU 提示 + Rectangle { + anchors.centerIn: parent + width: gpuListFlick.width - 32 + height: 80 + color: root.cardBackground + radius: 10 + border.width: 1 + border.color: root.cardBorder + visible: !root.ready + + ColumnLayout { + anchors.centerIn: parent + spacing: 6 + + Text { + text: "⚠" + font.pixelSize: 24 + } + + Text { + text: qsTr("No GPU detected") + font.pixelSize: 13 + color: root.secondaryText } } } } - Item { - Layout.fillHeight: true + // 刷新按钮 + Button { + id: refreshBtn + text: qsTr("Refresh") + Layout.fillWidth: true + Layout.preferredHeight: 36 + font.pixelSize: 13 + + background: Rectangle { + color: refreshBtn.hovered ? root.accentBlue : root.accentBlueLight + radius: 8 + } + + contentItem: Text { + text: refreshBtn.text + color: refreshBtn.hovered ? "white" : root.accentBlue + font.pixelSize: refreshBtn.font.pixelSize + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: { + if (root.applet) { + root.applet.refreshDeviceInfo() + } + } } } } @@ -210,6 +301,25 @@ AppletItem { } } + // 解析 GPU 名称的辅助函数 + function parseGpuName(info) { + var parts = info.split("(") + if (parts.length > 0) { + return parts[0].trim() + } + return info + } + + // 解析驱动信息的辅助函数 + function parseDriverInfo(info) { + var startIndex = info.indexOf("(") + var endIndex = info.lastIndexOf(")") + if (startIndex !== -1 && endIndex !== -1) { + return info.substring(startIndex + 1, endIndex) + } + return info + } + // 点击处理 TapHandler { acceptedButtons: Qt.LeftButton @@ -220,7 +330,6 @@ AppletItem { driverPopup.close() } else { Panel.requestClosePopup() - // 在打开前设置定位,确保弹窗出现在插件附近 const point = root.mapToItem(null, root.width / 2, root.height / 2) driverPopup.DockPanelPositioner.bounding = Qt.rect(point.x, point.y, driverPopup.width, driverPopup.height) driverPopup.open() @@ -228,18 +337,4 @@ AppletItem { toolTip.close() } } - - // 后端信号处理 - Connections { - target: root.applet - function onInstallSuccess() { - console.log("Install succeeded") - } - function onInstallFailed(error) { - console.log("Install failed:", error) - } - function onRequestReboot() { - console.log("Reboot requested") - } - } } diff --git a/translations/org.deepin.ds.graphics-driver_zh_CN.ts b/translations/org.deepin.ds.graphics-driver_zh_CN.ts index 027aa5b..a50e618 100644 --- a/translations/org.deepin.ds.graphics-driver_zh_CN.ts +++ b/translations/org.deepin.ds.graphics-driver_zh_CN.ts @@ -10,8 +10,8 @@ - Graphics Driver: - 显卡驱动: + No GPU detected + 未检测到显卡 @@ -20,43 +20,13 @@ - Driver service is not available - 驱动服务不可用 - - - - Device Information - 设备信息 - - - - Current Driver: + Current Driver: 当前驱动: - - - Device: - 设备: - Refresh 刷新 - - - Test Install - 测试安装 - - - - Installing... - 安装中... - - - - Cancel - 取消 - diff --git a/translations/org.deepin.ds.graphics-driver_zh_TW.ts b/translations/org.deepin.ds.graphics-driver_zh_TW.ts index 1742dd6..4f48244 100644 --- a/translations/org.deepin.ds.graphics-driver_zh_TW.ts +++ b/translations/org.deepin.ds.graphics-driver_zh_TW.ts @@ -10,8 +10,8 @@ - Graphics Driver: - 顯示卡驅動: + No GPU detected + 未偵測到顯示卡 @@ -20,43 +20,13 @@ - Driver service is not available - 驅動服務不可用 - - - - Device Information - 裝置資訊 - - - - Current Driver: + Current Driver: 目前驅動: - - - Device: - 裝置: - Refresh 重新整理 - - - Test Install - 測試安裝 - - - - Installing... - 安裝中... - - - - Cancel - 取消 -