summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-11-24 13:49:44 +0100
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-11-27 22:50:17 +0000
commitfb69a09a2490102ad0c3f6015e04942bb5df7505 (patch)
tree1f086e8f21cb2b312098850b7b602c2fe45776c1
parentb4c8e1517455becb138876c08b3bdd880a80770d (diff)
QWidget::mapTo/FromGlobal(): Avoid calling QWindow helpers until shown.
The platform window geometry can be misleading until it has been properly positioned and QWindowPrivate::resizeEventPending has been cleared. Task-number: QTBUG-49588 Task-number: QTBUG-48396 Change-Id: Ie065f62478fc8522a9ad51391bb897510afa5aad Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
-rw-r--r--src/widgets/kernel/qwidget.cpp10
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp56
2 files changed, 64 insertions, 2 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index b8b8640cea..229cfc0f85 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -12327,6 +12327,12 @@ QPaintEngine *QWidget::paintEngine() const
return 0; //##### @@@
}
+// Do not call QWindow::mapToGlobal() until QPlatformWindow is properly showing.
+static inline bool canMapPosition(QWindow *window)
+{
+ return window->handle() && !qt_window_private(window)->resizeEventPending;
+}
+
/*!
\fn QPoint QWidget::mapToGlobal(const QPoint &pos) const
@@ -12354,7 +12360,7 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const
#endif // !QT_NO_GRAPHICSVIEW
QWindow *window = w->windowHandle();
- if (window && window->handle())
+ if (window && canMapPosition(window))
return window->mapToGlobal(QPoint(x, y));
x += w->data->crect.x();
@@ -12390,7 +12396,7 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const
#endif // !QT_NO_GRAPHICSVIEW
QWindow *window = w->windowHandle();
- if (window && window->handle())
+ if (window && canMapPosition(window))
return window->mapFromGlobal(QPoint(x, y));
x -= w->data->crect.x();
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index 5ae0733965..b3f9c54f24 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -94,6 +94,7 @@ private slots:
void task208001_stylesheet();
void activeSubMenuPosition();
+ void activeSubMenuPositionExec();
void task242454_sizeHint();
void task176201_clear();
void task250673_activeMultiColumnSubMenuPosition();
@@ -694,6 +695,61 @@ void tst_QMenu::activeSubMenuPosition()
#endif
}
+// QTBUG-49588, QTBUG-48396: activeSubMenuPositionExec() is the same as
+// activeSubMenuPosition(), but uses QMenu::exec(), which produces a different
+// sequence of events. Verify that the sub menu is positioned to the right of the
+// main menu.
+class SubMenuPositionExecMenu : public QMenu
+{
+ Q_OBJECT
+public:
+ SubMenuPositionExecMenu() : QMenu("Menu-Title"), m_timerId(-1), m_timerTick(0)
+ {
+ addAction("Item 1");
+ m_subMenu = addMenu("Submenu");
+ m_subAction = m_subMenu->addAction("Sub-Item1");
+ setActiveAction(m_subMenu->menuAction());
+ }
+
+protected:
+ void showEvent(QShowEvent *e) Q_DECL_OVERRIDE
+ {
+ QVERIFY(m_subMenu->isVisible());
+ QVERIFY2(m_subMenu->x() > x(),
+ (QByteArray::number(m_subMenu->x()) + ' ' + QByteArray::number(x())).constData());
+ m_timerId = startTimer(50);
+ QMenu::showEvent(e);
+ }
+
+ void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE
+ {
+ if (e->timerId() == m_timerId) {
+ switch (m_timerTick++) {
+ case 0:
+ m_subMenu->close();
+ break;
+ case 1:
+ close();
+ break;
+ }
+ }
+ }
+
+private:
+ int m_timerId;
+ int m_timerTick;
+ QMenu *m_subMenu;
+ QAction *m_subAction;
+};
+
+void tst_QMenu::activeSubMenuPositionExec()
+{
+#ifndef Q_OS_WINCE
+ SubMenuPositionExecMenu menu;
+ menu.exec(QGuiApplication::primaryScreen()->availableGeometry().center());
+#endif // !Q_OS_WINCE
+}
+
void tst_QMenu::task242454_sizeHint()
{
QMenu menu;