From ca6eaf461886142256dfa64a761fc650be2b006f Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 22 Apr 2010 01:54:43 +0200 Subject: When using Qt::BypassGraphicsProxyWidget with QMenu the application is not stuck anymore When using this flag the child of the widget which is embedded is becoming a top level QWidget. So a right click on a text edit trigger the context menu to be top level. When creating this top level context menu we are grabbing the mouse but we were never releasing it when the menu was hidden. The patch check if the widget uses the Qt::BypassGraphicsProxyWidget and ungrab the mouse. The patch also fix a bug when positioning the QMenu, it was for the same reason. Task-number:QTBUG-7254 Reviewed-by:brad --- src/gui/graphicsview/qgraphicsproxywidget.cpp | 11 ++++++++++- src/gui/kernel/qwidget.cpp | 2 +- src/gui/widgets/qmenu.cpp | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index ad7cf5d..1f89714 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -1024,9 +1024,18 @@ void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *even // Map event position from us to the receiver pos = d->mapToReceiver(pos, receiver); + QPoint globalPos = receiver->mapToGlobal(pos.toPoint()); + //If the receiver by-pass the proxy its popups + //will be top level QWidgets therefore they need + //the screen position. mapToGlobal expect the widget to + //have proper coordinates in regards of the windowing system + //but it's not true because the widget is embedded. + if (bypassGraphicsProxyWidget(receiver)) + globalPos = event->screenPos(); + // Send mouse event. ### Doesn't propagate the event. QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()), - pos.toPoint(), receiver->mapToGlobal(pos.toPoint()), event->modifiers()); + pos.toPoint(), globalPos, event->modifiers()); QApplication::sendEvent(receiver, &contextMenuEvent); event->setAccepted(contextMenuEvent.isAccepted()); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 046bc7f..441e823 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -7322,7 +7322,7 @@ void QWidgetPrivate::hide_helper() bool isEmbedded = false; #if !defined QT_NO_GRAPHICSVIEW - isEmbedded = q->isWindow() && nearestGraphicsProxyWidget(q->parentWidget()) != 0; + isEmbedded = q->isWindow() && !bypassGraphicsProxyWidget(q) && nearestGraphicsProxyWidget(q->parentWidget()) != 0; #else Q_UNUSED(isEmbedded); #endif diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index f9b132e..907dd14 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1834,7 +1834,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction) QSize size = sizeHint(); QRect screen; #ifndef QT_NO_GRAPHICSVIEW - bool isEmbedded = d->nearestGraphicsProxyWidget(this); + bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this); if (isEmbedded) screen = d->popupGeometry(this); else -- cgit v0.12