diff --git a/desktopintegration.cpp b/desktopintegration.cpp index f23a1a7f..a63a6689 100644 --- a/desktopintegration.cpp +++ b/desktopintegration.cpp @@ -74,6 +74,26 @@ QString DesktopIntegration::backgroundUrl() const return QString("image://blurhash/%1").arg(m_appearanceIntegration->wallpaperBlurhash()); } +bool DesktopIntegration::isDockedApp(const QString &desktopId) const +{ + // This is something we shouldn't do but anyway... + const QString & fullPath = AppInfo::fullPathByDesktopId(desktopId); + // Seems QML's list type doesn't have a contains() method... + return m_dockIntegration->isDocked(fullPath); +} + +void DesktopIntegration::sendToDock(const QString &desktopId) +{ + const QString & fullPath = AppInfo::fullPathByDesktopId(desktopId); + return m_dockIntegration->sendToDock(fullPath); +} + +void DesktopIntegration::removeFromDock(const QString &desktopId) +{ + const QString & fullPath = AppInfo::fullPathByDesktopId(desktopId); + return m_dockIntegration->removeFromDock(fullPath); +} + DesktopIntegration::DesktopIntegration(QObject *parent) : QObject(parent) , m_dockIntegration(new DdeDock(this)) diff --git a/desktopintegration.h b/desktopintegration.h index 9fe42833..73256885 100644 --- a/desktopintegration.h +++ b/desktopintegration.h @@ -35,6 +35,10 @@ class DesktopIntegration : public QObject QRect dockGeometry() const; QString backgroundUrl() const; + Q_INVOKABLE bool isDockedApp(const QString & desktopId) const; + Q_INVOKABLE void sendToDock(const QString & desktopId); + Q_INVOKABLE void removeFromDock(const QString & desktopId); + signals: void dockPositionChanged(); void dockGeometryChanged(); diff --git a/qml/AppItemMenu.qml b/qml/AppItemMenu.qml index 72775d52..70f77cf8 100644 --- a/qml/AppItemMenu.qml +++ b/qml/AppItemMenu.qml @@ -18,8 +18,10 @@ Loader { signal closed() Component { - id: contextMenu + id: contextMenuComp + Menu { + id: contextMenu MenuItem { text: qsTr("Open") onTriggered: { @@ -46,12 +48,21 @@ Loader { } MenuSeparator {} MenuItem { text: true ? qsTr("Send to desktop") : qsTr("Remove from desktop") } - MenuItem { text: true ? qsTr("Send to dock") : qsTr("Remove from dock") } + MenuItem { + text: DesktopIntegration.isDockedApp(appItem.desktopId) ? qsTr("Remove from dock") : qsTr("Send to dock") + onTriggered: { + if (DesktopIntegration.isDockedApp(appItem.desktopId)) { + DesktopIntegration.removeFromDock(appItem.desktopId); + } else { + DesktopIntegration.sendToDock(appItem.desktopId); + } + } + } MenuSeparator {} MenuItem { text: true ? qsTr("Add to startup") : qsTr("Remove from startup") } MenuItem { text: qsTr("Use a proxy") } MenuItem { - enabled: !AppsModel.appIsCompulsoryForDesktop(appItem.desktopId) + enabled: !DesktopIntegration.appIsCompulsoryForDesktop(appItem.desktopId) text: qsTr("Uninstall") } @@ -63,7 +74,7 @@ Loader { } asynchronous: true - sourceComponent: contextMenu + sourceComponent: contextMenuComp function popup() { active = true; diff --git a/qml/Main.qml b/qml/Main.qml index 9d6908f3..71ede55c 100644 --- a/qml/Main.qml +++ b/qml/Main.qml @@ -14,6 +14,8 @@ import org.deepin.launchpad 1.0 ApplicationWindow { id: root + property bool isMenuShown: false + // title: activeFocusItem + " " + (activeFocusItem ? activeFocusItem.Accessible.name : "") width: 780 height: 600 @@ -44,7 +46,7 @@ ApplicationWindow { } onActiveChanged: { - if (!active) { + if (!active && !isMenuShown) { delayHideTimer.running = true } } @@ -71,8 +73,12 @@ ApplicationWindow { isFavoriteItem: isFavoriteItem, hideFavoriteMenu: hideFavoriteMenu }); - // menu.closed.connect(function() { /**/ }); + menu.closed.connect(function() { + root.isMenuShown = false + root.requestActivate() + }); menu.popup(); + root.isMenuShown = true } function updateWindowVisibilityAndPosition() { diff --git a/src/ddeintegration/ddedock.cpp b/src/ddeintegration/ddedock.cpp index 055276a6..708f2627 100644 --- a/src/ddeintegration/ddedock.cpp +++ b/src/ddeintegration/ddedock.cpp @@ -39,6 +39,29 @@ QRect DdeDock::geometry() const return m_rect; } +bool DdeDock::isDocked(const QString &desktop) const +{ + QDBusPendingReply reply(m_dbusDaemonDockIface->IsDocked(desktop)); + reply.waitForFinished(); + + if (reply.isError()) { + qDebug() << reply.error(); + return false; + } + + return reply.value(); +} + +void DdeDock::sendToDock(const QString &desktop, int idx) +{ + m_dbusDaemonDockIface->RequestDock(desktop, idx); +} + +void DdeDock::removeFromDock(const QString &desktop) +{ + m_dbusDaemonDockIface->RequestUndock(desktop); +} + void DdeDock::updateDockRectAndPositionFromDBus() { updateDockPositionFromDBus(); diff --git a/src/ddeintegration/ddedock.h b/src/ddeintegration/ddedock.h index f40b3506..80221e85 100644 --- a/src/ddeintegration/ddedock.h +++ b/src/ddeintegration/ddedock.h @@ -22,6 +22,10 @@ class DdeDock : public QObject Qt::ArrowType direction() const; QRect geometry() const; + bool isDocked(const QString & desktop) const; + void sendToDock(const QString & desktop, int idx = -1); + void removeFromDock(const QString & desktop); + signals: void directionChanged(); void geometryChanged(); diff --git a/src/gioutils/appinfo.cpp b/src/gioutils/appinfo.cpp index 0ced87ec..ac1460b3 100644 --- a/src/gioutils/appinfo.cpp +++ b/src/gioutils/appinfo.cpp @@ -19,3 +19,13 @@ bool AppInfo::launchByDesktopId(const QString &desktopId) return true; } + +QString AppInfo::fullPathByDesktopId(const QString &desktopId) +{ + GDesktopAppInfo * appInfo = g_desktop_app_info_new(desktopId.toStdString().c_str()); + if (!appInfo) return QString(); + + const char * filePath = g_desktop_app_info_get_filename(appInfo); + + return QString::fromUtf8(filePath); +} diff --git a/src/gioutils/appinfo.h b/src/gioutils/appinfo.h index d2604f73..1911602d 100644 --- a/src/gioutils/appinfo.h +++ b/src/gioutils/appinfo.h @@ -10,4 +10,5 @@ class AppInfo { public: static bool launchByDesktopId(const QString & desktopId); + static QString fullPathByDesktopId(const QString & desktopId); };