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.cpp72
1 files changed, 65 insertions, 7 deletions
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index 847058e5b2..c15ec54f35 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -3,6 +3,7 @@
#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>
@@ -14,6 +15,8 @@
#include <QAbstractScrollArea>
#include <QPainter>
+#include <QtCore/qpointer.h>
+
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
@@ -162,11 +165,31 @@ 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);
}
@@ -191,11 +214,16 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt:
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
@@ -220,6 +248,9 @@ QWindowContainer::~QWindowContainer()
d->window->destroy();
delete d->window;
+
+ disconnect(qGuiApp, &QGuiApplication::focusWindowChanged,
+ this, &QWindowContainer::focusWindowChanged);
}
@@ -243,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);
@@ -251,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:
@@ -271,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();
@@ -328,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)
{
@@ -345,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);
}
@@ -363,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();
}