diff --git a/graphicsdriverapplet.cpp b/graphicsdriverapplet.cpp index 54fb70b..d4c07e7 100644 --- a/graphicsdriverapplet.cpp +++ b/graphicsdriverapplet.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,7 @@ GraphicsDriverApplet::GraphicsDriverApplet(QObject *parent) , m_progressTimer(new QTimer(this)) , m_installProgress(0) , m_isInstalling(false) + , m_dbusAvailable(false) { } @@ -36,15 +38,14 @@ GraphicsDriverApplet::~GraphicsDriverApplet() bool GraphicsDriverApplet::load() { initDBusConnection(); - connect(m_progressTimer, &QTimer::timeout, [this]() { - // Poll progress - }); return DApplet::load(); } bool GraphicsDriverApplet::init() { - refreshDeviceInfo(); + if (m_dbusAvailable) { + refreshDeviceInfo(); + } return DApplet::init(); } @@ -68,6 +69,11 @@ bool GraphicsDriverApplet::isInstalling() const return m_isInstalling; } +bool GraphicsDriverApplet::dbusAvailable() const +{ + return m_dbusAvailable; +} + void GraphicsDriverApplet::refreshDeviceInfo() { if (!m_dbusInterface || !m_dbusInterface->isValid()) { @@ -215,6 +221,13 @@ void GraphicsDriverApplet::initDBusConnection() 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, @@ -228,8 +241,13 @@ void GraphicsDriverApplet::initDBusConnection() 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) diff --git a/graphicsdriverapplet.h b/graphicsdriverapplet.h index 69a8676..5188e7f 100644 --- a/graphicsdriverapplet.h +++ b/graphicsdriverapplet.h @@ -22,6 +22,7 @@ class GraphicsDriverApplet : public DApplet 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) public: explicit GraphicsDriverApplet(QObject *parent = nullptr); @@ -34,6 +35,7 @@ public: QString deviceInfo() const; int installProgress() const; bool isInstalling() const; + bool dbusAvailable() const; Q_INVOKABLE void refreshDeviceInfo(); Q_INVOKABLE void prepareInstall(const QString &driverName); @@ -49,6 +51,7 @@ signals: void installSuccess(); void installFailed(const QString &error); void requestReboot(); + void dbusAvailableChanged(); private slots: void onGetDeviceReply(QDBusPendingCallWatcher *call); @@ -61,6 +64,7 @@ private: QDBusInterface *m_dbusInterface; QTimer *m_progressTimer; + bool m_dbusAvailable; QString m_currentDriver; QString m_deviceInfo; diff --git a/install.sh b/install.sh index 3c41ad6..f6b062a 100755 --- a/install.sh +++ b/install.sh @@ -2,8 +2,11 @@ set -e +# 切换到项目根目录 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + echo "=== 构建插件 ===" -cd ~/Documents/projects/JSwitchDisplayApplet rm -rf build cmake -Bbuild cmake --build build diff --git a/package/driverview.qml b/package/driverview.qml index ad8e1a3..d42b633 100644 --- a/package/driverview.qml +++ b/package/driverview.qml @@ -11,39 +11,70 @@ import org.deepin.ds.dock 1.0 AppletItem { id: root objectName: "graphics driver applet" + property int dockOrder: 21 + property int dockSize: Panel.rootObject.dockItemMaxSize || 48 - property bool useColumnLayout: Panel.position % 2 - property int dockOrder: 20 - property int dockSize: Panel.rootObject.dockSize || 48 - - implicitWidth: useColumnLayout ? dockSize : 80 + implicitWidth: dockSize implicitHeight: dockSize - property var applet: Applet + // 访问 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 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 + // 图标区域 + Rectangle { + anchors.fill: parent + color: "#3498db" + radius: 8 + + Text { + anchors.centerIn: parent + text: "GPU" + font.pixelSize: root.dockSize * 0.3 + color: "white" + } + } + + // 悬停提示 PanelToolTip { id: toolTip - text: qsTr("Graphics Driver Manager") + text: qsTr("Graphics Driver: ") + root.currentDriver toolTipX: DockPanelPositioner.x toolTipY: DockPanelPositioner.y } + Timer { + id: toolTipShowTimer + interval: 50 + onTriggered: { + const point = root.mapToItem(null, root.width / 2, root.height / 2) + toolTip.DockPanelPositioner.bounding = Qt.rect(point.x, point.y, toolTip.width, toolTip.height) + toolTip.open() + } + } + HoverHandler { onHoveredChanged: { if (hovered && !driverPopup.popupVisible) { - const point = root.mapToItem(null, root.width / 2, root.height / 2) - toolTip.DockPanelPositioner.bounding = Qt.rect(point.x, point.y, toolTip.width, toolTip.height) - toolTip.open() + toolTipShowTimer.start() } else { + if (toolTipShowTimer.running) { + toolTipShowTimer.stop() + } toolTip.close() } } } + // 弹出窗口 PanelPopup { id: driverPopup - width: 300 - height: 360 + width: 320 + height: 400 popupX: DockPanelPositioner.x popupY: DockPanelPositioner.y @@ -53,96 +84,121 @@ AppletItem { } } - ColumnLayout { + Control { + id: popupContainer anchors.fill: parent - anchors.margins: 16 - spacing: 12 + padding: 16 - Text { - text: qsTr("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: qsTr("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: qsTr("Refresh") - Layout.fillWidth: true - onClicked: { - if (root.applet) { - root.applet.refreshDeviceInfo() - } - } - } - - Button { - text: qsTr("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 + contentItem: ColumnLayout { + spacing: 12 Text { - text: qsTr("Installing... ") + (root.applet ? root.applet.installProgress + "%" : "0%") - font.pixelSize: 12 + text: qsTr("Graphics Driver Manager") + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true } - ProgressBar { + Rectangle { Layout.fillWidth: true - value: root.applet ? root.applet.installProgress / 100 : 0 + Layout.preferredHeight: 1 + color: "#cccccc" } - Button { - text: qsTr("Cancel") + // D-Bus 不可用提示 + Rectangle { Layout.fillWidth: true - onClicked: { - if (root.applet) { - root.applet.cancelInstall() + 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 } } } - } - Item { - Layout.fillHeight: 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 + Layout.fillWidth: true + spacing: 8 + + Text { + text: qsTr("Installing... ") + root.installProgress + "%" + font.pixelSize: 12 + } + + ProgressBar { + Layout.fillWidth: true + value: root.installProgress / 100 + } + + Button { + text: qsTr("Cancel") + Layout.fillWidth: true + onClicked: { + if (root.applet) { + root.applet.cancelInstall() + } + } + } + } + + Item { + Layout.fillHeight: true + } } } @@ -154,6 +210,7 @@ AppletItem { } } + // 点击处理 TapHandler { acceptedButtons: Qt.LeftButton gesturePolicy: TapHandler.ReleaseWithinBounds @@ -163,12 +220,16 @@ 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() } toolTip.close() } } + // 后端信号处理 Connections { target: root.applet function onInstallSuccess() {