From 8d0c1ec5a601b1726bce7dbf10f131d3392f3059 Mon Sep 17 00:00:00 2001 From: jokul Date: Sun, 12 Jul 2026 21:35:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=81=A2=E5=A4=8D=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=8C=85=E5=90=ABD-Bus=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E5=92=8CQML=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 3 +- graphicsdriverapplet.cpp | 226 +++++++++++++++++++++++++++++++++++++++ graphicsdriverapplet.h | 49 +++++++++ package/driverview.qml | 125 ++++++++++++++++++++++ 4 files changed, 402 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ff7ce4..690d2f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) -find_package(Qt6 REQUIRED COMPONENTS Core Quick) +find_package(Qt6 REQUIRED COMPONENTS Core Quick DBus) find_package(Dtk6 REQUIRED COMPONENTS Core) add_library(org.deepin.ds.graphics-driver SHARED @@ -28,6 +28,7 @@ target_include_directories(org.deepin.ds.graphics-driver PRIVATE target_link_libraries(org.deepin.ds.graphics-driver PRIVATE Qt6::Core Qt6::Quick + Qt6::DBus Dtk6::Core ) diff --git a/graphicsdriverapplet.cpp b/graphicsdriverapplet.cpp index 7a44b27..54fb70b 100644 --- a/graphicsdriverapplet.cpp +++ b/graphicsdriverapplet.cpp @@ -5,23 +5,249 @@ #include "graphicsdriverapplet.h" #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) +{ +} + +GraphicsDriverApplet::~GraphicsDriverApplet() { } bool GraphicsDriverApplet::load() { + initDBusConnection(); + connect(m_progressTimer, &QTimer::timeout, [this]() { + // Poll progress + }); return DApplet::load(); } bool GraphicsDriverApplet::init() { + refreshDeviceInfo(); return DApplet::init(); } +QString GraphicsDriverApplet::currentDriver() const +{ + return m_currentDriver; +} + +QString GraphicsDriverApplet::deviceInfo() const +{ + return m_deviceInfo; +} + +int GraphicsDriverApplet::installProgress() const +{ + return m_installProgress; +} + +bool GraphicsDriverApplet::isInstalling() const +{ + return m_isInstalling; +} + +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); +} + +void GraphicsDriverApplet::prepareInstall(const QString &driverName) +{ + if (!m_dbusInterface || !m_dbusInterface->isValid()) { + emit installFailed("DBus interface is not valid"); + return; + } + + QLocale locale; + QString language = locale.name(); + + 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(); + }); +} + +void GraphicsDriverApplet::testInstall() +{ + if (!m_dbusInterface || !m_dbusInterface->isValid()) { + emit installFailed("DBus interface is not valid"); + return; + } + + setInstalling(true); + + 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(); + }); +} + +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; + } + + 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; + } + + connect(m_dbusInterface, SIGNAL(ReportProgress(QString)), + this, SLOT(onReportProgress(QString))); +} + +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(); + } + } +} + D_APPLET_CLASS(GraphicsDriverApplet) DS_END_NAMESPACE diff --git a/graphicsdriverapplet.h b/graphicsdriverapplet.h index ceb9f14..69a8676 100644 --- a/graphicsdriverapplet.h +++ b/graphicsdriverapplet.h @@ -6,17 +6,66 @@ #include +#include +#include +#include +#include +#include + DS_BEGIN_NAMESPACE 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) + public: explicit GraphicsDriverApplet(QObject *parent = nullptr); + ~GraphicsDriverApplet(); virtual bool load() override; virtual bool init() override; + + QString currentDriver() const; + QString deviceInfo() const; + int installProgress() const; + bool isInstalling() 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(); + +private slots: + void onGetDeviceReply(QDBusPendingCallWatcher *call); + void onGetCurrDriverReply(QDBusPendingCallWatcher *call); + void onReportProgress(const QString &ratio); + +private: + void initDBusConnection(); + void setInstalling(bool installing); + + QDBusInterface *m_dbusInterface; + QTimer *m_progressTimer; + + QString m_currentDriver; + QString m_deviceInfo; + int m_installProgress; + bool m_isInstalling; }; DS_END_NAMESPACE diff --git a/package/driverview.qml b/package/driverview.qml index 5cd751c..44c3505 100644 --- a/package/driverview.qml +++ b/package/driverview.qml @@ -4,6 +4,7 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 import org.deepin.ds 1.0 ContainmentItem { @@ -13,6 +14,8 @@ ContainmentItem { implicitHeight: 56 property int dockOrder: 20 + property var applet: Applet + Rectangle { anchors.fill: parent color: "#3498db" @@ -24,5 +27,127 @@ ContainmentItem { font.pixelSize: 14 color: "white" } + + MouseArea { + anchors.fill: parent + onClicked: { + popup.visible = !popup.visible + } + } + } + + Popup { + id: popup + x: 0 + y: -popup.height - 10 + width: 300 + height: 400 + closePolicy: Popup.CloseOnPressOutside + + ColumnLayout { + anchors.fill: parent + anchors.margins: 16 + spacing: 12 + + Text { + text: "Graphics Driver Manager" + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true + } + + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 1 + color: "#ccc" + } + + GroupBox { + Layout.fillWidth: true + title: "Device Information" + + ColumnLayout { + anchors.fill: parent + spacing: 8 + + Text { + text: "Current Driver: " + (root.applet ? root.applet.currentDriver || "Unknown" : "Unknown") + font.pixelSize: 12 + Layout.fillWidth: true + } + + Text { + text: "Device Info: " + (root.applet ? root.applet.deviceInfo || "Unknown" : "Unknown") + font.pixelSize: 12 + wrapMode: Text.WordWrap + Layout.fillWidth: true + } + } + } + + Button { + text: "Refresh" + Layout.fillWidth: true + onClicked: { + if (root.applet) { + root.applet.refreshDeviceInfo() + } + } + } + + Button { + text: "Test Install" + Layout.fillWidth: true + enabled: root.applet && !root.applet.isInstalling + onClicked: { + if (root.applet) { + root.applet.testInstall() + } + } + } + + ColumnLayout { + visible: root.applet && root.applet.isInstalling + Layout.fillWidth: true + spacing: 8 + + Text { + text: "Installing... " + (root.applet ? root.applet.installProgress + "%" : "0%") + font.pixelSize: 12 + } + + ProgressBar { + Layout.fillWidth: true + value: root.applet ? root.applet.installProgress / 100 : 0 + } + + Button { + text: "Cancel" + Layout.fillWidth: true + onClicked: { + if (root.applet) { + root.applet.cancelInstall() + } + } + } + } + + Item { + Layout.fillHeight: true + } + } + } + + Connections { + target: root.applet + function onInstallSuccess() { + console.log("Install succeeded") + } + function onInstallFailed(error) { + console.log("Install failed:", error) + } + function onRequestReboot() { + console.log("Reboot requested") + } } }