From a629a6dc04515e7d01340e58d0161c84adb09e38 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 17 Oct 2022 15:19:51 +0200 Subject: [PATCH] QIOSMessageDialog::exec - work around 'windowsless' exec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the need for such scenario is arguable, we can imagine that some app first shows some message box (by calling QDialog::exec()), and then creates and shows the main UI/window/widget. Without such a widget, app's keyWindow is nil, its rootViewController is also nil and no alert is presented at all. To save the situation, we try hard and check the primary screen's uiWindow (using QIOSScreen::uiWindow) searching for any window and using its root view controller. Fixes: QTBUG-79977 Change-Id: I9bf38bdf540f1f1dbe42b86df94d6a1b4694e9f2 Reviewed-by: Tor Arne Vestbø (cherry picked from commit f50f6a456aca6f0782eab2bf475d4f9c86a21f4c) Reviewed-by: Qt Cherry-pick Bot --- .../platforms/ios/qiosmessagedialog.mm | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm index 4352963cdeb..b7e1f9a89f4 100644 --- a/src/plugins/platforms/ios/qiosmessagedialog.mm +++ b/src/plugins/platforms/ios/qiosmessagedialog.mm @@ -47,6 +47,7 @@ #include "qiosglobal.h" #include "quiview.h" +#include "qiosscreen.h" #include "qiosmessagedialog.h" QIOSMessageDialog::QIOSMessageDialog() @@ -147,6 +148,25 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win } UIWindow *window = parent ? reinterpret_cast(parent->winId()).window : qt_apple_sharedApplication().keyWindow; + if (!window) { + qCDebug(lcQpaWindow, "Attempting to exec a dialog without any window/widget visible."); + + auto *primaryScreen = static_cast(QGuiApplication::primaryScreen()->handle()); + Q_ASSERT(primaryScreen); + + window = primaryScreen->uiWindow(); + if (window.hidden) { + // With a window hidden, an attempt to present view controller + // below fails with a warning, that a view "is not a part of + // any view hierarchy". The UIWindow is initially hidden, + // as unhiding it is what hides the splash screen. + window.hidden = NO; + } + } + + if (!window) + return false; + [window.rootViewController presentViewController:m_alertController animated:YES completion:nil]; return true; }