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.cpp73
1 files changed, 48 insertions, 25 deletions
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index 072a0bc5fa..376a93c758 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -3,7 +3,9 @@
#include "qwindowcontainer_p.h"
#include "qwidget_p.h"
+#include "qwidgetwindow_p.h"
#include <QtGui/qwindow.h>
+#include <QtGui/private/qwindow_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#include <QDebug>
@@ -14,6 +16,8 @@
#include <QAbstractScrollArea>
#include <QPainter>
+#include <QtCore/qpointer.h>
+
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
@@ -25,7 +29,6 @@ public:
QWindowContainerPrivate()
: window(nullptr)
- , oldFocusWindow(nullptr)
, usesNativeWidgets(false)
{
}
@@ -100,7 +103,6 @@ public:
}
QPointer<QWindow> window;
- QWindow *oldFocusWindow;
QWindow fakeParent;
uint usesNativeWidgets : 1;
@@ -162,11 +164,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);
}
@@ -184,6 +206,7 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt:
}
d->window = embeddedWindow;
+ d->window->installEventFilter(this);
QString windowName = d->window->objectName();
if (windowName.isEmpty())
@@ -196,7 +219,8 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt:
setAcceptDrops(true);
- connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow*)), this, SLOT(focusWindowChanged(QWindow*)));
+ connect(containedWindow(), &QWindow::minimumHeightChanged, this, &QWindowContainer::updateGeometry);
+ connect(containedWindow(), &QWindow::minimumWidthChanged, this, &QWindowContainer::updateGeometry);
}
QWindow *QWindowContainer::containedWindow() const
@@ -217,29 +241,14 @@ QWindowContainer::~QWindowContainer()
// QEvent::PlatformSurface delivery relies on virtuals. Getting
// SurfaceAboutToBeDestroyed can be essential for OpenGL, Vulkan, etc.
// QWindow subclasses in particular. Keep these working.
- if (d->window)
+ if (d->window) {
+ d->window->removeEventFilter(this);
d->window->destroy();
+ }
delete d->window;
}
-
-
-/*!
- \internal
- */
-
-void QWindowContainer::focusWindowChanged(QWindow *focusWindow)
-{
- Q_D(QWindowContainer);
- d->oldFocusWindow = focusWindow;
- if (focusWindow == d->window) {
- QWidget *widget = QApplication::focusWidget();
- if (widget)
- widget->clearFocus();
- }
-}
-
/*!
\internal
*/
@@ -254,8 +263,12 @@ bool QWindowContainer::eventFilter(QObject *o, QEvent *e)
QChildEvent *ce = static_cast<QChildEvent *>(e);
if (ce->child() == d->window) {
o->removeEventFilter(this);
+ d->window->removeEventFilter(this);
d->window = nullptr;
}
+ } else if (e->type() == QEvent::FocusIn) {
+ if (o == d->window)
+ setFocus(Qt::ActiveWindowFocusReason);
}
return false;
}
@@ -305,11 +318,16 @@ bool QWindowContainer::event(QEvent *e)
break;
case QEvent::FocusIn:
if (d->window->parent()) {
- if (d->oldFocusWindow != d->window) {
+ if (QGuiApplication::focusWindow() != d->window) {
+ QFocusEvent *event = static_cast<QFocusEvent *>(e);
+ const auto reason = event->reason();
+ QWindowPrivate::FocusTarget target = QWindowPrivate::FocusTarget::Current;
+ if (reason == Qt::TabFocusReason)
+ target = QWindowPrivate::FocusTarget::First;
+ else if (reason == Qt::BacktabFocusReason)
+ target = QWindowPrivate::FocusTarget::Last;
+ qt_window_private(d->window)->setFocusToTarget(target);
d->window->requestActivate();
- } else {
- QWidget *next = nextInFocusChain();
- next->setFocus();
}
}
break;
@@ -346,6 +364,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)
{