diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2015-01-21 18:04:29 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com> | 2015-01-22 12:58:34 +0100 |
commit | a2b358e7f5f46472d21d4ea24ec0c2646bc51cc7 (patch) | |
tree | f9edbedbe7b7cc956b56111def0dac372c455c40 /src/gui/kernel | |
parent | 38abd653774aa0b3c5cdfd9a8b78619605230726 (diff) |
Only show QWindows after QScreen destruction if coming from virtual sibling
For windows that were shown on an external screen (not a virtual sibling
of the primary screen), eg. on iOS, it doesn't make sense to re-show the
window when moved back to the primary screen.
By moving the logic into the QScreen destructor, we ensure that the code
path is hit both for the old and unsupported style way of destroying
QPlatformScreen by deleting it directly, and the new and safe way
of using QPlatformIntegration::destroyScreen(), while still allowing
clients to manage the windows themselves by emitting screenRemoved()
before applying our fallback logic.
[ChangeLog][QtGui][Important Behavior Changes] QWindows will no longer
be re-shown automatically when moved from a destroyed QScreen, unless
that QScreen was a virtual sibling of the primary screen.
Change-Id: If1105bc5ef41a5392854bb97d121c998bffa3606
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qscreen.cpp | 31 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 25 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.h | 3 |
3 files changed, 30 insertions, 29 deletions
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 6594565c15..8357e14354 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -72,8 +72,35 @@ QScreen::QScreen(QPlatformScreen *screen) */ QScreen::~QScreen() { - if (qApp) - Q_EMIT qApp->screenRemoved(this); + if (!qApp) + return; + + // Allow clients to manage windows that are affected by the screen going + // away, before we fall back to moving them to the primary screen. + emit qApp->screenRemoved(this); + + if (QGuiApplication::closingDown()) + return; + + QScreen *primaryScreen = QGuiApplication::primaryScreen(); + if (this == primaryScreen) + return; + + bool movingFromVirtualSibling = primaryScreen->handle()->virtualSiblings().contains(handle()); + + // Move any leftover windows to the primary screen + foreach (QWindow *window, QGuiApplication::topLevelWindows()) { + if (window->screen() != this) + continue; + + const bool wasVisible = window->isVisible(); + window->setScreen(primaryScreen); + + // Re-show window if moved from a virtual sibling screen. Otherwise + // leave it up to the application developer to show the window. + if (movingFromVirtualSibling) + window->setVisible(wasVisible); + } } /*! diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index ced39bbe10..b679dd9bfc 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -344,20 +344,14 @@ inline bool QWindowPrivate::windowRecreationRequired(QScreen *newScreen) const inline void QWindowPrivate::disconnectFromScreen() { - if (topLevelScreen) { - Q_Q(QWindow); - QObject::disconnect(topLevelScreen, &QObject::destroyed, q, &QWindow::screenDestroyed); + if (topLevelScreen) topLevelScreen = 0; - } } void QWindowPrivate::connectToScreen(QScreen *screen) { - Q_Q(QWindow); disconnectFromScreen(); topLevelScreen = screen; - if (topLevelScreen) - QObject::connect(topLevelScreen, &QObject::destroyed, q, &QWindow::screenDestroyed); } void QWindowPrivate::emitScreenChangedRecursion(QScreen *newScreen) @@ -1712,23 +1706,6 @@ void QWindow::setScreen(QScreen *newScreen) d->setTopLevelScreen(newScreen, true /* recreate */); } -void QWindow::screenDestroyed(QObject *object) -{ - Q_D(QWindow); - if (d->parentWindow || QGuiApplication::closingDown()) - return; - if (object == static_cast<QObject *>(d->topLevelScreen)) { - const bool wasVisible = isVisible(); - setScreen(0); - // destroy() might have hidden our window, show it again. - // This might not be the best behavior if the new screen isn't a virtual sibling - // of the old one. This can be removed once platform plugins have the power to - // update the QScreen of its QWindows itself. - if (wasVisible && d->platformWindow) - setVisible(true); - } -} - /*! \fn QWindow::screenChanged(QScreen *screen) diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 350cd8af24..1a43ac6fc2 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -314,9 +314,6 @@ Q_SIGNALS: Q_REVISION(1) void opacityChanged(qreal opacity); -private Q_SLOTS: - void screenDestroyed(QObject *screen); - protected: virtual void exposeEvent(QExposeEvent *); virtual void resizeEvent(QResizeEvent *); |