From d7a9e08f0ada36ad8ad44651f27a76c9c74e3428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 19 Apr 2017 11:19:19 +0200 Subject: Make QWindow::setVisible() work for widgets QWidget has its own setVisible() code that needs to be run in order to correctly transition widget visibility. It is desirable to be able to show and hide (native) widgets also from the QWindow side, for example from the platform plugin, or from generic QWindow handling code in QtGui. Add a new virtual QWindowPrivate::setVisible() and move the QWindow visibility implementation there. Subclasses can now override this function to add custom code. Make QWidgetPrivate::show/hide_sys() call the QWindowPrivate setVisible implementation instead of the QWindow setVisible public API. Change-Id: I082f174b100659e1221d5898b490f8a9f498abdf Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Shawn Rutledge Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidget.cpp | 8 ++++---- src/widgets/kernel/qwidgetwindow.cpp | 18 ++++++++++++++++++ src/widgets/kernel/qwidgetwindow_p.h | 3 +++ 3 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 7112e1c783..caa17e4aea 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7952,7 +7952,7 @@ void QWidgetPrivate::show_sys() { Q_Q(QWidget); - QWindow *window = q->windowHandle(); + QWidgetWindow *window = qobject_cast(q->windowHandle()); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { invalidateBuffer(q->rect()); @@ -7999,7 +7999,7 @@ void QWidgetPrivate::show_sys() qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show #endif invalidateBuffer(q->rect()); - window->setVisible(true); + window->setNativeWindowVisibility(true); // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ? if (window->isTopLevel()) { const QPoint crectTopLeft = q->data->crect.topLeft(); @@ -8091,7 +8091,7 @@ void QWidgetPrivate::hide_sys() { Q_Q(QWidget); - QWindow *window = q->windowHandle(); + QWidgetWindow *window = qobject_cast(q->windowHandle()); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { q->setAttribute(Qt::WA_Mapped, false); @@ -8121,7 +8121,7 @@ void QWidgetPrivate::hide_sys() } if (window) - window->setVisible(false); + window->setNativeWindowVisibility(false); } /*! diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 5b695d9f30..84323a5388 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -69,6 +69,15 @@ class QWidgetWindowPrivate : public QWindowPrivate { Q_DECLARE_PUBLIC(QWidgetWindow) public: + void setVisible(bool visible) override + { + Q_Q(QWidgetWindow); + if (QWidget *widget = q->widget()) + widget->setVisible(visible); + else + QWindowPrivate::setVisible(visible); + } + QWindow *eventReceiver() Q_DECL_OVERRIDE { Q_Q(QWidgetWindow); QWindow *w = q; @@ -164,6 +173,15 @@ QObject *QWidgetWindow::focusObject() const return widget; } +void QWidgetWindow::setNativeWindowVisibility(bool visible) +{ + Q_D(QWidgetWindow); + // Call base class setVisible() implementation to run the QWindow + // visibility logic. Don't call QWidgetWindowPrivate::setVisible() + // since that will recurse back into QWidget code. + d->QWindowPrivate::setVisible(visible); +} + static inline bool shouldBePropagatedToWidget(QEvent *event) { switch (event->type()) { diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index a81355160e..4c7e30da2f 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -63,10 +63,12 @@ QT_BEGIN_NAMESPACE class QCloseEvent; class QMoveEvent; +class QWidgetWindowPrivate; class QWidgetWindow : public QWindow { Q_OBJECT + Q_DECLARE_PRIVATE(QWidgetWindow) public: QWidgetWindow(QWidget *widget); ~QWidgetWindow(); @@ -77,6 +79,7 @@ public: #endif QObject *focusObject() const Q_DECL_OVERRIDE; + void setNativeWindowVisibility(bool visible); protected: bool event(QEvent *) Q_DECL_OVERRIDE; -- cgit v1.2.3