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 <shawn.rutledge@digia.com>
This commit is contained in:
Aleix Pol 2014-06-25 15:09:09 +02:00 committed by Frederik Gladhorn
parent 0541516907
commit 5f50416620
6 changed files with 37 additions and 3 deletions

View File

@ -897,7 +897,19 @@ QList<QScreen *> 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
*/

View File

@ -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);

View File

@ -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.
*/

View File

@ -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;

View File

@ -49,6 +49,9 @@
int i = 0;
typedef QHash<QScreen*, PropertyWatcher*> ScreensHash;
Q_GLOBAL_STATIC(ScreensHash, props);
void updateSiblings(PropertyWatcher* w)
{
QLineEdit *siblingsField = w->findChild<QLineEdit *>("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();
}

View File

@ -82,6 +82,5 @@ void PropertyWatcher::updateAllFields()
void PropertyWatcher::subjectDestroyed()
{
hide();
deleteLater();
qDebug("screen destroyed");
}