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>
This commit is contained in:
Tor Arne Vestbø 2017-02-09 16:37:37 +01:00
parent bf2160e72c
commit ee0edf1b0a
2 changed files with 22 additions and 15 deletions

View File

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

View File

@ -113,7 +113,7 @@ public:
{
}
void init();
void init(QScreen *targetScreen = nullptr);
void maybeQuitOnLastWindowClosed();
#ifndef QT_NO_CURSOR