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

View File

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

View File

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

View File

@@ -44,3 +44,29 @@ void wxDialog::EndWindowModal()
[NSApp endSheet: GetWXWindow()]; [NSApp endSheet: GetWXWindow()];
[GetWXWindow() orderOut: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

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

View File

@@ -436,26 +436,9 @@ void wxModalEventLoop::OSXDoRun()
#if OSX_USE_MODAL_SESSION #if OSX_USE_MODAL_SESSION
if ( m_modalWindow ) 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); BeginModalSession(m_modalWindow);
wxCFEventLoop::OSXDoRun(); wxCFEventLoop::OSXDoRun();
EndModalSession(); EndModalSession();
if ( restoreWorksWhenModal )
{
[(NSPanel*)parentWindow setWorksWhenModal:YES];
}
} }
else else
#endif #endif

View File

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

View File

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

View File

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

View File

@@ -23,21 +23,39 @@
#include "wx/osx/private.h" #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() bool wxDialog::OSXHasModalDialogsOpen()
{ {
return s_openDialogs > 0; return s_modalStack.size() > 0;
} }
void wxDialog::OSXBeginModalDialog() 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() void wxDialog::OSXEndModalDialog()
{ {
wxASSERT_MSG( s_openDialogs > 0, "incorrect internal modal dialog count"); wxASSERT_MSG( s_modalStack.back() == this, "incorrect internal modal dialog stack");
s_openDialogs--; 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() void wxDialog::Init()
@@ -146,9 +164,9 @@ int wxDialog::ShowModal()
wxModalEventLoop modalLoop(this); wxModalEventLoop modalLoop(this);
m_eventLoop = &modalLoop; m_eventLoop = &modalLoop;
wxDialog::OSXBeginModalDialog(); OSXBeginModalDialog();
modalLoop.Run(); modalLoop.Run();
wxDialog::OSXEndModalDialog(); OSXEndModalDialog();
m_eventLoop = NULL; m_eventLoop = NULL;