summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@digia.com>2015-02-03 13:05:20 +0100
committerDaniel Molkentin <daniel@molkentin.de>2015-02-07 16:19:59 +0000
commitf4b8697c40bd476ef6bf83418e144adce7c7d4a3 (patch)
treed5f7c03b627a459c5a6461ded2abc6d102c115ee /src/gui
parent45b60c01efc735ce9910d7724ee300855194ff33 (diff)
Handle gracefully the removal and re-attachment of all QScreens
Don't crash; restore windows when all screens are removed and re-added. xcb: on configure notify, check for screen change: it may be that a window belonging to a screen which was removed has now gotten mapped to the new screen. On screen change, send a synthetic expose event, because the real expose events already happened. Task-number: QTBUG-38326 Task-number: QTBUG-32973 Task-number: QTBUG-42985 Change-Id: If334f55c248468ad3c95e7066bb14eca377d2050 Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/kernel/qguiapplication.cpp4
-rw-r--r--src/gui/kernel/qplatformwindow.cpp5
-rw-r--r--src/gui/kernel/qscreen.cpp2
-rw-r--r--src/gui/kernel/qwindow.cpp14
-rw-r--r--src/gui/kernel/qwindow_p.h5
5 files changed, 20 insertions, 10 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index d44a79b37e..92be903b41 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2583,6 +2583,8 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E
return;
QWindow *window = e->exposed.data();
+ if (!window)
+ return;
QWindowPrivate *p = qt_window_private(window);
if (!p->receivedExpose) {
@@ -2598,7 +2600,7 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E
p->receivedExpose = true;
}
- p->exposed = e->isExposed;
+ p->exposed = e->isExposed && window->screen();
QExposeEvent exposeEvent(e->region);
QCoreApplication::sendSpontaneousEvent(window, &exposeEvent);
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 167bd44f0e..763ab68868 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -83,7 +83,8 @@ QPlatformWindow *QPlatformWindow::parent() const
*/
QPlatformScreen *QPlatformWindow::screen() const
{
- return window()->screen()->handle();
+ QScreen *scr = window()->screen();
+ return scr ? scr->handle() : Q_NULLPTR;
}
/*!
@@ -479,7 +480,7 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &
QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const
{
QPlatformScreen *currentScreen = screen();
- if (!parent() && !currentScreen->geometry().intersects(newGeometry)) {
+ if (!parent() && currentScreen && !currentScreen->geometry().intersects(newGeometry)) {
Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
if (screen->geometry().intersects(newGeometry))
return screen;
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 8357e14354..0cc8f1082a 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -86,7 +86,7 @@ QScreen::~QScreen()
if (this == primaryScreen)
return;
- bool movingFromVirtualSibling = primaryScreen->handle()->virtualSiblings().contains(handle());
+ bool movingFromVirtualSibling = primaryScreen && primaryScreen->handle()->virtualSiblings().contains(handle());
// Move any leftover windows to the primary screen
foreach (QWindow *window, QGuiApplication::topLevelWindows()) {
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index b679dd9bfc..773cce7a7f 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -338,7 +338,7 @@ inline bool QWindowPrivate::windowRecreationRequired(QScreen *newScreen) const
{
Q_Q(const QWindow);
const QScreen *oldScreen = q->screen();
- return oldScreen != newScreen && platformWindow
+ return oldScreen != newScreen && (platformWindow || !oldScreen)
&& !(oldScreen && oldScreen->virtualSiblings().contains(newScreen));
}
@@ -373,10 +373,13 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
}
if (newScreen != topLevelScreen) {
const bool shouldRecreate = recreate && windowRecreationRequired(newScreen);
- if (shouldRecreate)
+ const bool shouldShow = visibilityOnDestroy && !topLevelScreen;
+ if (shouldRecreate && platformWindow)
q->destroy();
connectToScreen(newScreen);
- if (newScreen && shouldRecreate)
+ if (shouldShow)
+ q->setVisible(true);
+ else if (newScreen && shouldRecreate)
create(true);
emitScreenChangedRecursion(newScreen);
}
@@ -1600,6 +1603,7 @@ void QWindow::destroy()
QGuiApplicationPrivate::tabletPressTarget = parent();
bool wasVisible = isVisible();
+ d->visibilityOnDestroy = wasVisible && d->platformWindow;
setVisible(false);
@@ -1683,7 +1687,7 @@ bool QWindow::setMouseGrabEnabled(bool grab)
QScreen *QWindow::screen() const
{
Q_D(const QWindow);
- return d->parentWindow ? d->parentWindow->screen() : d->topLevelScreen;
+ return d->parentWindow ? d->parentWindow->screen() : d->topLevelScreen.data();
}
/*!
@@ -1703,7 +1707,7 @@ void QWindow::setScreen(QScreen *newScreen)
Q_D(QWindow);
if (!newScreen)
newScreen = QGuiApplication::primaryScreen();
- d->setTopLevelScreen(newScreen, true /* recreate */);
+ d->setTopLevelScreen(newScreen, newScreen != 0);
}
/*!
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index c496d7716b..9151e76ea4 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -45,6 +45,7 @@
// We mean it.
//
+#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
#include <qpa/qplatformwindow.h>
@@ -73,6 +74,7 @@ public:
, parentWindow(0)
, platformWindow(0)
, visible(false)
+ , visibilityOnDestroy(false)
, exposed(false)
, windowState(Qt::WindowNoState)
, visibility(QWindow::Hidden)
@@ -147,6 +149,7 @@ public:
QWindow *parentWindow;
QPlatformWindow *platformWindow;
bool visible;
+ bool visibilityOnDestroy;
bool exposed;
QSurfaceFormat requestedFormat;
QString windowTitle;
@@ -175,7 +178,7 @@ public:
int updateTimer;
QPointer<QWindow> transientParent;
- QScreen *topLevelScreen;
+ QPointer<QScreen> topLevelScreen;
#ifndef QT_NO_CURSOR
QCursor cursor;