diff --git a/frame/dbus/dbusxmousearea.cpp b/frame/dbus/dbusxmousearea.cpp new file mode 100644 index 000000000..7b976a9d6 --- /dev/null +++ b/frame/dbus/dbusxmousearea.cpp @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2015 Deepin Technology Co., Ltd. + * + * 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 + * (at your option) any later version. + **/ + +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c DBusXMouseArea -p dbusxmousearea com.deepin.api.XMouseArea.xml + * + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusxmousearea.h" + +/* + * Implementation of interface class DBusXMouseArea + */ + +DBusXMouseArea::DBusXMouseArea(QObject *parent) + : QDBusAbstractInterface("com.deepin.api.XMouseArea", "/com/deepin/api/XMouseArea", staticInterfaceName(), QDBusConnection::sessionBus(), parent) +{ + QDBusConnection::sessionBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage))); +} + +DBusXMouseArea::~DBusXMouseArea() +{ + QDBusConnection::sessionBus().disconnect(service(), path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(propertyChanged(QDBusMessage))); +} + diff --git a/frame/dbus/dbusxmousearea.h b/frame/dbus/dbusxmousearea.h new file mode 100644 index 000000000..169ccffcf --- /dev/null +++ b/frame/dbus/dbusxmousearea.h @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2015 Deepin Technology Co., Ltd. + * + * 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 + * (at your option) any later version. + **/ + +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c DBusXMouseArea -p dbusxmousearea com.deepin.api.XMouseArea.xml + * + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef DBUSXMOUSEAREA_H_1441764668 +#define DBUSXMOUSEAREA_H_1441764668 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.api.XMouseArea + */ +class DBusXMouseArea: public QDBusAbstractInterface +{ + Q_OBJECT + + Q_SLOT void __propertyChanged__(const QDBusMessage &msg) + { + QList arguments = msg.arguments(); + if (3 != arguments.count()) { + return; + } + QString interfaceName = msg.arguments().at(0).toString(); + if (interfaceName != "com.deepin.api.XMouseArea") { + return; + } + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + QStringList keys = changedProps.keys(); + foreach(const QString & prop, keys) { + const QMetaObject *self = metaObject(); + for (int i = self->propertyOffset(); i < self->propertyCount(); ++i) { + QMetaProperty p = self->property(i); + if (p.name() == prop) { + Q_EMIT p.notifySignal().invoke(this); + } + } + } + } +public: + static inline const char *staticInterfaceName() + { + return "com.deepin.api.XMouseArea"; + } + +public: + explicit DBusXMouseArea(QObject *parent = 0); + + ~DBusXMouseArea(); + +public Q_SLOTS: // METHODS + 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 ButtonRelease(int in0, int in1, int in2, const QString &in3); +// begin property changed signals +}; + +namespace com +{ +namespace deepin +{ +namespace api +{ +typedef ::DBusXMouseArea XMouseArea; +} +} +} +#endif diff --git a/frame/frame.pro b/frame/frame.pro index 585e43201..1d6dbcbc6 100644 --- a/frame/frame.pro +++ b/frame/frame.pro @@ -30,7 +30,8 @@ SOURCES += main.cpp \ item/pluginsitem.cpp \ controller/dockpluginscontroller.cpp \ util/imagefactory.cpp \ - util/dockpopupwindow.cpp + util/dockpopupwindow.cpp \ + dbus/dbusxmousearea.cpp HEADERS += \ window/mainwindow.h \ @@ -52,7 +53,8 @@ HEADERS += \ item/pluginsitem.h \ controller/dockpluginscontroller.h \ util/imagefactory.h \ - util/dockpopupwindow.h + util/dockpopupwindow.h \ + dbus/dbusxmousearea.h dbus_service.files += com.deepin.dde.dock.service dbus_service.path = /usr/share/dbus-1/services diff --git a/frame/item/dockitem.cpp b/frame/item/dockitem.cpp index 11f16c72d..e260dca2f 100644 --- a/frame/item/dockitem.cpp +++ b/frame/item/dockitem.cpp @@ -179,7 +179,9 @@ void DockItem::showPopupWindow(QWidget * const content, const bool model) popup->setHeight(content->sizeHint().height()); const QPoint p = popupMarkPoint(); - popup->show(p, model); + QMetaObject::invokeMethod(popup, "show", Qt::QueuedConnection, Q_ARG(QPoint, p), Q_ARG(bool, model)); + + connect(popup, &DockPopupWindow::accept, this, &DockItem::popupWindowAccept); } void DockItem::popupWindowAccept() @@ -187,6 +189,8 @@ void DockItem::popupWindowAccept() if (!PopupWindow->isVisible()) return; + disconnect(PopupWindow.get(), &DockPopupWindow::accept, this, &DockItem::popupWindowAccept); + PopupWindow->hide(); emit requestWindowAutoHide(true); diff --git a/frame/item/pluginsitem.cpp b/frame/item/pluginsitem.cpp index 63d049705..7bc2c651f 100644 --- a/frame/item/pluginsitem.cpp +++ b/frame/item/pluginsitem.cpp @@ -51,16 +51,10 @@ void PluginsItem::detachPluginWidget() void PluginsItem::mousePressEvent(QMouseEvent *e) { - if (e->button() == Qt::LeftButton) - { - MousePressPoint = e->pos(); - } - else if (e->button() == Qt::RightButton) - { + DockItem::mousePressEvent(e); - } - else - DockItem::mousePressEvent(e); + if (e->button() == Qt::LeftButton) + MousePressPoint = e->pos(); } void PluginsItem::mouseMoveEvent(QMouseEvent *e) @@ -77,8 +71,10 @@ void PluginsItem::mouseMoveEvent(QMouseEvent *e) void PluginsItem::mouseReleaseEvent(QMouseEvent *e) { + DockItem::mouseReleaseEvent(e); + if (e->button() != Qt::LeftButton) - return DockItem::mouseReleaseEvent(e); + return; e->accept(); diff --git a/frame/util/dockpopupwindow.cpp b/frame/util/dockpopupwindow.cpp index 7d1d328d8..e774392d6 100644 --- a/frame/util/dockpopupwindow.cpp +++ b/frame/util/dockpopupwindow.cpp @@ -4,9 +4,17 @@ DWIDGET_USE_NAMESPACE DockPopupWindow::DockPopupWindow(QWidget *parent) : DArrowRectangle(ArrowBottom, parent), - m_model(false) -{ + m_model(false), + m_acceptDelayTimer(new QTimer(this)), + + m_mouseInter(new DBusXMouseArea(this)) +{ + m_acceptDelayTimer->setSingleShot(true); + m_acceptDelayTimer->setInterval(100); + + connect(m_acceptDelayTimer, &QTimer::timeout, this, &DockPopupWindow::accept); + connect(m_mouseInter, &DBusXMouseArea::ButtonRelease, this, &DockPopupWindow::globalMouseRelease); } bool DockPopupWindow::model() const @@ -19,4 +27,30 @@ void DockPopupWindow::show(const QPoint &pos, const bool model) m_model = model; DArrowRectangle::show(pos.x(), pos.y()); + + if (model) + m_mouseAreaKey = m_mouseInter->RegisterFullScreen(); +} + +void DockPopupWindow::mousePressEvent(QMouseEvent *e) +{ + DArrowRectangle::mousePressEvent(e); + + if (e->button() == Qt::LeftButton) + m_acceptDelayTimer->start(); +} + +void DockPopupWindow::globalMouseRelease() +{ + Q_ASSERT(m_model); + + const QRect rect = QRect(pos(), size()); + const QPoint pos = QCursor::pos(); + + if (rect.contains(pos)) + return; + + emit accept(); + + m_mouseInter->UnregisterArea(m_mouseAreaKey); } diff --git a/frame/util/dockpopupwindow.h b/frame/util/dockpopupwindow.h index 94f0054a8..e5e3c4b02 100644 --- a/frame/util/dockpopupwindow.h +++ b/frame/util/dockpopupwindow.h @@ -1,6 +1,8 @@ #ifndef DOCKPOPUPWINDOW_H #define DOCKPOPUPWINDOW_H +#include "dbus/dbusxmousearea.h" + #include class DockPopupWindow : public Dtk::Widget::DArrowRectangle @@ -12,10 +14,25 @@ public: bool model() const; +public slots: void show(const QPoint &pos, const bool model = false); +signals: + void accept() const; + +protected: + void mousePressEvent(QMouseEvent *e); + +private slots: + void globalMouseRelease(); + private: bool m_model; + QString m_mouseAreaKey; + + QTimer *m_acceptDelayTimer; + + DBusXMouseArea *m_mouseInter; }; #endif // DOCKPOPUPWINDOW_H diff --git a/plugins/system-tray/fashiontrayitem.cpp b/plugins/system-tray/fashiontrayitem.cpp index ec445bdd1..9c89fe48c 100644 --- a/plugins/system-tray/fashiontrayitem.cpp +++ b/plugins/system-tray/fashiontrayitem.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include #define DRAG_THRESHOLD 10 diff --git a/plugins/system-tray/traywidget.cpp b/plugins/system-tray/traywidget.cpp index 78a795dbb..2cca4093b 100644 --- a/plugins/system-tray/traywidget.cpp +++ b/plugins/system-tray/traywidget.cpp @@ -81,6 +81,8 @@ void TrayWidget::mousePressEvent(QMouseEvent *e) void TrayWidget::mouseReleaseEvent(QMouseEvent *e) { + QWidget::mouseReleaseEvent(e); + const QPoint distance = e->pos() - m_pressPoint; if (distance.manhattanLength() > DRAG_THRESHOLD) return;