QPA: Cleanup native dialog modal execution
Remove the _q_platformRunNativeAppModalPanel() function, together with the launchNativeAppModalPanel() signal and emitLaunchNativeAppModalPanel() slot, which were previously used to run the modal loop inside the QDialog::exec() loop. This trick isn't necessary anymore, so remove the mechanism and code related to it. Rename QPlatformDialogHelper::platformNativeDialogModalHelp() to exec_sys(). This function is now responsible for both showing the native dialog and running the modal loop. QDialog:exec() now calls this function if a native dialog is in use (it does not call QEventLoop::exec() anymore). The dialogResultCode_sys() function was unused, so it has also been removed. This commit also removes some unused private slots that were left over from the port to QPA. Note that the comments in the Cocoa plugin are still valid and relevant, but this commit does not fix the scenarios mentioned. This will be done in a future commit. The Windows plugin needs minor changes. The QueuedConnections to accept() and reject() cause the deliver to come too late, resulting in crashes, hence the change to AutoConnection (which ends up being a DirectConnection). Change-Id: Ifc90325c945ca78737e60bf331929f03ecc52e0a Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com> Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
This commit is contained in:
parent
9f2f7a8f72
commit
ab947649eb
@ -90,26 +90,20 @@ public:
|
||||
|
||||
virtual QVariant styleHint(StyleHint hint) const;
|
||||
|
||||
virtual void platformNativeDialogModalHelp() = 0;
|
||||
virtual void _q_platformRunNativeAppModalPanel() = 0;
|
||||
virtual void exec_sys() = 0;
|
||||
|
||||
virtual void deleteNativeDialog_sys() = 0;
|
||||
|
||||
virtual bool show_sys(Qt::WindowFlags windowFlags,
|
||||
Qt::WindowModality windowModality,
|
||||
QWindow *parent) = 0;
|
||||
virtual void hide_sys() = 0;
|
||||
|
||||
virtual DialogCode dialogResultCode_sys() = 0;
|
||||
|
||||
static QVariant defaultStyleHint(QPlatformDialogHelper::StyleHint hint);
|
||||
|
||||
Q_SIGNALS:
|
||||
void launchNativeAppModalPanel();
|
||||
void accept();
|
||||
void reject();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void emitLaunchNativeAppModalPanel();
|
||||
};
|
||||
|
||||
class Q_GUI_EXPORT QColorDialogOptions
|
||||
|
@ -94,11 +94,6 @@ QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHi
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void QPlatformDialogHelper::emitLaunchNativeAppModalPanel()
|
||||
{
|
||||
emit launchNativeAppModalPanel();
|
||||
}
|
||||
|
||||
// Font dialog
|
||||
|
||||
class QFontDialogOptionsPrivate : public QSharedData
|
||||
|
@ -53,13 +53,11 @@ public:
|
||||
QCocoaColorDialogHelper();
|
||||
virtual ~QCocoaColorDialogHelper();
|
||||
|
||||
void platformNativeDialogModalHelp();
|
||||
void _q_platformRunNativeAppModalPanel();
|
||||
void exec_sys();
|
||||
void deleteNativeDialog_sys();
|
||||
bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
|
||||
void hide_sys();
|
||||
|
||||
DialogCode dialogResultCode_sys();
|
||||
void setCurrentColor_sys(const QColor&);
|
||||
QColor currentColor_sys() const;
|
||||
|
||||
|
@ -345,27 +345,14 @@ QCocoaColorDialogHelper::QCocoaColorDialogHelper() :
|
||||
QCocoaColorDialogHelper::~QCocoaColorDialogHelper()
|
||||
{ }
|
||||
|
||||
void QCocoaColorDialogHelper::platformNativeDialogModalHelp()
|
||||
void QCocoaColorDialogHelper::exec_sys()
|
||||
{
|
||||
// Do a queued meta-call to open the native modal dialog so it opens after the new
|
||||
// event loop has started to execute (in QDialog::exec). Using a timer rather than
|
||||
// a queued meta call is intentional to ensure that the call is only delivered when
|
||||
// [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
|
||||
// running (which is the case if e.g a top-most QEventLoop has been
|
||||
// interrupted, and the second-most event loop has not yet been reactivated (regardless
|
||||
// if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
|
||||
QTimer::singleShot(1, this, SIGNAL(launchNativeAppModalPanel()));
|
||||
}
|
||||
|
||||
void QCocoaColorDialogHelper::_q_platformRunNativeAppModalPanel()
|
||||
{
|
||||
// TODO:
|
||||
#if 0
|
||||
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
|
||||
#endif
|
||||
// Note: If NSApp is not running (which is the case if e.g a top-most
|
||||
// QEventLoop has been interrupted, and the second-most event loop has not
|
||||
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
|
||||
// showing a native modal dialog will fail.
|
||||
QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *>(mDelegate);
|
||||
[delegate runApplicationModalPanel];
|
||||
if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
|
||||
if ([delegate runApplicationModalPanel])
|
||||
emit accept();
|
||||
else
|
||||
emit reject();
|
||||
@ -395,14 +382,6 @@ void QCocoaColorDialogHelper::hide_sys()
|
||||
[reinterpret_cast<QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *>(mDelegate)->mColorPanel close];
|
||||
}
|
||||
|
||||
QCocoaColorDialogHelper::DialogCode QCocoaColorDialogHelper::dialogResultCode_sys()
|
||||
{
|
||||
if (!mDelegate)
|
||||
return QPlatformDialogHelper::Rejected;
|
||||
QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *>(mDelegate);
|
||||
return [delegate dialogResultCode];
|
||||
}
|
||||
|
||||
void QCocoaColorDialogHelper::setCurrentColor_sys(const QColor &color)
|
||||
{
|
||||
if (!mDelegate)
|
||||
|
@ -56,15 +56,13 @@ public:
|
||||
QCocoaFileDialogHelper();
|
||||
virtual ~QCocoaFileDialogHelper();
|
||||
|
||||
void platformNativeDialogModalHelp();
|
||||
void _q_platformRunNativeAppModalPanel();
|
||||
void exec_sys();
|
||||
|
||||
bool defaultNameFilterDisables() const;
|
||||
|
||||
void deleteNativeDialog_sys();
|
||||
bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
|
||||
void hide_sys();
|
||||
QPlatformFileDialogHelper::DialogCode dialogResultCode_sys();
|
||||
void setDirectory_sys(const QString &directory);
|
||||
QString directory_sys() const;
|
||||
void selectFile_sys(const QString &filename);
|
||||
|
@ -672,36 +672,18 @@ bool QCocoaFileDialogHelper::hideCocoaFilePanel()
|
||||
}
|
||||
}
|
||||
|
||||
void QCocoaFileDialogHelper::platformNativeDialogModalHelp()
|
||||
void QCocoaFileDialogHelper::exec_sys()
|
||||
{
|
||||
// Do a queued meta-call to open the native modal dialog so it opens after the new
|
||||
// event loop has started to execute (in QDialog::exec). Using a timer rather than
|
||||
// a queued meta call is intentional to ensure that the call is only delivered when
|
||||
// [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
|
||||
// running (which is the case if e.g a top-most QEventLoop has been
|
||||
// interrupted, and the second-most event loop has not yet been reactivated (regardless
|
||||
// if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
|
||||
QTimer::singleShot(1, this, SIGNAL(launchNativeAppModalPanel()));
|
||||
}
|
||||
|
||||
void QCocoaFileDialogHelper::_q_platformRunNativeAppModalPanel()
|
||||
{
|
||||
// TODO:
|
||||
#if 0
|
||||
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
|
||||
#endif
|
||||
// Note: If NSApp is not running (which is the case if e.g a top-most
|
||||
// QEventLoop has been interrupted, and the second-most event loop has not
|
||||
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
|
||||
// showing a native modal dialog will fail.
|
||||
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
|
||||
[delegate runApplicationModalPanel];
|
||||
if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
|
||||
if ([delegate runApplicationModalPanel])
|
||||
emit accept();
|
||||
else
|
||||
emit reject();
|
||||
}
|
||||
|
||||
QPlatformDialogHelper::DialogCode QCocoaFileDialogHelper::dialogResultCode_sys()
|
||||
{
|
||||
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
|
||||
return [delegate dialogResultCode];
|
||||
}
|
||||
|
||||
bool QCocoaFileDialogHelper::defaultNameFilterDisables() const
|
||||
|
@ -56,15 +56,13 @@ public:
|
||||
QCocoaFontDialogHelper();
|
||||
virtual ~QCocoaFontDialogHelper();
|
||||
|
||||
void platformNativeDialogModalHelp();
|
||||
void _q_platformRunNativeAppModalPanel();
|
||||
void exec_sys();
|
||||
|
||||
void deleteNativeDialog_sys();
|
||||
|
||||
bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
|
||||
void hide_sys();
|
||||
|
||||
QPlatformDialogHelper::DialogCode dialogResultCode_sys();
|
||||
|
||||
void setCurrentFont_sys(const QFont &);
|
||||
QFont currentFont_sys() const;
|
||||
|
||||
|
@ -364,27 +364,14 @@ QCocoaFontDialogHelper::QCocoaFontDialogHelper() :
|
||||
QCocoaFontDialogHelper::~QCocoaFontDialogHelper()
|
||||
{ }
|
||||
|
||||
void QCocoaFontDialogHelper::platformNativeDialogModalHelp()
|
||||
void QCocoaFontDialogHelper::exec_sys()
|
||||
{
|
||||
// Do a queued meta-call to open the native modal dialog so it opens after the new
|
||||
// event loop has started to execute (in QDialog::exec). Using a timer rather than
|
||||
// a queued meta call is intentional to ensure that the call is only delivered when
|
||||
// [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
|
||||
// running (which is the case if e.g a top-most QEventLoop has been
|
||||
// interrupted, and the second-most event loop has not yet been reactivated (regardless
|
||||
// if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
|
||||
QTimer::singleShot(1, this, SIGNAL(launchNativeAppModalPanel()));
|
||||
}
|
||||
|
||||
void QCocoaFontDialogHelper::_q_platformRunNativeAppModalPanel()
|
||||
{
|
||||
// TODO:
|
||||
#if 0
|
||||
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
|
||||
#endif
|
||||
// Note: If NSApp is not running (which is the case if e.g a top-most
|
||||
// QEventLoop has been interrupted, and the second-most event loop has not
|
||||
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
|
||||
// showing a native modal dialog will fail.
|
||||
QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
|
||||
[delegate runApplicationModalPanel];
|
||||
if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
|
||||
if ([delegate runApplicationModalPanel])
|
||||
emit accept();
|
||||
else
|
||||
emit reject();
|
||||
@ -414,14 +401,6 @@ void QCocoaFontDialogHelper::hide_sys()
|
||||
[reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mFontPanel close];
|
||||
}
|
||||
|
||||
QCocoaFontDialogHelper::DialogCode QCocoaFontDialogHelper::dialogResultCode_sys()
|
||||
{
|
||||
if (!mDelegate)
|
||||
return QPlatformDialogHelper::Rejected;
|
||||
QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
|
||||
return [delegate dialogResultCode];
|
||||
}
|
||||
|
||||
void QCocoaFontDialogHelper::setCurrentFont_sys(const QFont &font)
|
||||
{
|
||||
NSFontManager *mgr = [NSFontManager sharedFontManager];
|
||||
|
@ -519,29 +519,12 @@ void QWindowsDialogHelperBase<BaseClass>::hide_sys()
|
||||
}
|
||||
|
||||
template <class BaseClass>
|
||||
void QWindowsDialogHelperBase<BaseClass>::platformNativeDialogModalHelp()
|
||||
void QWindowsDialogHelperBase<BaseClass>::exec_sys()
|
||||
{
|
||||
if (QWindowsContext::verboseDialogs)
|
||||
qDebug("%s" , __FUNCTION__);
|
||||
if (QWindowsNativeDialogBase *nd =nativeDialog())
|
||||
nd->metaObject()->invokeMethod(this,
|
||||
"emitLaunchNativeAppModalPanel",
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
template <class BaseClass>
|
||||
void QWindowsDialogHelperBase<BaseClass>::_q_platformRunNativeAppModalPanel()
|
||||
{
|
||||
if (QWindowsNativeDialogBase *nd =nativeDialog())
|
||||
nd->exec(m_ownerWindow);
|
||||
}
|
||||
|
||||
template <class BaseClass>
|
||||
QPlatformDialogHelper::DialogCode QWindowsDialogHelperBase<BaseClass>::dialogResultCode_sys()
|
||||
{
|
||||
if (QWindowsNativeDialogBase *nd =nativeDialog())
|
||||
return nd->result();
|
||||
return QPlatformDialogHelper::Rejected;
|
||||
if (QWindowsNativeDialogBase *nd = nativeDialog())
|
||||
nd->exec(m_ownerWindow);
|
||||
}
|
||||
|
||||
static inline bool snapToDefaultButtonHint()
|
||||
@ -1135,19 +1118,14 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
|
||||
QWindowsNativeFileDialogBase *result = QWindowsNativeFileDialogBase::create(options()->acceptMode());
|
||||
if (!result)
|
||||
return 0;
|
||||
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()),
|
||||
Qt::QueuedConnection);
|
||||
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()),
|
||||
Qt::QueuedConnection);
|
||||
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()));
|
||||
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()));
|
||||
QObject::connect(result, SIGNAL(directoryEntered(QString)),
|
||||
this, SIGNAL(directoryEntered(QString)),
|
||||
Qt::QueuedConnection);
|
||||
this, SIGNAL(directoryEntered(QString)));
|
||||
QObject::connect(result, SIGNAL(currentChanged(QString)),
|
||||
this, SIGNAL(currentChanged(QString)),
|
||||
Qt::QueuedConnection);
|
||||
this, SIGNAL(currentChanged(QString)));
|
||||
QObject::connect(result, SIGNAL(filterSelected(QString)),
|
||||
this, SIGNAL(filterSelected(QString)),
|
||||
Qt::QueuedConnection);
|
||||
this, SIGNAL(filterSelected(QString)));
|
||||
|
||||
// Apply settings.
|
||||
const QSharedPointer<QFileDialogOptions> &opts = options();
|
||||
|
@ -66,8 +66,7 @@ class QWindowsDialogHelperBase : public BaseClass
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void platformNativeDialogModalHelp();
|
||||
virtual void _q_platformRunNativeAppModalPanel();
|
||||
virtual void exec_sys();
|
||||
virtual void deleteNativeDialog_sys();
|
||||
virtual bool show_sys(Qt::WindowFlags windowFlags,
|
||||
Qt::WindowModality windowModality,
|
||||
@ -75,8 +74,6 @@ public:
|
||||
virtual void hide_sys();
|
||||
virtual QVariant styleHint(QPlatformDialogHelper::StyleHint) const;
|
||||
|
||||
virtual QPlatformDialogHelper::DialogCode dialogResultCode_sys();
|
||||
|
||||
virtual bool supportsNonModalDialog() const { return true; }
|
||||
|
||||
protected:
|
||||
|
@ -124,7 +124,6 @@ private:
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_newColorTypedIn(QRgb rgb))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_platformRunNativeAppModalPanel())
|
||||
friend class QColorShower;
|
||||
};
|
||||
|
||||
|
@ -88,8 +88,6 @@ QPlatformDialogHelper *QDialogPrivate::platformHelper() const
|
||||
if (m_platformHelper) {
|
||||
QObject::connect(m_platformHelper, SIGNAL(accept()), dialog, SLOT(accept()));
|
||||
QObject::connect(m_platformHelper, SIGNAL(reject()), dialog, SLOT(reject()));
|
||||
QObject::connect(m_platformHelper, SIGNAL(launchNativeAppModalPanel()),
|
||||
dialog, SLOT(_q_platformRunNativeAppModalPanel()));
|
||||
ncThis->initHelper(m_platformHelper);
|
||||
}
|
||||
}
|
||||
@ -118,13 +116,6 @@ bool QDialogPrivate::setNativeDialogVisible(bool visible)
|
||||
return nativeDialogInUse;
|
||||
}
|
||||
|
||||
void QDialogPrivate::_q_platformRunNativeAppModalPanel()
|
||||
{
|
||||
if (nativeDialogInUse)
|
||||
platformHelper()->_q_platformRunNativeAppModalPanel();
|
||||
}
|
||||
|
||||
|
||||
QVariant QDialogPrivate::styleHint(QPlatformDialogHelper::StyleHint hint) const
|
||||
{
|
||||
if (const QPlatformDialogHelper *helper = platformHelper())
|
||||
@ -535,13 +526,14 @@ int QDialog::exec()
|
||||
}
|
||||
show();
|
||||
|
||||
if (d->nativeDialogInUse)
|
||||
d->platformHelper()->platformNativeDialogModalHelp();
|
||||
|
||||
QEventLoop eventLoop;
|
||||
d->eventLoop = &eventLoop;
|
||||
QPointer<QDialog> guard = this;
|
||||
(void) eventLoop.exec(QEventLoop::DialogExec);
|
||||
if (d->nativeDialogInUse) {
|
||||
d->platformHelper()->exec_sys();
|
||||
} else {
|
||||
QEventLoop eventLoop;
|
||||
d->eventLoop = &eventLoop;
|
||||
(void) eventLoop.exec(QEventLoop::DialogExec);
|
||||
}
|
||||
if (guard.isNull())
|
||||
return QDialog::Rejected;
|
||||
d->eventLoop = 0;
|
||||
|
@ -117,7 +117,6 @@ protected:
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QDialog)
|
||||
Q_DISABLE_COPY(QDialog)
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_platformRunNativeAppModalPanel())
|
||||
|
||||
#ifdef Q_OS_WINCE_WM
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_doneAction())
|
||||
|
@ -79,7 +79,6 @@ public:
|
||||
nativeDialogInUse(false), m_platformHelper(0), m_platformHelperCreated(false)
|
||||
{}
|
||||
~QDialogPrivate() { delete m_platformHelper; }
|
||||
void _q_platformRunNativeAppModalPanel();
|
||||
|
||||
QWindow *parentWindow() const;
|
||||
bool setNativeDialogVisible(bool visible);
|
||||
|
@ -252,7 +252,6 @@ private:
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_fileRenamed(const QString &path,
|
||||
const QString oldName, const QString newName))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_platformRunNativeAppModalPanel())
|
||||
friend class QPlatformDialogHelper;
|
||||
};
|
||||
|
||||
|
@ -244,7 +244,6 @@ public:
|
||||
// dialog. Returning false means that a non-native dialog must be
|
||||
// used instead.
|
||||
bool canBeNativeDialog();
|
||||
QDialog::DialogCode dialogResultCode_sys();
|
||||
|
||||
void setDirectory_sys(const QString &directory);
|
||||
QString directory_sys() const;
|
||||
@ -346,15 +345,6 @@ inline QString QFileDialogPrivate::rootPath() const {
|
||||
return model->rootPath();
|
||||
}
|
||||
|
||||
inline QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys()
|
||||
{
|
||||
QDialog::DialogCode result = QDialog::Rejected;
|
||||
if (QPlatformDialogHelper *helper = platformHelper())
|
||||
if (helper->dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
|
||||
result = QDialog::Accepted;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void QFileDialogPrivate::setDirectory_sys(const QString &directory)
|
||||
{
|
||||
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
|
||||
|
@ -118,9 +118,6 @@ private:
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_styleHighlighted(int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sizeHighlighted(int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_updateSample())
|
||||
#if defined(Q_WS_MAC)
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
|
||||
#endif
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QFontDialog::FontDialogOptions)
|
||||
|
Loading…
Reference in New Issue
Block a user