From effc6b4cd15aefa1bef30c27f0458390735fafb5 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 12 Feb 2015 15:28:12 +0100 Subject: Add widget support for requestUpdate() and improve its docs and tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We must do something when requestUpdate() is called on a QWidgetWindow. The semantics of UpdateRequest for QWindow and QWidget are unfortunately different: for widgets an UpdateRequest means "sync the backing store". For QWindow it also involves marking as dirty. Change-Id: Idf40b3fc0873652dc081edeb12c96b3007a126ef Reviewed-by: Morten Johan Sørvig Reviewed-by: Jørgen Lind --- src/gui/kernel/qwindow.cpp | 13 ++++++++---- src/widgets/kernel/qwidgetwindow.cpp | 12 ++++++++++- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 20 ++++++++++++++++++ .../widgets/qopenglwidget/tst_qopenglwidget.cpp | 24 ++++++++++++++++++++++ 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 1fbb67fb8a..4a88988322 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2078,11 +2078,16 @@ void QWindowPrivate::deliverUpdateRequest() Calling this function multiple times will result in a single event being delivered to the window. - Subclasses of QWindow should reimplement QWindow::event(), intercept - the event and call the application's rendering code, then call the - base class implementation. -*/ + Subclasses of QWindow should reimplement event(), intercept the event and + call the application's rendering code, then call the base class + implementation. + \note The subclass' reimplementation of event() must invoke the base class + implementation, unless it is absolutely sure that the event does not need to + be handled by the base class. For example, the default implementation of + this function relies on QEvent::Timer events. Filtering them away would + therefore break the delivery of the update events. +*/ void QWindow::requestUpdate() { Q_D(QWindow); diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 11dfe8a6d5..6c7dc070d5 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -292,11 +292,21 @@ bool QWidgetWindow::event(QEvent *event) case QEvent::WindowBlocked: qt_button_down = 0; break; + + case QEvent::UpdateRequest: + // This is not the same as an UpdateRequest for a QWidget. That just + // syncs the backing store while here we also must mark as dirty. + m_widget->repaint(); + return true; + default: break; } - return m_widget->event(event) || QWindow::event(event); + if (m_widget->event(event) && event->type() != QEvent::Timer) + return true; + + return QWindow::event(event); } QPointer qt_last_mouse_receiver = 0; diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index e542c85218..89490525c9 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -91,6 +91,7 @@ private slots: void modalWindowModallity(); void modalWindowPosition(); void windowsTransientChildren(); + void requestUpdate(); void initTestCase(); void cleanup(); @@ -1666,6 +1667,25 @@ void tst_QWindow::windowsTransientChildren() QVERIFY(isNativeWindowVisible(&child)); // Real children should be visible. } +void tst_QWindow::requestUpdate() +{ + QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); + + Window window; + window.setGeometry(geometry); + window.show(); + QCoreApplication::processEvents(); + QTRY_VERIFY(window.isExposed()); + + QVERIFY(window.received(QEvent::UpdateRequest) == 0); + + window.requestUpdate(); + QTRY_VERIFY(window.received(QEvent::UpdateRequest) == 1); + + window.requestUpdate(); + QTRY_VERIFY(window.received(QEvent::UpdateRequest) == 2); +} + #include QTEST_MAIN(tst_QWindow) diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index ade70b0eec..0c0c50ac64 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -55,6 +55,7 @@ private slots: void reparentToAlreadyCreated(); void reparentToNotYetCreated(); void asViewport(); + void requestUpdate(); }; void tst_QOpenGLWidget::create() @@ -305,6 +306,29 @@ void tst_QOpenGLWidget::asViewport() QVERIFY(view->paintCount() == 0); } +class PaintCountWidget : public QOpenGLWidget +{ +public: + PaintCountWidget() : m_count(0) { } + void reset() { m_count = 0; } + void paintGL() Q_DECL_OVERRIDE { ++m_count; } + int m_count; +}; + +void tst_QOpenGLWidget::requestUpdate() +{ + PaintCountWidget w; + w.resize(640, 480); + w.show(); + QTest::qWaitForWindowExposed(&w); + + w.reset(); + QCOMPARE(w.m_count, 0); + + w.windowHandle()->requestUpdate(); + QTRY_VERIFY(w.m_count > 0); +} + QTEST_MAIN(tst_QOpenGLWidget) #include "tst_qopenglwidget.moc" -- cgit v1.2.3