Fix windows expose logic
Make sure the value of QWindowsWindow::isExposed is in sync with regions we expose. This provoked a couple of existing issues in the qwidget test. setWindowGeometry tested that windows with invalid sizes got exposed on screen. They didn't, but because the plugin sent bogus events, these used to pass. Same with windowMoveResize. The expect fails are also rather bogus. Showing invalid-size widgets could be considered undefined behavior. The Window manager could resize it, choose to not show it at all, etc, but they now pass on windows. resizeEvent has been broken since 5.0.0, but the test didn't spin the event loop so the second event didn't get delivered before the test completed. Task-number: QTBUG-30744 Change-Id: I3a9efcd095f366126a87739f4248185b6c81d407 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>bb10
parent
5c6e2882dd
commit
2e0575ce89
|
|
@ -842,9 +842,6 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
|
|||
case QtWindows::FocusOutEvent:
|
||||
handleFocusEvent(et, platformWindow);
|
||||
return true;
|
||||
case QtWindows::ShowEvent:
|
||||
platformWindow->handleShown();
|
||||
return false; // Indicate transient children should be shown by windows (SW_PARENTOPENING)
|
||||
case QtWindows::HideEvent:
|
||||
platformWindow->handleHidden();
|
||||
return false;// Indicate transient children should be hidden by windows (SW_PARENTCLOSING)
|
||||
|
|
|
|||
|
|
@ -839,6 +839,15 @@ QWindowsWindow::~QWindowsWindow()
|
|||
destroyIcon();
|
||||
}
|
||||
|
||||
void QWindowsWindow::fireExpose(const QRegion ®ion, bool force)
|
||||
{
|
||||
if (region.isEmpty() && !force)
|
||||
clearFlag(Exposed);
|
||||
else
|
||||
setFlag(Exposed);
|
||||
QWindowSystemInterface::handleExposeEvent(window(), region);
|
||||
}
|
||||
|
||||
void QWindowsWindow::destroyWindow()
|
||||
{
|
||||
if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
|
||||
|
|
@ -942,13 +951,19 @@ void QWindowsWindow::setVisible(bool visible)
|
|||
if (m_data.hwnd) {
|
||||
if (visible) {
|
||||
show_sys();
|
||||
QWindowSystemInterface::handleExposeEvent(window(),
|
||||
QRect(QPoint(), geometry().size()));
|
||||
|
||||
// When the window is layered, we won't get WM_PAINT, and "we" are in control
|
||||
// over the rendering of the window
|
||||
// There is nobody waiting for this, so we don't need to flush afterwards.
|
||||
QWindow *w = window();
|
||||
if (w->format().hasAlpha() || qFuzzyCompare(w->opacity(), qreal(1)))
|
||||
fireExpose(QRect(0, 0, w->width(), w->height()));
|
||||
|
||||
} else {
|
||||
if (hasMouseCapture())
|
||||
setMouseGrabEnabled(false);
|
||||
hide_sys();
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion());
|
||||
fireExpose(QRegion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1094,14 +1109,9 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
|
|||
}
|
||||
}
|
||||
|
||||
void QWindowsWindow::handleShown()
|
||||
{
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size()));
|
||||
}
|
||||
|
||||
void QWindowsWindow::handleHidden()
|
||||
{
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion());
|
||||
fireExpose(QRegion());
|
||||
}
|
||||
|
||||
void QWindowsWindow::setGeometry(const QRect &rectIn)
|
||||
|
|
@ -1267,28 +1277,21 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
|
|||
if (message == WM_ERASEBKGND) // Backing store - ignored.
|
||||
return true;
|
||||
PAINTSTRUCT ps;
|
||||
if (testFlag(OpenGLSurface)) {
|
||||
// Observed painting problems with Aero style disabled (QTBUG-7865).
|
||||
if (testFlag(OpenGLDoubleBuffered))
|
||||
InvalidateRect(hwnd, 0, false);
|
||||
BeginPaint(hwnd, &ps);
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion(qrectFromRECT(ps.rcPaint)));
|
||||
if (!QWindowsContext::instance()->asyncExpose())
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
} else {
|
||||
BeginPaint(hwnd, &ps);
|
||||
const QRect updateRect = qrectFromRECT(ps.rcPaint);
|
||||
// Observed painting problems with Aero style disabled (QTBUG-7865).
|
||||
if (testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered))
|
||||
InvalidateRect(hwnd, 0, false);
|
||||
|
||||
if (QWindowsContext::verboseIntegration)
|
||||
qDebug() << __FUNCTION__ << this << window() << updateRect;
|
||||
BeginPaint(hwnd, &ps);
|
||||
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion(updateRect));
|
||||
if (!QWindowsContext::instance()->asyncExpose())
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
// If the a window is obscured by another window (such as a child window)
|
||||
// we still need to send isExposed=true, for compatibility.
|
||||
// Our tests depend on it.
|
||||
fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true);
|
||||
if (!QWindowsContext::instance()->asyncExpose())
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ public:
|
|||
WithinSetStyle = 0x800,
|
||||
WithinDestroy = 0x1000,
|
||||
TouchRegistered = 0x2000,
|
||||
AlertState = 0x4000
|
||||
AlertState = 0x4000,
|
||||
Exposed = 0x08000
|
||||
};
|
||||
|
||||
struct WindowData
|
||||
|
|
@ -161,7 +162,7 @@ public:
|
|||
|
||||
virtual void setVisible(bool visible);
|
||||
bool isVisible() const;
|
||||
virtual bool isExposed() const { return m_windowState != Qt::WindowMinimized && isVisible(); }
|
||||
virtual bool isExposed() const { return testFlag(Exposed); }
|
||||
virtual bool isActive() const;
|
||||
virtual bool isEmbedded(const QPlatformWindow *parentWindow) const;
|
||||
virtual QPoint mapToGlobal(const QPoint &pos) const;
|
||||
|
|
@ -217,7 +218,6 @@ public:
|
|||
|
||||
void handleMoved();
|
||||
void handleResized(int wParam);
|
||||
void handleShown();
|
||||
void handleHidden();
|
||||
|
||||
static inline HWND handleOf(const QWindow *w);
|
||||
|
|
@ -278,6 +278,7 @@ private:
|
|||
void handleGeometryChange();
|
||||
void handleWindowStateChange(Qt::WindowState state);
|
||||
inline void destroyIcon();
|
||||
void fireExpose(const QRegion ®ion, bool force=false);
|
||||
|
||||
mutable WindowData m_data;
|
||||
mutable unsigned m_flags;
|
||||
|
|
|
|||
|
|
@ -2089,11 +2089,14 @@ public:
|
|||
|
||||
void tst_QWidget::resizeEvent()
|
||||
{
|
||||
QSKIP("QTBUG-30744");
|
||||
|
||||
{
|
||||
QWidget wParent;
|
||||
wParent.resize(200, 200);
|
||||
ResizeWidget wChild(&wParent);
|
||||
wParent.show();
|
||||
QTest::qWaitForWindowExposed(&wParent);
|
||||
QCOMPARE (wChild.m_resizeEventCount, 1); // initial resize event before paint
|
||||
wParent.hide();
|
||||
QSize safeSize(640,480);
|
||||
|
|
@ -2109,6 +2112,7 @@ void tst_QWidget::resizeEvent()
|
|||
ResizeWidget wTopLevel;
|
||||
wTopLevel.resize(200, 200);
|
||||
wTopLevel.show();
|
||||
QTest::qWaitForWindowExposed(&wTopLevel);
|
||||
QCOMPARE (wTopLevel.m_resizeEventCount, 1); // initial resize event before paint for toplevels
|
||||
wTopLevel.hide();
|
||||
QSize safeSize(640,480);
|
||||
|
|
@ -2117,6 +2121,7 @@ void tst_QWidget::resizeEvent()
|
|||
wTopLevel.resize(safeSize);
|
||||
QCOMPARE (wTopLevel.m_resizeEventCount, 1);
|
||||
wTopLevel.show();
|
||||
QTest::qWaitForWindowExposed(&wTopLevel);
|
||||
QCOMPARE (wTopLevel.m_resizeEventCount, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -4428,11 +4433,8 @@ void tst_QWidget::setWindowGeometry()
|
|||
|
||||
widget.setGeometry(rect);
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
if (m_platform == QStringLiteral("windows")) {
|
||||
QEXPECT_FAIL("130,100 0x200, flags 0", "QTBUG-26424", Continue);
|
||||
QEXPECT_FAIL("130,50 0x0, flags 0", "QTBUG-26424", Continue);
|
||||
}
|
||||
if (rect.isValid())
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
QTRY_COMPARE(widget.geometry(), rect);
|
||||
|
||||
// setGeometry() while shown
|
||||
|
|
@ -4462,7 +4464,8 @@ void tst_QWidget::setWindowGeometry()
|
|||
|
||||
// show() again, geometry() should still be the same
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
if (rect.isValid())
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
QTRY_COMPARE(widget.geometry(), rect);
|
||||
|
||||
// final hide(), again geometry() should be unchanged
|
||||
|
|
@ -4478,7 +4481,8 @@ void tst_QWidget::setWindowGeometry()
|
|||
widget.setWindowFlags(Qt::WindowFlags(windowFlags));
|
||||
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
if (rect.isValid())
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
widget.setGeometry(rect);
|
||||
QTest::qWait(10);
|
||||
QTRY_COMPARE(widget.geometry(), rect);
|
||||
|
|
@ -4510,7 +4514,8 @@ void tst_QWidget::setWindowGeometry()
|
|||
|
||||
// show() again, geometry() should still be the same
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
if (rect.isValid())
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
QTest::qWait(10);
|
||||
QTRY_COMPARE(widget.geometry(), rect);
|
||||
|
||||
|
|
@ -4655,7 +4660,8 @@ void tst_QWidget::windowMoveResize()
|
|||
|
||||
// show() again, pos() should be the same
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
if (rect.isValid())
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
QApplication::processEvents();
|
||||
QTRY_COMPARE(widget.pos(), rect.topLeft());
|
||||
QTRY_COMPARE(widget.size(), rect.size());
|
||||
|
|
@ -4674,7 +4680,8 @@ void tst_QWidget::windowMoveResize()
|
|||
widget.setWindowFlags(Qt::WindowFlags(windowFlags));
|
||||
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
if (rect.isValid())
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
QApplication::processEvents();
|
||||
widget.move(rect.topLeft());
|
||||
widget.resize(rect.size());
|
||||
|
|
@ -4724,7 +4731,8 @@ void tst_QWidget::windowMoveResize()
|
|||
|
||||
// show() again, pos() should be the same
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
if (rect.isValid())
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&widget));
|
||||
QTest::qWait(10);
|
||||
QTRY_COMPARE(widget.pos(), rect.topLeft());
|
||||
QTRY_COMPARE(widget.size(), rect.size());
|
||||
|
|
|
|||
Loading…
Reference in New Issue