feat: 恢复完整功能,包含D-Bus通信和QML界面
This commit is contained in:
+2
-1
@@ -10,7 +10,7 @@ set(CMAKE_CXX_STANDARD 17)
|
|||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_AUTOMOC 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)
|
find_package(Dtk6 REQUIRED COMPONENTS Core)
|
||||||
|
|
||||||
add_library(org.deepin.ds.graphics-driver SHARED
|
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
|
target_link_libraries(org.deepin.ds.graphics-driver PRIVATE
|
||||||
Qt6::Core
|
Qt6::Core
|
||||||
Qt6::Quick
|
Qt6::Quick
|
||||||
|
Qt6::DBus
|
||||||
Dtk6::Core
|
Dtk6::Core
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,23 +5,249 @@
|
|||||||
#include "graphicsdriverapplet.h"
|
#include "graphicsdriverapplet.h"
|
||||||
#include <pluginfactory.h>
|
#include <pluginfactory.h>
|
||||||
|
|
||||||
|
#include <QDBusConnection>
|
||||||
|
#include <QDBusPendingReply>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
DCORE_USE_NAMESPACE
|
||||||
|
|
||||||
DS_BEGIN_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)
|
GraphicsDriverApplet::GraphicsDriverApplet(QObject *parent)
|
||||||
: DApplet(parent)
|
: DApplet(parent)
|
||||||
|
, m_dbusInterface(nullptr)
|
||||||
|
, m_progressTimer(new QTimer(this))
|
||||||
|
, m_installProgress(0)
|
||||||
|
, m_isInstalling(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicsDriverApplet::~GraphicsDriverApplet()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GraphicsDriverApplet::load()
|
bool GraphicsDriverApplet::load()
|
||||||
{
|
{
|
||||||
|
initDBusConnection();
|
||||||
|
connect(m_progressTimer, &QTimer::timeout, [this]() {
|
||||||
|
// Poll progress
|
||||||
|
});
|
||||||
return DApplet::load();
|
return DApplet::load();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GraphicsDriverApplet::init()
|
bool GraphicsDriverApplet::init()
|
||||||
{
|
{
|
||||||
|
refreshDeviceInfo();
|
||||||
return DApplet::init();
|
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<QString> 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<QString> 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)
|
D_APPLET_CLASS(GraphicsDriverApplet)
|
||||||
|
|
||||||
DS_END_NAMESPACE
|
DS_END_NAMESPACE
|
||||||
|
|||||||
@@ -6,17 +6,66 @@
|
|||||||
|
|
||||||
#include <applet.h>
|
#include <applet.h>
|
||||||
|
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QDBusPendingCallWatcher>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
DS_BEGIN_NAMESPACE
|
DS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class GraphicsDriverApplet : public DApplet
|
class GraphicsDriverApplet : public DApplet
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
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:
|
public:
|
||||||
explicit GraphicsDriverApplet(QObject *parent = nullptr);
|
explicit GraphicsDriverApplet(QObject *parent = nullptr);
|
||||||
|
~GraphicsDriverApplet();
|
||||||
|
|
||||||
virtual bool load() override;
|
virtual bool load() override;
|
||||||
virtual bool init() 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
|
DS_END_NAMESPACE
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
import org.deepin.ds 1.0
|
import org.deepin.ds 1.0
|
||||||
|
|
||||||
ContainmentItem {
|
ContainmentItem {
|
||||||
@@ -13,6 +14,8 @@ ContainmentItem {
|
|||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
property int dockOrder: 20
|
property int dockOrder: 20
|
||||||
|
|
||||||
|
property var applet: Applet
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "#3498db"
|
color: "#3498db"
|
||||||
@@ -24,5 +27,127 @@ ContainmentItem {
|
|||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
color: "white"
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user