QIOSMessageDialog::exec - work around 'windowsless' exec

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.

Pick-to: 6.4 6.2 5.15
Fixes: QTBUG-79977
Change-Id: I9bf38bdf540f1f1dbe42b86df94d6a1b4694e9f2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Timur Pocheptsov 2022-10-17 15:19:51 +02:00
parent bb1f616ff1
commit f50f6a456a

View File

@ -11,6 +11,7 @@
#include "qiosglobal.h"
#include "quiview.h"
#include "qiosscreen.h"
#include "qiosmessagedialog.h"
using namespace Qt::StringLiterals;
@ -113,6 +114,25 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win
}
UIWindow *window = parent ? reinterpret_cast<UIView *>(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<QIOSScreen*>(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;
}