Allow to prevent blocking of native dialogs by a proxy Qt dialog

When native dialogs become visible, their invisible proxy Qt dialog
blocks input to Qt windows. It is intended for native dialogs which
can't block Qt windows themselves, e.g. on Android. But this behavior
is incompatible with native dialogs which are implemented as in-process
Qt windows, because the proxy dialog blocks them as well.

This change introduces QPlatformDialogHelper::DialogIsQtWindow
style which allows to detect such cases and prevent blocking.

Change-Id: I8f1f741e05d09f2c27192890bcec35fdd2e8f074
Task-number: QTBUG-58116
Reviewed-by: Alberto Mardegan <mardy@users.sourceforge.net>
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Alexander Volkov 2015-12-25 14:24:44 +03:00 committed by Shawn Rutledge
parent 73bc1cf92f
commit eafca2229b
3 changed files with 32 additions and 0 deletions

View File

@ -61,6 +61,18 @@ QT_BEGIN_NAMESPACE
*/
/*!
\enum QPlatformDialogHelper::StyleHint
This enum type specifies platform-specific style hints.
\value DialogIsQtWindow Indicates that a platform-specific dialog is implemented
as in-process Qt window. It allows to prevent blocking the
dialog by an invisible proxy Qt dialog.
\sa styleHint()
*/
static const int buttonRoleLayouts[2][6][14] =
{
// Qt::Horizontal

View File

@ -80,6 +80,7 @@ class Q_GUI_EXPORT QPlatformDialogHelper : public QObject
Q_OBJECT
public:
enum StyleHint {
DialogIsQtWindow
};
enum DialogCode { Rejected, Accepted };

View File

@ -731,6 +731,20 @@ void QDialog::setVisible(bool visible)
if (!testAttribute(Qt::WA_DontShowOnScreen) && d->canBeNativeDialog() && d->setNativeDialogVisible(visible))
return;
// We should not block windows by the invisible modal dialog
// if a platform-specific dialog is implemented as an in-process
// Qt window, because in this case it will also be blocked.
const bool dontBlockWindows = testAttribute(Qt::WA_DontShowOnScreen)
&& d->styleHint(QPlatformDialogHelper::DialogIsQtWindow).toBool();
Qt::WindowModality oldModality;
bool wasModalitySet;
if (dontBlockWindows) {
oldModality = windowModality();
wasModalitySet = testAttribute(Qt::WA_SetWindowModality);
setWindowModality(Qt::NonModal);
}
if (visible) {
if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
return;
@ -797,6 +811,11 @@ void QDialog::setVisible(bool visible)
d->eventLoop->exit();
}
if (dontBlockWindows) {
setWindowModality(oldModality);
setAttribute(Qt::WA_SetWindowModality, wasModalitySet);
}
#if QT_CONFIG(pushbutton)
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
if (d->mainDef && isActiveWindow()