Cocoa integration - implement Qt::WindowModal file dialogs

Previously, for Qt::WindowModal dialogs  we were creating modal sheet with beginSheetModalForWindow:
and later (from exec) calling -runModal, essentially making a window modal dialog into (now) application
modal sheet, which is not right- it's centered relative to desktop and the jump from window modal sheet's
position (centered relative to a window) to application modal was quite visible.
Now, instead of [panel runModal] (== [NSApp runModalForWindow:panel])
we call [NSApp runModalForWindow:theRequiredWindow].

Change-Id: I793dc72c7d1fe96497bb35754f4d0eac9a5e00e5
Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
This commit is contained in:
Timur Pocheptsov 2015-04-24 16:48:14 +02:00
parent 2ca1253b13
commit 21e6c7ae47
5 changed files with 33 additions and 8 deletions

View File

@ -137,6 +137,12 @@ QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHi
return QVariant();
}
void QPlatformDialogHelper::execModalForWindow(QWindow *parent)
{
Q_UNUSED(parent);
exec();
}
// Font dialog
class QFontDialogOptionsPrivate : public QSharedData

View File

@ -145,6 +145,7 @@ public:
virtual QVariant styleHint(StyleHint hint) const;
virtual void exec() = 0;
virtual void execModalForWindow(QWindow *parent);
virtual bool show(Qt::WindowFlags windowFlags,
Qt::WindowModality windowModality,
QWindow *parent) = 0;

View File

@ -51,6 +51,7 @@ public:
virtual ~QCocoaFileDialogHelper();
void exec();
void execModalForWindow(QWindow *parent);
bool defaultNameFilterDisables() const;

View File

@ -254,17 +254,22 @@ static QString strippedText(QString s)
|| [self panel:nil shouldShowFilename:filepath];
[self updateProperties];
QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
[mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""];
NSWindow *nsparent = static_cast<NSWindow *>(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent));
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
[mSavePanel beginSheetModalForWindow:nsparent completionHandler:^(NSInteger result){
mReturnCode = result;
if (mHelper)
mHelper->QNSOpenSavePanelDelegate_panelClosed(result == NSOKButton);
[[NSApplication sharedApplication] stopModalWithCode:result];
}];
mReturnCode = [[NSApplication sharedApplication] runModalForWindow:nsparent];
QAbstractEventDispatcher::instance()->interrupt();
if (mHelper)
mHelper->QNSOpenSavePanelDelegate_panelClosed(mReturnCode == NSOKButton);
}
- (BOOL)isHiddenFile:(NSString *)filename isDir:(BOOL)isDir
@ -706,14 +711,15 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate()
bool QCocoaFileDialogHelper::showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent)
{
Q_UNUSED(parent)
createNSOpenSavePanelDelegate();
if (!mDelegate)
return false;
if (windowModality == Qt::NonModal)
[mDelegate showModelessPanel];
else if (windowModality == Qt::WindowModal && parent)
[mDelegate showWindowModalSheet:parent];
// no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel()
// no need to show a Qt::ApplicationModal dialog here, since it will be done in exec;
// Qt::WindowModal will be done in execModalForWindow.
return true;
}
@ -745,6 +751,14 @@ void QCocoaFileDialogHelper::exec()
}
void QCocoaFileDialogHelper::execModalForWindow(QWindow *parent)
{
if (!parent)
return exec();
[mDelegate showWindowModalSheet:parent];
}
bool QCocoaFileDialogHelper::defaultNameFilterDisables() const
{
return true;

View File

@ -534,7 +534,10 @@ int QDialog::exec()
QPointer<QDialog> guard = this;
if (d->nativeDialogInUse) {
d->platformHelper()->exec();
if (windowModality() == Qt::WindowModal)
d->platformHelper()->execModalForWindow(d->parentWindow());
else
d->platformHelper()->exec();
} else {
QEventLoop eventLoop;
d->eventLoop = &eventLoop;