From 55fa3c189f88933d390177ad5606d3de9deacf93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 14 Mar 2012 17:55:43 +0100 Subject: Got rid of Map / Unmap events in favor of Expose event. Since change 2e4d8f67a871f2033 the need for Map and Unmap events has gone away, as now the Expose event is used to notify the application about when it can start rendering. The Map and Unmap events weren't really used except by QWidget to set the WA_Mapped flag, which we now set based on the expose / unexpose. Also guarantee that a Resize event is always sent before the first Expose, by re-introducing an asynchronous expose event handler. Since an expose is required before rendering to a QWindow, show a warning if QOpenGLContext::swapBuffers() or QBackingStore::flush() if called on a window that has not received its first expose. Change-Id: Ia6b609aa275d5b463b5011a96f2fd9bbe52e9bc4 Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qcoreevent.h | 13 ++++---- src/gui/kernel/qguiapplication.cpp | 38 ++++++++++-------------- src/gui/kernel/qguiapplication_p.h | 3 -- src/gui/kernel/qopenglcontext.cpp | 9 +++++- src/gui/kernel/qplatformwindow_qpa.cpp | 6 ++-- src/gui/kernel/qwindow.cpp | 36 ++++++++++++++++++---- src/gui/kernel/qwindow_p.h | 5 +++- src/gui/kernel/qwindowsysteminterface_qpa.cpp | 20 ++++++++----- src/gui/kernel/qwindowsysteminterface_qpa.h | 4 +-- src/gui/kernel/qwindowsysteminterface_qpa_p.h | 24 ++------------- src/gui/painting/qbackingstore.cpp | 4 +++ src/opengl/qgl.cpp | 2 +- src/plugins/platforms/windows/qwindowswindow.cpp | 5 ++-- src/plugins/platforms/xcb/qxcbwindow.cpp | 23 ++++++++++++-- src/plugins/platforms/xcb/qxcbwindow.h | 4 +++ src/widgets/kernel/qwidget_qpa.cpp | 11 +++++-- src/widgets/kernel/qwidgetbackingstore.cpp | 27 +++-------------- src/widgets/kernel/qwidgetwindow_qpa.cpp | 17 +++++------ 18 files changed, 132 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 1d54b32dfa..a207849604 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -268,17 +268,14 @@ public: ScrollPrepare = 204, Scroll = 205, - Map = 206, - Unmap = 207, + Expose = 206, - Expose = 208, + InputMethodQuery = 207, + OrientationChange = 208, // Screen orientation has changed - InputMethodQuery = 209, - OrientationChange = 210, // Screen orientation has changed + TouchCancel = 209, - TouchCancel = 211, - - ThemeChange = 212, + ThemeChange = 210, // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index c6ff5bb230..0fd18e7d2d 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -971,12 +971,6 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv QGuiApplicationPrivate::processThemeChanged( static_cast(e)); break; - case QWindowSystemInterfacePrivate::Map: - QGuiApplicationPrivate::processMapEvent(static_cast(e)); - break; - case QWindowSystemInterfacePrivate::Unmap: - QGuiApplicationPrivate::processUnmapEvent(static_cast(e)); - break; case QWindowSystemInterfacePrivate::Expose: QGuiApplicationPrivate::processExposeEvent(static_cast(e)); break; @@ -1589,30 +1583,28 @@ void QGuiApplicationPrivate::reportLogicalDotsPerInchChange(QWindowSystemInterfa emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch()); } -void QGuiApplicationPrivate::processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e) +void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e) { - if (!e->mapped) + if (!e->exposed) return; - QEvent event(QEvent::Map); - QCoreApplication::sendSpontaneousEvent(e->mapped.data(), &event); -} + QWindow *window = e->exposed.data(); + QWindowPrivate *p = qt_window_private(window); -void QGuiApplicationPrivate::processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e) -{ - if (!e->unmapped) - return; + if (!p->receivedExpose) { + if (p->resizeEventPending) { + // as a convenience for plugins, send a resize event before the first expose event if they haven't done so + QSize size = p->geometry.size(); + QResizeEvent e(size, size); + QGuiApplication::sendSpontaneousEvent(window, &e); - QEvent event(QEvent::Unmap); - QCoreApplication::sendSpontaneousEvent(e->unmapped.data(), &event); -} + p->resizeEventPending = false; + } -void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e) -{ - if (!e->exposed) - return; + p->receivedExpose = true; + } - QWindow *window = e->exposed.data(); + p->exposed = e->isExposed; QExposeEvent exposeEvent(e->region); QCoreApplication::sendSpontaneousEvent(window, &exposeEvent); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index f30a2bb5a0..6792e9382c 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -118,9 +118,6 @@ public: static void reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e); static void processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce); - static void processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e); - static void processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e); - static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e); static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions); diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index eaff417f15..29f46aefd6 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -502,7 +503,13 @@ void QOpenGLContext::swapBuffers(QSurface *surface) if (surface->surfaceType() != QSurface::OpenGLSurface) { qWarning() << "QOpenGLContext::swapBuffers() called with non-opengl surface"; return; - } + } + + if (surface->surfaceClass() == QSurface::Window + && !qt_window_private(static_cast(surface))->receivedExpose) + { + qWarning() << "QOpenGLContext::swapBuffers() called with non-exposed window, behavior is undefined"; + } QPlatformSurface *surfaceHandle = surface->surfaceHandle(); if (!surfaceHandle) diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index e12228d7bd..c8e2776366 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -142,11 +142,13 @@ QMargins QPlatformWindow::frameMargins() const /*! Reimplemented in subclasses to show the surface if \a visible is \c true, and hide it if \a visible is \c false. + + The default implementation sends a synchronous expose event. */ void QPlatformWindow::setVisible(bool visible) { - Q_UNUSED(visible); - QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); + QRect rect(QPoint(), geometry().size()); + QWindowSystemInterface::handleSynchronousExposeEvent(window(), rect); } /*! Requests setting the window flags of this surface diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 78b6f6f722..ab1e8f7601 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -108,6 +108,18 @@ QT_BEGIN_NAMESPACE called whenever the windows exposure in the windowing system changes. On windowing systems that do not make this information visible to the application, isExposed() will simply return the same value as isVisible(). + + \section1 Rendering + + There are two Qt APIs that can be used to render content into a window, + QBackingStore for rendering with a QPainter and flushing the contents + to a window with type QSurface::RasterSurface, and QOpenGLContext for + rendering with OpenGL to a window with type QSurface::OpenGLSurface. + + The application can start rendering as soon as isExposed() returns true, + and can keep rendering until it isExposed() returns false. To find out when + isExposed() changes, reimplement exposeEvent(). The window will always get + a resize event before the first expose event. */ /*! @@ -578,9 +590,7 @@ void QWindow::requestActivateWindow() bool QWindow::isExposed() const { Q_D(const QWindow); - if (d->platformWindow) - return d->platformWindow->isExposed(); - return false; + return d->exposed; } /*! @@ -1077,6 +1087,9 @@ void QWindow::destroy() } setVisible(false); delete d->platformWindow; + d->resizeEventPending = true; + d->receivedExpose = false; + d->exposed = false; d->platformWindow = 0; } @@ -1336,12 +1349,19 @@ bool QWindow::close() The expose event is sent by the window system whenever the window's exposure on screen changes. + The application can start rendering into the window with QBackingStore + and QOpenGLContext as soon as it gets an exposeEvent() such that + isExposed() is true. + If the window is moved off screen, is made totally obscured by another window, iconified or similar, this function might be called and the value of isExposed() might change to false. When this happens, an application should stop its rendering as it is no longer visible to the user. + A resize event will always be sent before the expose event the first time + a window is shown. + \sa isExposed() */ void QWindow::exposeEvent(QExposeEvent *ev) @@ -1372,7 +1392,10 @@ void QWindow::resizeEvent(QResizeEvent *ev) /*! Override this to handle show events. - The show event is called when the window becomes visible in the windowing system. + The show event is called when the window has requested becoming visible. + + If the window is successfully shown by the windowing system, this will + be followed by a resize and an expose event. */ void QWindow::showEvent(QShowEvent *ev) { @@ -1380,9 +1403,10 @@ void QWindow::showEvent(QShowEvent *ev) } /*! - Override this to handle show events. + Override this to handle hide evens. - The show event is called when the window becomes hidden in the windowing system. + The hide event is called when the window has requested being hidden in the + windowing system. */ void QWindow::hideEvent(QHideEvent *ev) { diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 7f3958b3ff..03b3b92a25 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -72,8 +72,10 @@ public: , parentWindow(0) , platformWindow(0) , visible(false) + , exposed(false) , windowState(Qt::WindowNoState) , resizeEventPending(true) + , receivedExpose(false) , positionPolicy(WindowFrameExclusive) , contentOrientation(Qt::PrimaryOrientation) , windowOrientation(Qt::PrimaryOrientation) @@ -99,17 +101,18 @@ public: return offset; } - QWindow::SurfaceType surfaceType; Qt::WindowFlags windowFlags; QWindow *parentWindow; QPlatformWindow *platformWindow; bool visible; + bool exposed; QSurfaceFormat requestedFormat; QString windowTitle; QRect geometry; Qt::WindowState windowState; bool resizeEventPending; + bool receivedExpose; PositionPolicy positionPolicy; Qt::ScreenOrientation contentOrientation; Qt::ScreenOrientation windowOrientation; diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp index 9ab91d65d5..fcffd75b39 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp +++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ #include "qwindowsysteminterface_qpa.h" +#include "qplatformwindow_qpa.h" #include "qwindowsysteminterface_qpa_p.h" #include "private/qguiapplication_p.h" #include "private/qevent_p.h" @@ -274,6 +275,15 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); } + +QWindowSystemInterfacePrivate::ExposeEvent::ExposeEvent(QWindow *exposed, const QRegion ®ion) + : WindowSystemEvent(Expose) + , exposed(exposed) + , isExposed(exposed && exposed->handle() ? exposed->handle()->isExposed() : false) + , region(region) +{ +} + int QWindowSystemInterfacePrivate::windowSystemEventsQueued() { queueMutex.lock(); @@ -426,15 +436,9 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw) QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); } -void QWindowSystemInterface::handleMapEvent(QWindow *tlw) -{ - QWindowSystemInterfacePrivate::MapEvent *e = new QWindowSystemInterfacePrivate::MapEvent(tlw); - QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); -} - -void QWindowSystemInterface::handleUnmapEvent(QWindow *tlw) +void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion ®ion) { - QWindowSystemInterfacePrivate::UnmapEvent *e = new QWindowSystemInterfacePrivate::UnmapEvent(tlw); + QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region); QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); } diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h index 560f47d972..1fbf430bf9 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa.h @@ -130,9 +130,7 @@ public: static void handleWindowActivated(QWindow *w); static void handleWindowStateChanged(QWindow *w, Qt::WindowState newState); - static void handleMapEvent(QWindow *w); - static void handleUnmapEvent(QWindow *w); - + static void handleExposeEvent(QWindow *tlw, const QRegion ®ion); static void handleSynchronousExposeEvent(QWindow *tlw, const QRegion ®ion); // Drag and drop. These events are sent immediately. diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h index fe97b486ad..d7be7699e9 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h @@ -42,6 +42,7 @@ #define QWINDOWSYSTEMINTERFACE_QPA_P_H #include "qwindowsysteminterface_qpa.h" + #include QT_BEGIN_HEADER @@ -66,8 +67,6 @@ public: ScreenAvailableGeometry, ScreenLogicalDotsPerInch, ThemeChange, - Map, - Unmap, Expose }; @@ -241,28 +240,11 @@ public: QWeakPointer window; }; - class MapEvent : public WindowSystemEvent { - public: - MapEvent(QWindow *mapped) - : WindowSystemEvent(Map), mapped(mapped) - { } - QWeakPointer mapped; - }; - - class UnmapEvent : public WindowSystemEvent { - public: - UnmapEvent(QWindow *unmapped) - : WindowSystemEvent(Unmap), unmapped(unmapped) - { } - QWeakPointer unmapped; - }; - class ExposeEvent : public WindowSystemEvent { public: - ExposeEvent(QWindow *exposed, const QRegion ®ion) - : WindowSystemEvent(Expose), exposed(exposed), region(region) - { } + ExposeEvent(QWindow *exposed, const QRegion ®ion); QWeakPointer exposed; + bool isExposed; QRegion region; }; diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 03c2fc8d6a..63f7ba594f 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -82,6 +82,10 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *win, const QPoint &off { if (!win) win = window(); + + if (win && !qt_window_private(win)->receivedExpose) + qWarning("QBackingStore::flush() called with non-exposed window, behavior is undefined"); + d_ptr->platformBackingStore->flush(win, region, offset); } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index eb27e865b5..2c683f7ae7 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3770,7 +3770,7 @@ void QGLWidget::setFormat(const QGLFormat &format) void QGLWidget::updateGL() { - if (updatesEnabled()) + if (updatesEnabled() && testAttribute(Qt::WA_Mapped)) glDraw(); } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index fa3661db22..6ff854805c 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -708,7 +708,6 @@ void QWindowsWindow::setVisible(bool visible) hide_sys(); } } - QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); } bool QWindowsWindow::isVisible() const @@ -804,12 +803,12 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const void QWindowsWindow::handleShown() { - QWindowSystemInterface::handleMapEvent(window()); + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); } void QWindowsWindow::handleHidden() { - QWindowSystemInterface::handleUnmapEvent(window()); + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); } void QWindowsWindow::setGeometry(const QRect &rectIn) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 4de3734c22..3e63ab0f27 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -160,6 +160,8 @@ void QXcbWindow::create() { destroy(); + m_deferredExpose = false; + m_configureNotifyPending = true; m_windowState = Qt::WindowNoState; Qt::WindowType type = window()->windowType(); @@ -1260,7 +1262,7 @@ void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) // if count is non-zero there are more expose events pending if (event->count == 0) { - QWindowSystemInterface::handleSynchronousExposeEvent(window(), m_exposeRegion); + QWindowSystemInterface::handleExposeEvent(window(), m_exposeRegion); m_exposeRegion = QRegion(); } } @@ -1327,6 +1329,13 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); + m_configureNotifyPending = false; + + if (m_deferredExpose) { + m_deferredExpose = false; + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); + } + m_dirtyFrameMargins = true; #if XCB_USE_DRI2 @@ -1335,13 +1344,21 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * #endif } +bool QXcbWindow::isExposed() const +{ + return m_mapped; +} + void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event) { if (event->window == m_window) { m_mapped = true; if (m_deferredActivation) requestActivateWindow(); - QWindowSystemInterface::handleMapEvent(window()); + if (m_configureNotifyPending) + m_deferredExpose = true; + else + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); } } @@ -1349,7 +1366,7 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) { if (event->window == m_window) { m_mapped = false; - QWindowSystemInterface::handleUnmapEvent(window()); + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index c212095e98..37e0bdb8d3 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -72,6 +72,8 @@ public: WId winId() const; void setParent(const QPlatformWindow *window); + bool isExposed() const; + void setWindowTitle(const QString &title); void raise(); void lower(); @@ -155,6 +157,8 @@ private: bool m_mapped; bool m_transparent; bool m_deferredActivation; + bool m_deferredExpose; + bool m_configureNotifyPending; xcb_window_t m_netWmUserTimeWindow; QSurfaceFormat m_format; diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 3d23b04ddf..0f55646958 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -440,9 +440,9 @@ static inline QRect positionTopLevelWindow(QRect geometry, const QScreen *screen void QWidgetPrivate::show_sys() { Q_Q(QWidget); - q->setAttribute(Qt::WA_Mapped); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { invalidateBuffer(q->rect()); + q->setAttribute(Qt::WA_Mapped); return; } @@ -483,8 +483,8 @@ void QWidgetPrivate::show_sys() void QWidgetPrivate::hide_sys() { Q_Q(QWidget); - q->setAttribute(Qt::WA_Mapped, false); deactivateWidgetCleanup(); + if (!q->isWindow()) { QWidget *p = q->parentWidget(); if (p &&p->isVisible()) { @@ -492,7 +492,12 @@ void QWidgetPrivate::hide_sys() } return; } - if (QWindow *window = q->windowHandle()) { + + invalidateBuffer(q->rect()); + + if (q->testAttribute(Qt::WA_DontShowOnScreen)) { + q->setAttribute(Qt::WA_Mapped, false); + } else if (QWindow *window = q->windowHandle()) { window->setVisible(false); } } diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index b331356e66..2e9f072a0f 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -914,29 +914,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra) { - if (!tlw || !tlwExtra) - return true; - -#ifdef Q_WS_X11 - // Delay the sync until we get an Expose event from X11 (initial show). - // Qt::WA_Mapped is set to true, but the actual mapping has not yet occurred. - // However, we must repaint immediately regardless of the state if someone calls repaint(). - if (tlwExtra->waitingForMapNotify && !tlwExtra->inRepaint) - return true; -#endif - - if (!tlw->testAttribute(Qt::WA_Mapped)) - return true; - - if (!tlw->isVisible() -#ifndef Q_WS_X11 - // If we're minimized on X11, WA_Mapped will be false and we - // will return in the case above. Some window managers on X11 - // sends us the PropertyNotify to change the minimized state - // *AFTER* we've received the expose event, which is baaad. - || tlw->isMinimized() -#endif - ) + if (!tlw || !tlwExtra || !tlw->testAttribute(Qt::WA_Mapped) || !tlw->isVisible()) return true; return false; @@ -1345,6 +1323,9 @@ void QWidgetPrivate::repaint_sys(const QRegion &rgn) return; Q_Q(QWidget); + if (discardSyncRequest(q, maybeTopData())) + return; + if (q->testAttribute(Qt::WA_StaticContents)) { if (!extra) createExtra(); diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index f58dddb70f..498908f4db 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -137,15 +137,6 @@ bool QWidgetWindow::event(QEvent *event) handleDragEvent(event); break; - case QEvent::Map: - m_widget->setAttribute(Qt::WA_Mapped); - m_widget->d_func()->syncBackingStore(); - return true; - - case QEvent::Unmap: - m_widget->setAttribute(Qt::WA_Mapped, false); - return true; - case QEvent::Expose: handleExposeEvent(static_cast(event)); return true; @@ -432,7 +423,13 @@ void QWidgetWindow::handleDragEvent(QEvent *event) void QWidgetWindow::handleExposeEvent(QExposeEvent *event) { - m_widget->d_func()->syncBackingStore(event->region()); + if (isExposed()) { + m_widget->setAttribute(Qt::WA_Mapped); + if (!event->region().isNull()) + m_widget->d_func()->syncBackingStore(event->region()); + } else { + m_widget->setAttribute(Qt::WA_Mapped, false); + } } void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event) -- cgit v1.2.3