summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel/qwindowcontainer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/kernel/qwindowcontainer.cpp')
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp127
1 files changed, 72 insertions, 55 deletions
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index b4d889fdfa..c15ec54f35 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -1,44 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwindowcontainer_p.h"
#include "qwidget_p.h"
+#include "qwidgetwindow_p.h"
#include <QtGui/qwindow.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
@@ -50,8 +15,12 @@
#include <QAbstractScrollArea>
#include <QPainter>
+#include <QtCore/qpointer.h>
+
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
class QWindowContainerPrivate : public QWidgetPrivate
{
public:
@@ -196,16 +165,34 @@ public:
application can greatly hurt the overall performance of the
application.
+ \li Since 6.7, if \a window belongs to a widget (that is, \a window
+ was received from calling \l windowHandle()), no container will be
+ created. Instead, this function will return the widget itself, after
+ being reparented to \l parent. Since no container will be created,
+ \a flags will be ignored. In other words, if \a window belongs to
+ a widget, consider just reparenting that widget to \a parent instead
+ of using this function.
+
\endlist
*/
QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent, Qt::WindowFlags flags)
{
+ // Embedding a QWidget in a window container doesn't make sense,
+ // and has various issues in practice, so just return the widget
+ // itself.
+ if (auto *widgetWindow = qobject_cast<QWidgetWindow *>(window)) {
+ QWidget *widget = widgetWindow->widget();
+ if (flags != Qt::WindowFlags()) {
+ qWarning() << window << "refers to a widget:" << widget
+ << "WindowFlags" << flags << "will be ignored.";
+ }
+ widget->setParent(parent);
+ return widget;
+ }
return new QWindowContainer(window, parent, flags);
}
-
-
/*!
\internal
*/
@@ -219,24 +206,24 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt:
return;
}
- // The embedded QWindow must use the same logic as QWidget when it comes to the surface type.
- // Otherwise we may end up with BadMatch failures on X11.
- if (embeddedWindow->surfaceType() == QSurface::RasterSurface
- && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::RasterGLSurface)
- && !QCoreApplication::testAttribute(Qt::AA_ForceRasterWidgets))
- embeddedWindow->setSurfaceType(QSurface::RasterGLSurface);
-
d->window = embeddedWindow;
QString windowName = d->window->objectName();
if (windowName.isEmpty())
windowName = QString::fromUtf8(d->window->metaObject()->className());
- d->fakeParent.setObjectName(windowName + QLatin1String("ContainerFakeParent"));
+ d->fakeParent.setObjectName(windowName + "ContainerFakeParent"_L1);
d->window->setParent(&d->fakeParent);
+ d->window->parent()->installEventFilter(this);
+ d->window->setFlag(Qt::SubWindow);
+
setAcceptDrops(true);
- connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow*)), this, SLOT(focusWindowChanged(QWindow*)));
+ connect(qGuiApp, &QGuiApplication::focusWindowChanged,
+ this, &QWindowContainer::focusWindowChanged);
+
+ connect(containedWindow(), &QWindow::minimumHeightChanged, this, &QWindowContainer::updateGeometry);
+ connect(containedWindow(), &QWindow::minimumWidthChanged, this, &QWindowContainer::updateGeometry);
}
QWindow *QWindowContainer::containedWindow() const
@@ -261,6 +248,9 @@ QWindowContainer::~QWindowContainer()
d->window->destroy();
delete d->window;
+
+ disconnect(qGuiApp, &QGuiApplication::focusWindowChanged,
+ this, &QWindowContainer::focusWindowChanged);
}
@@ -284,6 +274,26 @@ void QWindowContainer::focusWindowChanged(QWindow *focusWindow)
\internal
*/
+bool QWindowContainer::eventFilter(QObject *o, QEvent *e)
+{
+ Q_D(QWindowContainer);
+ if (!d->window)
+ return false;
+
+ if (e->type() == QEvent::ChildRemoved) {
+ QChildEvent *ce = static_cast<QChildEvent *>(e);
+ if (ce->child() == d->window) {
+ o->removeEventFilter(this);
+ d->window = nullptr;
+ }
+ }
+ return false;
+}
+
+/*!
+ \internal
+ */
+
bool QWindowContainer::event(QEvent *e)
{
Q_D(QWindowContainer);
@@ -292,12 +302,6 @@ bool QWindowContainer::event(QEvent *e)
QEvent::Type type = e->type();
switch (type) {
- case QEvent::ChildRemoved: {
- QChildEvent *ce = static_cast<QChildEvent *>(e);
- if (ce->child() == d->window)
- d->window = nullptr;
- break;
- }
// The only thing we are interested in is making sure our sizes stay
// in sync, so do a catch-all case.
case QEvent::Resize:
@@ -312,10 +316,13 @@ bool QWindowContainer::event(QEvent *e)
case QEvent::Show:
d->updateUsesNativeWidgets();
if (d->isStillAnOrphan()) {
+ d->window->parent()->removeEventFilter(this);
d->window->setParent(d->usesNativeWidgets
? windowHandle()
: window()->windowHandle());
d->fakeParent.destroy();
+ if (d->window->parent())
+ d->window->parent()->installEventFilter(this);
}
if (d->window->parent()) {
d->markParentChain();
@@ -369,6 +376,11 @@ bool QWindowContainer::event(QEvent *e)
return QWidget::event(e);
}
+QSize QWindowContainer::minimumSizeHint() const
+{
+ return containedWindow() ? containedWindow()->minimumSize() : QSize(0, 0);
+}
+
typedef void (*qwindowcontainer_traverse_callback)(QWidget *parent);
static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse_callback callback)
{
@@ -386,7 +398,10 @@ static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse
void QWindowContainer::toplevelAboutToBeDestroyed(QWidget *parent)
{
if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent())
+ d->window->parent()->removeEventFilter(parent);
d->window->setParent(&d->fakeParent);
+ d->window->parent()->installEventFilter(parent);
}
qwindowcontainer_traverse(parent, toplevelAboutToBeDestroyed);
}
@@ -404,7 +419,9 @@ void QWindowContainer::parentWasChanged(QWidget *parent)
tld->createTLSysExtra();
Q_ASSERT(toplevel->windowHandle());
}
+ d->window->parent()->removeEventFilter(parent);
d->window->setParent(toplevel->windowHandle());
+ toplevel->windowHandle()->installEventFilter(parent);
d->fakeParent.destroy();
d->updateGeometry();
}