diff --git a/src/frameworkdbus/dbusxeventmonitor.cpp b/src/frameworkdbus/dbusxeventmonitor.cpp new file mode 100644 index 0000000..8584c8b --- /dev/null +++ b/src/frameworkdbus/dbusxeventmonitor.cpp @@ -0,0 +1,73 @@ +/* + * This file was generated by qdbusxml2cpp-fix version 0.8 + * Command line was: qdbusxml2cpp-fix -c org_deepin_api_XEventMonitor -p /home/donghl/work/code/dde-dock/frame/dbusinterface/generation_dbus_interface/org_deepin_api_xeventmonitor /home/donghl/work/code/dde-dock/frame/dbusinterface/xml/org.deepin.api.XEventMonitor.xml + * + * qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusxeventmonitor.h" + +/* + * Implementation of interface class __org_deepin_api_XEventMonitor + */ + +class __org_deepin_api_XEventMonitorPrivate +{ +public: + __org_deepin_api_XEventMonitorPrivate() = default; + + // begin member variables + +public: + QMap m_processingCalls; + QMap> m_waittingCalls; +}; + +__org_deepin_api_XEventMonitor::__org_deepin_api_XEventMonitor(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent) + , d_ptr(new __org_deepin_api_XEventMonitorPrivate) +{ + if (QMetaType::type("AreaList") == QMetaType::UnknownType) + registerAreaListMetaType(); +} + +__org_deepin_api_XEventMonitor::~__org_deepin_api_XEventMonitor() +{ + qDeleteAll(d_ptr->m_processingCalls.values()); + delete d_ptr; +} + +void __org_deepin_api_XEventMonitor::CallQueued(const QString &callName, const QList &args) +{ + if (d_ptr->m_waittingCalls.contains(callName)) { + d_ptr->m_waittingCalls[callName] = args; + return; + } + if (d_ptr->m_processingCalls.contains(callName)) { + d_ptr->m_waittingCalls.insert(callName, args); + } else { + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args)); + connect(watcher, &QDBusPendingCallWatcher::finished, this, &__org_deepin_api_XEventMonitor::onPendingCallFinished); + d_ptr->m_processingCalls.insert(callName, watcher); + } +} + +void __org_deepin_api_XEventMonitor::onPendingCallFinished(QDBusPendingCallWatcher *w) +{ + w->deleteLater(); + const auto callName = d_ptr->m_processingCalls.key(w); + Q_ASSERT(!callName.isEmpty()); + if (callName.isEmpty()) + return; + + d_ptr->m_processingCalls.remove(callName); + if (!d_ptr->m_waittingCalls.contains(callName)) + return; + + const auto args = d_ptr->m_waittingCalls.take(callName); + CallQueued(callName, args); +} diff --git a/src/frameworkdbus/dbusxeventmonitor.h b/src/frameworkdbus/dbusxeventmonitor.h new file mode 100644 index 0000000..501fad3 --- /dev/null +++ b/src/frameworkdbus/dbusxeventmonitor.h @@ -0,0 +1,101 @@ +/* + * This file was generated by qdbusxml2cpp-fix version 0.8 + * Command line was: qdbusxml2cpp-fix -c org_deepin_api_XEventMonitor -p /home/donghl/work/code/dde-dock/frame/dbusinterface/generation_dbus_interface/org_deepin_api_xeventmonitor /home/donghl/work/code/dde-dock/frame/dbusinterface/xml/org.deepin.api.XEventMonitor.xml + * + * qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef ORG_DEEPIN_API_XEVENTMONITOR_H +#define ORG_DEEPIN_API_XEVENTMONITOR_H + +#include "types/arealist.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface org.deepin.api.XEventMonitor1 + */ +class __org_deepin_api_XEventMonitorPrivate; +class __org_deepin_api_XEventMonitor : public DBusExtendedAbstractInterface +{ + Q_OBJECT + +public: + static inline const char *staticInterfaceName() + { return "org.deepin.api.XEventMonitor1"; } + +public: + explicit __org_deepin_api_XEventMonitor(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~__org_deepin_api_XEventMonitor(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply RegisterArea(int in0, int in1, int in2, int in3, int in4) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3) << QVariant::fromValue(in4); + return asyncCallWithArgumentList(QStringLiteral("RegisterArea"), argumentList); + } + + inline QDBusPendingReply RegisterAreas(AreaList in0, int in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QStringLiteral("RegisterAreas"), argumentList); + } + + inline QDBusPendingReply RegisterFullScreen() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("RegisterFullScreen"), argumentList); + } + + inline QDBusPendingReply UnregisterArea(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("UnregisterArea"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void ButtonPress(int in0, int in1, int in2, const QString &in3); + void ButtonRelease(int in0, int in1, int in2, const QString &in3); + void CancelAllArea(); + void CursorInto(int in0, int in1, const QString &in2); + void CursorMove(int in0, int in1, const QString &in2); + void CursorOut(int in0, int in1, const QString &in2); + void KeyPress(const QString &in0, int in1, int in2, const QString &in3); + void KeyRelease(const QString &in0, int in1, int in2, const QString &in3); + // begin property changed signals + +public Q_SLOTS: + void CallQueued(const QString &callName, const QList &args); + +private Q_SLOTS: + void onPendingCallFinished(QDBusPendingCallWatcher *w); + +private: + __org_deepin_api_XEventMonitorPrivate *d_ptr; +}; + +namespace org { + namespace deepin { + namespace api { + typedef ::__org_deepin_api_XEventMonitor XEventMonitor1; + } + } +} + +#endif diff --git a/src/frameworkdbus/types/arealist.cpp b/src/frameworkdbus/types/arealist.cpp new file mode 100644 index 0000000..e4055ad --- /dev/null +++ b/src/frameworkdbus/types/arealist.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 ~ 2017 Deepin Technology Co., Ltd. + * + * Author: sbw + * kirigaya + * Hualet + * + * Maintainer: sbw + * kirigaya + * Hualet + * zhaolong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "arealist.h" + +bool MonitRect::operator ==(const MonitRect &rect) +{ + return x1 == rect.x1 && y1 == rect.y1 && x2 == rect.x2 && y2 == rect.y2; +} + +QDBusArgument &operator<<(QDBusArgument &arg, const MonitRect &rect) +{ + arg.beginStructure(); + arg << rect.x1 << rect.y1 << rect.x2 << rect.y2; + arg.endStructure(); + + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, MonitRect &rect) +{ + arg.beginStructure(); + arg >> rect.x1 >> rect.y1 >> rect.x2 >> rect.y2; + arg.endStructure(); + + return arg; +} + +void registerAreaListMetaType() +{ + qRegisterMetaType("MonitRect"); + qDBusRegisterMetaType(); + + qRegisterMetaType("AreaList"); + qDBusRegisterMetaType(); +} diff --git a/src/frameworkdbus/types/arealist.h b/src/frameworkdbus/types/arealist.h new file mode 100644 index 0000000..be61f02 --- /dev/null +++ b/src/frameworkdbus/types/arealist.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 ~ 2017 Deepin Technology Co., Ltd. + * + * Author: sbw + * kirigaya + * Hualet + * + * Maintainer: sbw + * kirigaya + * Hualet + * zhaolong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef AREALIST_H +#define AREALIST_H + +#include +#include +#include + +struct MonitRect { + int x1; + int y1; + int x2; + int y2; + + bool operator ==(const MonitRect& rect); +}; + +typedef QList AreaList; + +Q_DECLARE_METATYPE(MonitRect) +Q_DECLARE_METATYPE(AreaList) + +QDBusArgument &operator<<(QDBusArgument &arg, const MonitRect &rect); +const QDBusArgument &operator>>(const QDBusArgument &arg, MonitRect &rect); + +void registerAreaListMetaType(); + +#endif // AREALIST_H diff --git a/src/modules/dock/dbushandler.cpp b/src/modules/dock/dbushandler.cpp index ac066d1..73ba6ba 100644 --- a/src/modules/dock/dbushandler.cpp +++ b/src/modules/dock/dbushandler.cpp @@ -33,6 +33,7 @@ DBusHandler::DBusHandler(Dock *_dock, QObject *parent) , m_wm(new com::deepin::WM("com.deepin.wm", "/com/deepin/wm", m_session, this)) , m_wmSwitcher(new com::deepin::WMSwitcher("com.deepin.wmWMSwitcher", "/com/deepin/WMSwitcher", m_session, this)) , m_kwaylandManager(nullptr) + , m_xEventMonitor(nullptr) { // 关联org.deepin.dde.daemon.Launcher1事件 ItemChanged connect(m_launcherEnd, &LauncherBackEnd::ItemChanged, this, &DBusHandler::handleLauncherItemChanged); @@ -45,6 +46,14 @@ DBusHandler::DBusHandler(Dock *_dock, QObject *parent) // 关联com.deepin.WMSwitcher事件 WMChanged connect(m_wmSwitcher, &__WMSwitcher::WMChanged, this, [&](QString name) {m_dock->setWMName(name);}); + + if (QString(getenv("XDG_SESSION_TYPE")).contains("wayland")) { + m_xEventMonitor = new org::deepin::api::XEventMonitor1("org.deepin.api.XEventMonitor1", "/org/deepin/api/XEventMonitor1", m_session, this); + // 注册XEventMonitor区域为整个屏幕的区域 + m_activeWindowMonitorKey = m_xEventMonitor->RegisterFullScreen(); + // 关联XEventMonitor的ButtonRelease事件 + connect(m_xEventMonitor, &org::deepin::api::XEventMonitor1::ButtonRelease, this, &DBusHandler::onActiveWindowButtonRelease); + } } // 关联com.deepin.daemon.KWayland.WindowManager事件 @@ -138,15 +147,34 @@ void DBusHandler::handleWlActiveWindowChange() WindowInfoK *info = m_dock->handleActiveWindowChangedK(activeWinInternalId); if (info && info->getXid() != 0) { - WindowInfoBase *base = static_cast(info); - if (base) { - m_dock->handleActiveWindowChanged(base); - } + m_dock->handleActiveWindowChanged(info); } else { m_dock->updateHideState(false); } } +void DBusHandler::onActiveWindowButtonRelease(int type, int x, int y, const QString &key) +{ + // 当鼠标松开区域事件的时候,取消注册,同时调用激活窗口的方法来触发智能隐藏的相关信号 + if (key != m_activeWindowMonitorKey) + return; + + uint activeWinInternalId = wlActiveWindow(); + if (activeWinInternalId == 0) + return; + + WindowInfoK *info = m_dock->handleActiveWindowChangedK(activeWinInternalId); + if (!info) + return; + + // 如果是在当前激活窗口区域内释放的,则触发检测智能隐藏的方法 + DockRect dockRect = info->getGeometry(); + if (dockRect.X <= x && x <= dockRect.X + dockRect.Width && dockRect.Y <= y && y <= dockRect.Y + dockRect.Height) { + // 取消智能隐藏 + m_dock->updateHideState(false); + } +} + void DBusHandler::listenKWindowSignals(WindowInfoK *windowInfo) { PlasmaWindow *window = windowInfo->getPlasmaWindow(); diff --git a/src/modules/dock/dbushandler.h b/src/modules/dock/dbushandler.h index 196a209..6205f48 100644 --- a/src/modules/dock/dbushandler.h +++ b/src/modules/dock/dbushandler.h @@ -29,6 +29,7 @@ #include "dbuskwaylandwindowmanager.h" #include "windowinfok.h" #include "dbusplasmawindow.h" +#include "dbusxeventmonitor.h" #include #include @@ -76,6 +77,7 @@ public: private Q_SLOTS: void handleWlActiveWindowChange(); + void onActiveWindowButtonRelease(int type, int x, int y, const QString &key); private: Dock *m_dock; @@ -86,6 +88,9 @@ private: com::deepin::WM *m_wm; com::deepin::WMSwitcher *m_wmSwitcher; com::deepin::daemon::kwayland::WindowManager *m_kwaylandManager; + + org::deepin::api::XEventMonitor1 *m_xEventMonitor; + QString m_activeWindowMonitorKey; }; #endif // DBUSHANDLER_H diff --git a/src/modules/dock/dock.cpp b/src/modules/dock/dock.cpp index eab093e..0e44324 100644 --- a/src/modules/dock/dock.cpp +++ b/src/modules/dock/dock.cpp @@ -896,13 +896,13 @@ bool Dock::hasInterSectionK(const DockRect &windowRect, QRect dockRect) int rbX = MIN(windowRect.X + windowRect.Width, dockRect.x() + dockRect.width()); int rbY = MIN(windowRect.Y + windowRect.Height, dockRect.y() + dockRect.height()); - if (position == int(PositionMode::Left) || position == int(PositionMode::Right)) { + if (position == int(PositionMode::Left) || position == int(PositionMode::Right)) return ltX <= rbX && ltY < rbY; - } else if (position == int(PositionMode::Top) || position == int(PositionMode::Bottom)) { + + if (position == int(PositionMode::Top) || position == int(PositionMode::Bottom)) return ltX < rbX && ltY <= rbY; - } else { - return ltX < rbX && ltY < rbY; - } + + return ltX < rbX && ltY < rbY; } /** @@ -1213,7 +1213,7 @@ bool Dock::isWaylandEnv() */ WindowInfoK *Dock::handleActiveWindowChangedK(uint activeWin) { - return m_waylandManager->handleActiveWindowChangedK(activeWin); + return m_waylandManager->findWindowById(activeWin); } /** diff --git a/src/modules/dock/waylandmanager.cpp b/src/modules/dock/waylandmanager.cpp index 2dec2ce..2052e2a 100644 --- a/src/modules/dock/waylandmanager.cpp +++ b/src/modules/dock/waylandmanager.cpp @@ -82,18 +82,16 @@ void WaylandManager::unRegisterWindow(const QString &objPath) deleteWindow(objPath); } -WindowInfoK *WaylandManager::handleActiveWindowChangedK(uint activeWin) +WindowInfoK *WaylandManager::findWindowById(uint activeWin) { - WindowInfoK *winInfo = nullptr; QMutexLocker locker(&m_mutex); for (auto iter = m_kWinInfos.begin(); iter != m_kWinInfos.end(); iter++) { - if (iter.value()->getInnerId() == activeWin) { - winInfo = iter.value(); - break; + if (iter.value()->getInnerId() == QString::number(activeWin)) { + return iter.value(); } } - return winInfo; + return nullptr; } WindowInfoK *WaylandManager::findWindowByXid(XWindow xid) diff --git a/src/modules/dock/waylandmanager.h b/src/modules/dock/waylandmanager.h index de3986d..d5bf05b 100644 --- a/src/modules/dock/waylandmanager.h +++ b/src/modules/dock/waylandmanager.h @@ -40,7 +40,7 @@ public: void registerWindow(const QString &objPath); void unRegisterWindow(const QString &objPath); - WindowInfoK *handleActiveWindowChangedK(uint activeWin); + WindowInfoK *findWindowById(uint activeWin); WindowInfoK *findWindowByXid(XWindow xid); WindowInfoK *findWindowByObjPath(QString objPath); void insertWindow(QString objPath, WindowInfoK *windowInfo); diff --git a/src/modules/dock/windowinfobase.h b/src/modules/dock/windowinfobase.h index db92049..e2519bc 100644 --- a/src/modules/dock/windowinfobase.h +++ b/src/modules/dock/windowinfobase.h @@ -30,6 +30,7 @@ class Entry; class AppInfo; class ProcessInfo; + class WindowInfoBase { public: @@ -56,17 +57,17 @@ public: virtual void update() = 0; virtual void killClient() = 0; virtual QString uuid() = 0; + virtual QString getInnerId() { return innerId; } XWindow getXid() {return xid;} - void setEntry(Entry *value) {entry = value;} - Entry *getEntry() {return entry;} - QString getEntryInnerId() {return entryInnerId;} - QString getInnerId() {return innerId;} - void setEntryInnerId(QString value) {entryInnerId = value;} - AppInfo *getAppInfo() {return app;} - void setAppInfo(AppInfo *value) {app = value;} - int getPid() {return pid;} - ProcessInfo *getProcess() {return processInfo;} + void setEntry(Entry *value) { entry = value; } + Entry *getEntry() { return entry; } + QString getEntryInnerId() { return entryInnerId; } + void setEntryInnerId(QString value) { entryInnerId = value; } + AppInfo *getAppInfo() { return app; } + void setAppInfo(AppInfo *value) { app = value; } + int getPid() { return pid; } + ProcessInfo *getProcess() { return processInfo; } bool containAtom(QVector supports, XCBAtom ty) {return supports.indexOf(ty) != -1;} protected: diff --git a/src/modules/dock/windowinfok.cpp b/src/modules/dock/windowinfok.cpp index 6ed466a..165eb1b 100644 --- a/src/modules/dock/windowinfok.cpp +++ b/src/modules/dock/windowinfok.cpp @@ -222,3 +222,8 @@ QString WindowInfoK::uuid() return QString(m_plasmaWindow->Uuid()); } +QString WindowInfoK::getInnerId() +{ + return QString::number(m_internalId); +} + diff --git a/src/modules/dock/windowinfok.h b/src/modules/dock/windowinfok.h index 53225ab..fbe1b45 100644 --- a/src/modules/dock/windowinfok.h +++ b/src/modules/dock/windowinfok.h @@ -52,6 +52,7 @@ public: virtual void update() override; virtual void killClient() override; virtual QString uuid() override; + QString getInnerId() override; QString getAppId(); void setAppId(QString _appId);