diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2017-02-09 16:37:37 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2017-02-15 23:00:43 +0000 |
commit | ee0edf1b0aa36cfdd5d9628b2bbeb1fb590a3290 (patch) | |
tree | 6ce0b71ab2a303ab21bc3964f2ec3ac7a95777d0 | |
parent | bf2160e72cd8840a8e604438cbdc807483ac980a (diff) |
QWindow: prevent window reparenting into Qt::Desktop windows
Qt::Desktop exists to support QDesktopWidget, which predates the QScreen
API. QWidget internally has checks that prevents you from reparenting a
QWidget into a QDesktopWidget, so we should have the same limitations on
the QWindow level. This allows platform plugins to implement Qt::Desktop
as simple (possibly shared) wrappers around QScreen without having to
allocate native window resources for each desktop window.
Change-Id: Ia1bac506febd3d827a6e0b8ad3bfd95be0cc7f9d
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 35 | ||||
-rw-r--r-- | src/gui/kernel/qwindow_p.h | 2 |
2 files changed, 22 insertions, 15 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 6092b08ea1..9d41a72072 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -155,8 +155,17 @@ QWindow::QWindow(QScreen *targetScreen) , QSurface(QSurface::Window) { Q_D(QWindow); - d->connectToScreen(targetScreen ? targetScreen : QGuiApplication::primaryScreen()); - d->init(); + d->init(targetScreen); +} + +static QWindow *nonDesktopParent(QWindow *parent) +{ + if (parent && parent->type() == Qt::Desktop) { + qWarning("QWindows can not be reparented into desktop windows"); + return nullptr; + } + + return parent; } /*! @@ -170,14 +179,8 @@ QWindow::QWindow(QScreen *targetScreen) \sa setParent() */ QWindow::QWindow(QWindow *parent) - : QObject(*new QWindowPrivate(), parent) - , QSurface(QSurface::Window) + : QWindow(*new QWindowPrivate(), parent) { - Q_D(QWindow); - d->parentWindow = parent; - if (!parent) - d->connectToScreen(QGuiApplication::primaryScreen()); - d->init(); } /*! @@ -193,13 +196,10 @@ QWindow::QWindow(QWindow *parent) \sa setParent() */ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent) - : QObject(dd, parent) + : QObject(dd, nonDesktopParent(parent)) , QSurface(QSurface::Window) { Q_D(QWindow); - d->parentWindow = parent; - if (!parent) - d->connectToScreen(QGuiApplication::primaryScreen()); d->init(); } @@ -215,10 +215,15 @@ QWindow::~QWindow() QGuiApplicationPrivate::instance()->modalWindowList.removeOne(this); } -void QWindowPrivate::init() +void QWindowPrivate::init(QScreen *targetScreen) { Q_Q(QWindow); + parentWindow = static_cast<QWindow *>(q->QObject::parent()); + + if (!parentWindow) + connectToScreen(targetScreen ? targetScreen : QGuiApplication::primaryScreen()); + // If your application aborts here, you are probably creating a QWindow // before the screen list is populated. if (Q_UNLIKELY(!parentWindow && !topLevelScreen)) { @@ -671,6 +676,8 @@ QWindow *QWindow::parent() const */ void QWindow::setParent(QWindow *parent) { + parent = nonDesktopParent(parent); + Q_D(QWindow); if (d->parentWindow == parent) return; diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index d1727a1c57..272401453a 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -113,7 +113,7 @@ public: { } - void init(); + void init(QScreen *targetScreen = nullptr); void maybeQuitOnLastWindowClosed(); #ifndef QT_NO_CURSOR |