use Cocoa fix for nested modal loops for system dialogs also

This commit is contained in:
Stefan Csomor
2018-08-27 11:50:35 +02:00
parent fd569842b1
commit 99eba63796
10 changed files with 81 additions and 30 deletions

View File

@@ -140,7 +140,7 @@ int wxColourDialog::ShowModal()
//
// Start the color panel modal loop
//
wxDialog::OSXBeginModalDialog();
OSXBeginModalDialog();
NSModalSession session = [NSApp beginModalSessionForWindow:theColorPanel];
for (;;)
{
@@ -151,7 +151,7 @@ int wxColourDialog::ShowModal()
break;
}
[NSApp endModalSession:session];
wxDialog::OSXEndModalDialog();
OSXEndModalDialog();
//free up the memory for the delegates - we don't need them anymore
[theColorPanel setDelegate:nil];

View File

@@ -86,9 +86,9 @@ int wxFontDialog::ShowModal()
{
WX_HOOK_MODAL_DIALOG();
wxDialog::OSXBeginModalDialog();
OSXBeginModalDialog();
int retval = RunMixedFontDialog(this);
wxDialog::OSXEndModalDialog();
OSXEndModalDialog();
return retval ;
}

View File

@@ -532,7 +532,7 @@ int wxFontDialog::ShowModal()
// the color panel until the color panel closes, switching
// back to the font panel modal loop once it does close.
//
wxDialog::OSXBeginModalDialog();
OSXBeginModalDialog();
do
{
//
@@ -571,7 +571,7 @@ int wxFontDialog::ShowModal()
//out of its modal loop because the color panel was
//opened) return the font panel modal loop
}while([theFPDelegate isClosed] == NO);
wxDialog::OSXEndModalDialog();
OSXEndModalDialog();
//free up the memory for the delegates - we don't need them anymore
[theFPDelegate release];

View File

@@ -44,3 +44,29 @@ void wxDialog::EndWindowModal()
[NSApp endSheet: GetWXWindow()];
[GetWXWindow() orderOut:GetWXWindow()];
}
bool wxDialog::OSXGetWorksWhenModal()
{
bool worksWhenModal = false;
NSWindow* nswindow = IsModal() ? GetWXWindow() : nil;
if ( nswindow != nil )
{
if ( [nswindow isKindOfClass:[NSPanel class]] && [(NSPanel*)nswindow worksWhenModal] == YES )
{
[(NSPanel*)nswindow setWorksWhenModal:NO];
worksWhenModal = true;
}
}
return worksWhenModal;
}
void wxDialog::OSXSetWorksWhenModal(bool worksWhenModal)
{
NSWindow* nswindow = IsModal() ? GetWXWindow() : nil;
if ( nswindow != nil )
{
if ( [nswindow isKindOfClass:[NSPanel class]] && [(NSPanel*)nswindow worksWhenModal] == YES )
[(NSPanel*)nswindow setWorksWhenModal:worksWhenModal];
}
}

View File

@@ -116,9 +116,14 @@ int wxDirDialog::ShowModal()
m_path.clear();
int returnCode = -1;
OSXBeginModalDialog();
returnCode = (NSInteger)[oPanel runModalForDirectory:dir.AsNSString() file:nil types:nil];
ModalFinishedCallback(oPanel, returnCode);
OSXEndModalDialog();
return GetReturnCode();
}

View File

@@ -436,26 +436,9 @@ void wxModalEventLoop::OSXDoRun()
#if OSX_USE_MODAL_SESSION
if ( m_modalWindow )
{
bool restoreWorksWhenModal = false;
wxDialog* const parentDialog = wxDynamicCast(wxGetTopLevelParent(m_modalWindow->GetParent()), wxDialog);
NSWindow* parentWindow = parentDialog && parentDialog->IsModal() ? parentDialog->GetWXWindow() : nil;
if ( parentWindow != nil )
{
if ( [parentWindow isKindOfClass:[NSPanel class]] && [(NSPanel*)parentWindow worksWhenModal] == YES )
{
[(NSPanel*)parentWindow setWorksWhenModal:NO];
restoreWorksWhenModal = true;
}
}
BeginModalSession(m_modalWindow);
wxCFEventLoop::OSXDoRun();
EndModalSession();
if ( restoreWorksWhenModal )
{
[(NSPanel*)parentWindow setWorksWhenModal:YES];
}
}
else
#endif

