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>bb10
parent
b4c8e15174
commit
fb69a09a24
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue