187QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent, Qt::WindowFlags flags)
192 if (
auto *widgetWindow = qobject_cast<QWidgetWindow *>(window)) {
193 QWidget *widget = widgetWindow->widget();
194 if (flags != Qt::WindowFlags()) {
195 qWarning() << window <<
"refers to a widget:" << widget
196 <<
"WindowFlags" << flags <<
"will be ignored.";
198 widget->setParent(parent);
201 return new QWindowContainer(window, parent, flags);
208QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt::WindowFlags flags)
209 : QWidget(*
new QWindowContainerPrivate, parent, flags)
211 Q_D(QWindowContainer);
212 if (Q_UNLIKELY(!embeddedWindow)) {
213 qWarning(
"QWindowContainer: embedded window cannot be null");
217 d->window = embeddedWindow;
218 d->window->installEventFilter(
this);
220 QString windowName = d->window->objectName();
221 if (windowName.isEmpty())
222 windowName = QString::fromUtf8(d->window->metaObject()->className());
223 d->fakeParent.setObjectName(windowName +
"ContainerFakeParent"_L1);
225 d->window->setParent(&d->fakeParent);
226 d->window->parent()->installEventFilter(
this);
227 d->window->setFlag(Qt::SubWindow);
229 setAcceptDrops(
true);
231 connect(containedWindow(), &QWindow::minimumHeightChanged,
this, &QWindowContainer::updateGeometry);
232 connect(containedWindow(), &QWindow::minimumWidthChanged,
this, &QWindowContainer::updateGeometry);
265bool QWindowContainer::eventFilter(QObject *o, QEvent *e)
267 Q_D(QWindowContainer);
271 if (e->type() == QEvent::ChildRemoved) {
272 QChildEvent *ce =
static_cast<QChildEvent *>(e);
273 if (ce->child() == d->window) {
274 o->removeEventFilter(
this);
275 d->window->removeEventFilter(
this);
278 }
else if (e->type() == QEvent::FocusIn) {
279 if (o == d->window) {
280 if (d->syncingFocus) {
281 d->syncingFocus =
false;
285 setFocus(Qt::ActiveWindowFocusReason);
295bool QWindowContainer::event(QEvent *e)
297 Q_D(QWindowContainer);
299 return QWidget::event(e);
301 QEvent::Type type = e->type();
311 case QEvent::PolishRequest:
315 d->updateUsesNativeWidgets();
316 if (d->isStillAnOrphan()) {
317 d->window->parent()->removeEventFilter(
this);
318 d->window->setParent(d->usesNativeWidgets
320 : window()->windowHandle());
321 d->fakeParent.destroy();
322 if (d->window->parent())
323 d->window->parent()->installEventFilter(
this);
325 if (d->window->parent()) {
326 d->markParentChain();
331 if (d->window->parent())
334 case QEvent::FocusIn:
335 if (d->window->parent()) {
336 if (QGuiApplication::focusWindow() != d->window && !d->syncingFocus) {
337 QFocusEvent *event =
static_cast<QFocusEvent *>(e);
338 const auto reason = event->reason();
339 QWindowPrivate::FocusTarget target = QWindowPrivate::FocusTarget::Current;
340 if (reason == Qt::TabFocusReason)
341 target = QWindowPrivate::FocusTarget::First;
342 else if (reason == Qt::BacktabFocusReason)
343 target = QWindowPrivate::FocusTarget::Last;
344 qt_window_private(d->window)->setFocusToTarget(target, reason);
345 d->syncingFocus =
true;
346 d->window->requestActivate();
349 QTimer::singleShot(200,
this, [
this]() {
350 Q_D(QWindowContainer);
351 d->syncingFocus =
false;
356#if QT_CONFIG(draganddrop)
358 case QEvent::DragMove:
359 case QEvent::DragLeave:
360 QCoreApplication::sendEvent(d->window, e);
361 return e->isAccepted();
362 case QEvent::DragEnter:
365 QCoreApplication::sendEvent(d->window, e);
372 static bool needsPunch = !QGuiApplicationPrivate::platformIntegration()->hasCapability(
373 QPlatformIntegration::TopStackedNativeChildWindows);
376 p.setCompositionMode(QPainter::CompositionMode_Source);
377 p.fillRect(rect(), Qt::transparent);
386 return QWidget::event(e);
408void QWindowContainer::toplevelAboutToBeDestroyed(QWidget *parent)
410 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
411 if (d->window->parent())
412 d->window->parent()->removeEventFilter(parent);
413 d->window->setParent(&d->fakeParent);
414 d->window->parent()->installEventFilter(parent);
416 qwindowcontainer_traverse(parent, toplevelAboutToBeDestroyed);
419void QWindowContainer::parentWasChanged(QWidget *parent)
421 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
422 if (d->window->parent()) {
423 d->updateUsesNativeWidgets();
424 d->markParentChain();
425 QWidget *toplevel = d->usesNativeWidgets ? parent : parent->window();
426 if (!toplevel->windowHandle()) {
427 QWidgetPrivate *tld =
static_cast<QWidgetPrivate *>(QWidgetPrivate::get(toplevel));
428 tld->createTLExtra();
429 tld->createTLSysExtra();
430 Q_ASSERT(toplevel->windowHandle());
432 d->window->parent()->removeEventFilter(parent);
433 d->window->setParent(toplevel->windowHandle());
434 toplevel->windowHandle()->installEventFilter(parent);
435 d->fakeParent.destroy();
439 qwindowcontainer_traverse(parent, parentWasChanged);