View File

@@ -559,6 +559,8 @@ int wxFileDialog::ShowModal()
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
OSXBeginModalDialog();
if ( HasFlag(wxFD_SAVE) )
{
NSSavePanel* sPanel = [NSSavePanel savePanel];
@@ -627,6 +629,9 @@ int wxFileDialog::ShowModal()
ModalFinishedCallback(oPanel, returnCode);
}
OSXEndModalDialog();
wxGCC_WARNING_RESTORE(deprecated-declarations)

View File

@@ -168,8 +168,13 @@ int wxMessageDialog::ShowModal()
{
NSAlert* alert = (NSAlert*)ConstructNSAlert();
OSXBeginModalDialog();
int button = -1;
button = [alert runModal];
OSXEndModalDialog();
ModalFinishedCallback(alert, button);
[alert release];
}

View File

@@ -72,12 +72,16 @@ int wxMacPrintDialog::ShowModal()
[dict setValue:[NSNumber numberWithInt:m_printDialogData.GetMinPage()] forKey:@"com_apple_print_PrintSettings_PMFirstPage"];
[dict setValue:[NSNumber numberWithInt:m_printDialogData.GetMaxPage()] forKey:@"com_apple_print_PrintSettings_PMLastPage"];
OSXBeginModalDialog();
if ( (NSInteger)[panel runModalWithPrintInfo:printInfo] == NSOKButton )
{
result = wxID_OK;
m_printDialogData.GetPrintData().ConvertFromNative();
((wxOSXPrintData*)m_printDialogData.GetPrintData().GetNativeData())->TransferTo( &m_printDialogData );
}
OSXEndModalDialog();
return result;
}
@@ -93,6 +97,9 @@ int wxMacPageSetupDialog::ShowModal()
NSPageLayout *pageLayout = [NSPageLayout pageLayout];
NSPrintInfo* printInfo = ((wxOSXCocoaPrintData*)m_pageSetupData.GetPrintData().GetNativeData())->GetNSPrintInfo();
OSXBeginModalDialog();
if ( [pageLayout runModalWithPrintInfo:printInfo] == NSOKButton )
{
result = wxID_OK;
@@ -100,6 +107,8 @@ int wxMacPageSetupDialog::ShowModal()
m_pageSetupData.SetPaperSize( m_pageSetupData.GetPrintData().GetPaperSize() );
}
OSXEndModalDialog();
return result;
}

View File

@@ -23,21 +23,39 @@
#include "wx/osx/private.h"
static int s_openDialogs = 0;
wxVector<wxDialog*> wxDialog::s_modalStack;
#if wxOSX_USE_COCOA
wxVector<bool> wxDialog::s_modalWorksStack;
#endif
bool wxDialog::OSXHasModalDialogsOpen()
{
return s_openDialogs > 0;
return s_modalStack.size() > 0;
}
void wxDialog::OSXBeginModalDialog()
{
s_openDialogs++;
#if wxOSX_USE_COCOA
// turning off worksWhenModal on 'parent'
if ( s_modalStack.size() > 0 )
s_modalStack.back()->OSXSetWorksWhenModal(false);
s_modalWorksStack.push_back(OSXGetWorksWhenModal());
#endif
s_modalStack.push_back(this);
}
void wxDialog::OSXEndModalDialog()
{
wxASSERT_MSG( s_openDialogs > 0, "incorrect internal modal dialog count");
s_openDialogs--;
wxASSERT_MSG( s_modalStack.back() == this, "incorrect internal modal dialog stack");
s_modalStack.pop_back();
#if wxOSX_USE_COCOA
s_modalWorksStack.pop_back();
// restore worksWhenModal
if ( s_modalStack.size() > 0 )
s_modalStack.back()->OSXSetWorksWhenModal(s_modalWorksStack.back());
#endif
}
void wxDialog::Init()
@@ -146,9 +164,9 @@ int wxDialog::ShowModal()
wxModalEventLoop modalLoop(this);
m_eventLoop = &modalLoop;
wxDialog::OSXBeginModalDialog();
OSXBeginModalDialog();
modalLoop.Run();
wxDialog::OSXEndModalDialog();
OSXEndModalDialog();
m_eventLoop = NULL;