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#if QT_CONFIG(accessibility)
223 QWindowPrivate::get(d->window)->setAccessibleParent(
this);
226 QString windowName = d->window->objectName();
227 if (windowName.isEmpty())
228 windowName = QString::fromUtf8(d->window->metaObject()->className());
229 d->fakeParent.setObjectName(windowName +
"ContainerFakeParent"_L1);
231 d->window->setParent(&d->fakeParent);
232 d->window->parent()->installEventFilter(
this);
233 d->window->setFlag(Qt::SubWindow);
235 setAcceptDrops(
true);
237 connect(containedWindow(), &QWindow::minimumHeightChanged,
this, &QWindowContainer::updateGeometry);
238 connect(containedWindow(), &QWindow::minimumWidthChanged,
this, &QWindowContainer::updateGeometry);
271bool QWindowContainer::eventFilter(QObject *o, QEvent *e)
273 Q_D(QWindowContainer);
277 if (e->type() == QEvent::ChildRemoved) {
278 QChildEvent *ce =
static_cast<QChildEvent *>(e);
279 if (ce->child() == d->window) {
280 o->removeEventFilter(
this);
281 d->window->removeEventFilter(
this);
282#if QT_CONFIG(accessibility)
283 auto *windowPrivate = QWindowPrivate::get(d->window);
284 if (windowPrivate->accessibleParent ==
this)
285 windowPrivate->setAccessibleParent(
nullptr);
289 }
else if (e->type() == QEvent::FocusIn) {
290 if (o == d->window) {
291 if (d->syncingFocus) {
292 d->syncingFocus =
false;
296 setFocus(Qt::ActiveWindowFocusReason);
306bool QWindowContainer::event(QEvent *e)
308 Q_D(QWindowContainer);
310 return QWidget::event(e);
312 QEvent::Type type = e->type();
322 case QEvent::PolishRequest:
326 d->updateUsesNativeWidgets();
327 if (d->isStillAnOrphan()) {
328 d->window->parent()->removeEventFilter(
this);
329 d->window->setParent(d->usesNativeWidgets
331 : window()->windowHandle());
332 d->fakeParent.destroy();
333 if (d->window->parent())
334 d->window->parent()->installEventFilter(
this);
336 if (d->window->parent()) {
337 d->markParentChain();
342 if (d->window->parent())
345 case QEvent::FocusIn:
346 if (d->window->parent()) {
347 if (QGuiApplication::focusWindow() != d->window && !d->syncingFocus) {
348 QFocusEvent *event =
static_cast<QFocusEvent *>(e);
349 const auto reason = event->reason();
350 QWindowPrivate::FocusTarget target = QWindowPrivate::FocusTarget::Current;
351 if (reason == Qt::TabFocusReason)
352 target = QWindowPrivate::FocusTarget::First;
353 else if (reason == Qt::BacktabFocusReason)
354 target = QWindowPrivate::FocusTarget::Last;
355 qt_window_private(d->window)->setFocusToTarget(target, reason);
356 d->syncingFocus =
true;
357 d->window->requestActivate();
360 QTimer::singleShot(200,
this, [
this]() {
361 Q_D(QWindowContainer);
362 d->syncingFocus =
false;
367#if QT_CONFIG(draganddrop)
369 case QEvent::DragMove:
370 case QEvent::DragLeave:
371 QCoreApplication::sendEvent(d->window, e);
372 return e->isAccepted();
373 case QEvent::DragEnter:
376 QCoreApplication::sendEvent(d->window, e);
383 static bool needsPunch = !QGuiApplicationPrivate::platformIntegration()->hasCapability(
384 QPlatformIntegration::TopStackedNativeChildWindows);
387 p.setCompositionMode(QPainter::CompositionMode_Source);
388 p.fillRect(rect(), Qt::transparent);
397 return QWidget::event(e);
419void QWindowContainer::toplevelAboutToBeDestroyed(QWidget *parent)
421 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
422 if (d->window->parent())
423 d->window->parent()->removeEventFilter(parent);
424 d->window->setParent(&d->fakeParent);
425 d->window->parent()->installEventFilter(parent);
427 qwindowcontainer_traverse(parent, toplevelAboutToBeDestroyed);
430void QWindowContainer::parentWasChanged(QWidget *parent)
432 if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
433 if (d->window->parent()) {
434 d->updateUsesNativeWidgets();
435 d->markParentChain();
436 QWidget *toplevel = d->usesNativeWidgets ? parent : parent->window();
437 if (!toplevel->windowHandle()) {
438 QWidgetPrivate *tld =
static_cast<QWidgetPrivate *>(QWidgetPrivate::get(toplevel));
439 tld->createTLExtra();
440 tld->createTLSysExtra();
441 Q_ASSERT(toplevel->windowHandle());
443 d->window->parent()->removeEventFilter(parent);
444 d->window->setParent(toplevel->windowHandle());
445 toplevel->windowHandle()->installEventFilter(parent);
446 d->fakeParent.destroy();
450 qwindowcontainer_traverse(parent, parentWasChanged);