From 230a15d4759c18454d37d6da4c6193b2c04cbfd6 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 7 Jun 2011 18:11:30 +0200 Subject: [PATCH] correctly manage popup menus similar fix in the taskbar coming --- declarativeimports/core/dialog.cpp | 34 +++++++++++++++++++++++++++--- declarativeimports/core/dialog.h | 2 ++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/declarativeimports/core/dialog.cpp b/declarativeimports/core/dialog.cpp index 831c0bdb3..cd84c8fb2 100644 --- a/declarativeimports/core/dialog.cpp +++ b/declarativeimports/core/dialog.cpp @@ -30,7 +30,8 @@ DialogProxy::DialogProxy(QObject *parent) - : QObject(parent) + : QObject(parent), + m_isPopupMenu(false) { m_dialog = new Plasma::Dialog(); m_dialog->installEventFilter(this); @@ -117,11 +118,21 @@ void DialogProxy::setVisible(const bool visible) if (visible) { m_dialog->setWindowFlags(m_flags); m_dialog->raise(); + if (m_isPopupMenu && QWidget::mouseGrabber() != m_dialog) { + QTimer::singleShot(200, this, SLOT(syncGrab())); + } } emit visibleChanged(); } } +void DialogProxy::syncGrab() +{ + if (m_isPopupMenu) { + m_dialog->grabMouse(); + } +} + QPoint DialogProxy::popupPosition(QGraphicsObject *item) const { Plasma::Corona *corona = qobject_cast(item->scene()); @@ -192,13 +203,30 @@ bool DialogProxy::eventFilter(QObject *watched, QEvent *event) if (re->oldSize().height() != re->size().height()) { emit heightChanged(); } - } + } else if (watched == m_dialog && event->type() == QEvent::Hide) { + m_dialog->releaseMouse(); + } else if (watched == m_dialog && event->type() == QEvent::MouseButtonPress) { + if (m_isPopupMenu) { + QMouseEvent *me = static_cast(event); + if (!m_dialog->geometry().contains(me->globalPos())) { + m_dialog->releaseMouse(); + setVisible(false); + } + } + } return false; } void DialogProxy::setAttribute(int attribute, bool on) { - m_dialog->setAttribute((Qt::WidgetAttribute)attribute, on); + Qt::WidgetAttribute attr = (Qt::WidgetAttribute)attribute; + if (attr == Qt::WA_X11NetWmWindowTypePopupMenu) { + m_isPopupMenu = on; + if (m_isPopupMenu && QWidget::mouseGrabber() != m_dialog) { + QTimer::singleShot(200, this, SLOT(syncGrab())); + } + } + m_dialog->setAttribute(attr, on); } #include "dialog.moc" diff --git a/declarativeimports/core/dialog.h b/declarativeimports/core/dialog.h index e86fffc76..8a7eb4492 100644 --- a/declarativeimports/core/dialog.h +++ b/declarativeimports/core/dialog.h @@ -86,6 +86,7 @@ Q_SIGNALS: protected Q_SLOTS: void syncMainItem(); + void syncGrab(); protected: bool eventFilter(QObject *watched, QEvent *event); @@ -95,6 +96,7 @@ private: Qt::WindowFlags m_flags; DeclarativeItemContainer *m_declarativeItemContainer; QWeakPointer m_mainItem; + bool m_isPopupMenu; }; #endif