backport of r15902

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@75928 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor
2014-02-18 17:47:59 +00:00
parent 6e277a8848
commit 98dc6aa95c

View File

@@ -32,9 +32,24 @@
#include "wx/log.h" #include "wx/log.h"
#include "wx/scopeguard.h" #include "wx/scopeguard.h"
#include "wx/vector.h"
#include "wx/hashmap.h"
#include "wx/osx/private.h" #include "wx/osx/private.h"
struct wxModalSessionStackElement
{
WXWindow dummyWindow;
void* modalSession;
};
typedef wxVector<wxModalSessionStackElement> wxModalSessionStack;
WX_DECLARE_HASH_MAP(wxGUIEventLoop*, wxModalSessionStack*, wxPointerHash, wxPointerEqual,
wxModalSessionStackMap);
static wxModalSessionStackMap gs_modalSessionStackMap;
// ============================================================================ // ============================================================================
// wxEventLoop implementation // wxEventLoop implementation
// ============================================================================ // ============================================================================
@@ -110,6 +125,7 @@ wxGUIEventLoop::wxGUIEventLoop()
wxGUIEventLoop::~wxGUIEventLoop() wxGUIEventLoop::~wxGUIEventLoop()
{ {
wxASSERT( gs_modalSessionStackMap.find( this ) == gs_modalSessionStackMap.end() );
wxASSERT( m_modalSession == nil ); wxASSERT( m_modalSession == nil );
wxASSERT( m_dummyWindow == nil ); wxASSERT( m_dummyWindow == nil );
wxASSERT( m_modalNestedLevel == 0 ); wxASSERT( m_modalNestedLevel == 0 );
@@ -474,16 +490,35 @@ bool wxModalEventLoop::ProcessIdle()
void wxGUIEventLoop::BeginModalSession( wxWindow* modalWindow ) void wxGUIEventLoop::BeginModalSession( wxWindow* modalWindow )
{ {
WXWindow nsnow = nil; WXWindow nsnow = nil;
if ( m_modalNestedLevel > 0 ) m_modalNestedLevel++;
if ( m_modalNestedLevel > 1 )
{ {
wxASSERT_MSG( m_modalWindow == modalWindow, "Nested Modal Sessions must be based on same window"); wxModalSessionStack* stack = NULL;
m_modalNestedLevel++;
return; if ( m_modalNestedLevel == 2 )
{
stack = new wxModalSessionStack;
gs_modalSessionStackMap[this] = stack;
}
else
{
stack = gs_modalSessionStackMap[this];
}
wxModalSessionStackElement element;
element.dummyWindow = m_dummyWindow;
element.modalSession = m_modalSession;
stack->push_back(element);
// shortcut if nothing changed in this level
if ( m_modalWindow == modalWindow )
return;
} }
m_modalWindow = modalWindow; m_modalWindow = modalWindow;
m_modalNestedLevel = 1;
if ( modalWindow ) if ( modalWindow )
{ {
@@ -505,9 +540,9 @@ void wxGUIEventLoop::BeginModalSession( wxWindow* modalWindow )
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:YES defer:YES
]; ];
[nsnow orderOut:nil];
m_dummyWindow = nsnow; m_dummyWindow = nsnow;
} }
[nsnow orderOut:nil];
m_modalSession = [NSApp beginModalSessionForWindow:nsnow]; m_modalSession = [NSApp beginModalSessionForWindow:nsnow];
wxASSERT_MSG(m_modalSession != NULL, "modal session couldn't be started"); wxASSERT_MSG(m_modalSession != NULL, "modal session couldn't be started");
} }
@@ -518,7 +553,8 @@ void wxGUIEventLoop::EndModalSession()
wxASSERT_MSG(m_modalNestedLevel > 0, "incorrect modal nesting level"); wxASSERT_MSG(m_modalNestedLevel > 0, "incorrect modal nesting level");
if ( --m_modalNestedLevel == 0 ) --m_modalNestedLevel;
if ( m_modalNestedLevel == 0 )
{ {
[NSApp endModalSession:(NSModalSession)m_modalSession]; [NSApp endModalSession:(NSModalSession)m_modalSession];
m_modalSession = nil; m_modalSession = nil;
@@ -528,6 +564,32 @@ void wxGUIEventLoop::EndModalSession()
m_dummyWindow = nil; m_dummyWindow = nil;
} }
} }
else
{
wxModalSessionStack* stack = gs_modalSessionStackMap[this];
wxModalSessionStackElement element = stack->back();
stack->pop_back();
if( m_modalNestedLevel == 1 )
{
gs_modalSessionStackMap.erase(this);
delete stack;
}
if ( m_modalSession != element.modalSession )
{
[NSApp endModalSession:(NSModalSession)m_modalSession];
m_modalSession = element.modalSession;
}
if ( m_dummyWindow != element.dummyWindow )
{
if ( element.dummyWindow )
[element.dummyWindow release];
m_dummyWindow = element.dummyWindow;
}
}
} }
// //