diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 18 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 34 |
3 files changed, 49 insertions, 5 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b1d80d7b8f..b99fca6620 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -276,6 +276,8 @@ QWidgetPrivate::QWidgetPrivate(int version) , renderToTextureReallyDirty(1) , renderToTextureComposeActive(0) #endif + , childrenHiddenByWState(0) + , childrenShownByExpose(0) #if defined(Q_OS_WIN) , noPaintOnScreen(0) #endif @@ -9005,13 +9007,23 @@ bool QWidget::event(QEvent *event) case QEvent::WindowStateChange: { const bool wasMinimized = static_cast<const QWindowStateChangeEvent *>(event)->oldState() & Qt::WindowMinimized; if (wasMinimized != isMinimized()) { + QWidget *widget = const_cast<QWidget *>(this); if (wasMinimized) { - QShowEvent showEvent; - QCoreApplication::sendEvent(const_cast<QWidget *>(this), &showEvent); + // Always send the spontaneous events here, otherwise it can break the application! + if (!d->childrenShownByExpose) { + // Show widgets only when they are not yet shown by the expose event + d->showChildren(true); + QShowEvent showEvent; + QCoreApplication::sendSpontaneousEvent(widget, &showEvent); + } + d->childrenHiddenByWState = false; // Set it always to "false" when window is restored } else { QHideEvent hideEvent; - QCoreApplication::sendEvent(const_cast<QWidget *>(this), &hideEvent); + QCoreApplication::sendSpontaneousEvent(widget, &hideEvent); + d->hideChildren(true); + d->childrenHiddenByWState = true; } + d->childrenShownByExpose = false; // Set it always to "false" when window state changes } changeEvent(event); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index b130c5421a..5f07a8802a 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -746,6 +746,8 @@ public: uint renderToTextureReallyDirty : 1; uint renderToTextureComposeActive : 1; #endif + uint childrenHiddenByWState : 1; + uint childrenShownByExpose : 1; // *************************** Platform specific ************************************ #if defined(Q_OS_WIN) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 872572a7e2..aa7bcc2ef8 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -871,10 +871,40 @@ void QWidgetWindow::handleDropEvent(QDropEvent *event) void QWidgetWindow::handleExposeEvent(QExposeEvent *event) { - if (isExposed()) { + QWidgetPrivate *wPriv = m_widget->d_func(); + const bool exposed = isExposed(); + + if (wPriv->childrenHiddenByWState) { + // If widgets has been previously hidden by window state change event + // and they aren't yet shown... + if (exposed) { + // If the window becomes exposed... + if (!wPriv->childrenShownByExpose) { + // ... and they haven't been shown by this function yet - show it. + wPriv->showChildren(true); + QShowEvent showEvent; + QCoreApplication::sendSpontaneousEvent(m_widget, &showEvent); + wPriv->childrenShownByExpose = true; + } + } else { + // If the window becomes not exposed... + if (wPriv->childrenShownByExpose) { + // ... and child widgets was previously shown by the expose event - hide widgets again. + // This is a workaround, because sometimes when window is minimized programatically, + // the QPA can notify that the window is exposed after changing window state to minimized + // and then, the QPA can send next expose event with null exposed region (not exposed). + wPriv->hideChildren(true); + QHideEvent hideEvent; + QCoreApplication::sendSpontaneousEvent(m_widget, &hideEvent); + wPriv->childrenShownByExpose = false; + } + } + } + + if (exposed) { m_widget->setAttribute(Qt::WA_Mapped); if (!event->region().isNull()) - m_widget->d_func()->syncBackingStore(event->region()); + wPriv->syncBackingStore(event->region()); } else { m_widget->setAttribute(Qt::WA_Mapped, false); } |