From 5f504166203d9562ef5b41a0f18ae191aa34ee63 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Wed, 25 Jun 2014 15:09:09 +0200 Subject: [PATCH] Make it possible to know when a screen is being removed So far, we had to listen to the QObject::destroyed signal from the QScreen class to figure out whether a screen was removed. Often, this is already too late, given that most of the QWindows have been moved by then and we don't get to react before the windows are being set to the primary screen. This patch introduces a new signal that will notify about a screen removal before the screen is started to be destroyed, so that the application gets to decide what to do with the screens before Qt decides to move things around. [ChangeLog][QtGui][QGuiApplication] Added QGuiApplication::screenRemoved signal to inform that a screen has been removed, before Qt reacts to it. Change-Id: I99304179f4d345cae581a87baac6cff7b8773dea Reviewed-by: Shawn Rutledge --- src/gui/kernel/qguiapplication.cpp | 14 +++++++++++++- src/gui/kernel/qguiapplication.h | 1 + src/gui/kernel/qscreen.cpp | 10 ++++++++++ src/gui/kernel/qscreen.h | 1 + tests/manual/qscreen/main.cpp | 11 +++++++++++ tests/manual/qscreen/propertywatcher.cpp | 3 +-- 6 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 87c95e64209..96bea942eae 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -897,7 +897,19 @@ QList QGuiApplication::screens() This signal is emitted whenever a new screen \a screen has been added to the system. - \sa screens(), primaryScreen() + \sa screens(), primaryScreen(), screenRemoved() +*/ + +/*! + \fn void QGuiApplication::screenRemoved(QScreen *screen) + + This signal is emitted whenever a \a screen is removed from the system. It + provides an opportunity to manage the windows on the screen before Qt falls back + to moving them to the primary screen. + + \sa screens(), screenAdded(), QObject::destroyed(), QWindow::setScreen() + + \since 5.4 */ diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 1b1e1dabfff..6e751e1275a 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -165,6 +165,7 @@ public: Q_SIGNALS: void fontDatabaseChanged(); void screenAdded(QScreen *screen); + void screenRemoved(QScreen *screen); void lastWindowClosed(); void focusObjectChanged(QObject *focusObject); void focusWindowChanged(QWindow *focusWindow); diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 70ee631fc83..90f48d45931 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -74,6 +74,16 @@ QScreen::QScreen(QPlatformScreen *screen) { } + +/*! + Destroys the screen. + */ +QScreen::~QScreen() +{ + if (qApp) + Q_EMIT qApp->screenRemoved(this); +} + /*! Get the platform screen handle. */ diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h index bdd59396573..9e439f5a20b 100644 --- a/src/gui/kernel/qscreen.h +++ b/src/gui/kernel/qscreen.h @@ -89,6 +89,7 @@ class Q_GUI_EXPORT QScreen : public QObject Q_PROPERTY(qreal refreshRate READ refreshRate NOTIFY refreshRateChanged) public: + ~QScreen(); QPlatformScreen *handle() const; QString name() const; diff --git a/tests/manual/qscreen/main.cpp b/tests/manual/qscreen/main.cpp index 905c7d6f770..c085d3fd5b3 100644 --- a/tests/manual/qscreen/main.cpp +++ b/tests/manual/qscreen/main.cpp @@ -49,6 +49,9 @@ int i = 0; +typedef QHash ScreensHash; +Q_GLOBAL_STATIC(ScreensHash, props); + void updateSiblings(PropertyWatcher* w) { QLineEdit *siblingsField = w->findChild("siblings"); @@ -88,12 +91,19 @@ void screenAdded(QScreen* screen) geom.moveCenter(screen->geometry().center()); w->move(geom.topLeft()); + props->insert(screen, w); + // workaround for the fact that virtualSiblings is not a property, // thus there is no change notification: // allow the user to update the field manually QObject::connect(w, &PropertyWatcher::updatedAllFields, &updateSiblings); } +void screenRemoved(QScreen* screen) +{ + delete props->take(screen); +} + int main(int argc, char *argv[]) { QApplication a(argc, argv); @@ -101,5 +111,6 @@ int main(int argc, char *argv[]) foreach (QScreen *screen, screens) screenAdded(screen); QObject::connect((const QGuiApplication*)QGuiApplication::instance(), &QGuiApplication::screenAdded, &screenAdded); + QObject::connect((const QGuiApplication*)QGuiApplication::instance(), &QGuiApplication::screenRemoved, &screenRemoved); return a.exec(); } diff --git a/tests/manual/qscreen/propertywatcher.cpp b/tests/manual/qscreen/propertywatcher.cpp index 2213f4ac1d3..9e34c697990 100644 --- a/tests/manual/qscreen/propertywatcher.cpp +++ b/tests/manual/qscreen/propertywatcher.cpp @@ -82,6 +82,5 @@ void PropertyWatcher::updateAllFields() void PropertyWatcher::subjectDestroyed() { - hide(); - deleteLater(); + qDebug("screen destroyed"); }