Fix hang when reparenting a frozen window in wxOSX
The wrong order of changing parent and freezing/thawing could result in hanging the application when reparenting frozen windows, e.g. when switching order of pages in a notebook. Closes #16722.
This commit is contained in:
		@@ -769,6 +769,30 @@ void wxWidgetCocoaImpl::SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEve
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void SetDrawingEnabledIfFrozenRecursive(wxWidgetCocoaImpl *impl, bool enable)
 | 
			
		||||
{
 | 
			
		||||
    if (!impl->GetWXPeer())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (impl->GetWXPeer()->IsFrozen())
 | 
			
		||||
        impl->SetDrawingEnabled(enable);
 | 
			
		||||
 | 
			
		||||
    for ( wxWindowList::iterator i = impl->GetWXPeer()->GetChildren().begin();
 | 
			
		||||
          i != impl->GetWXPeer()->GetChildren().end();
 | 
			
		||||
          ++i )
 | 
			
		||||
    {
 | 
			
		||||
        wxWindow *child = *i;
 | 
			
		||||
        if ( child->IsTopLevel() || !child->IsFrozen() )
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        // Skip any user panes as they'll handle this themselves
 | 
			
		||||
        if ( !child->GetPeer() || child->GetPeer()->IsUserPane() )
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        SetDrawingEnabledIfFrozenRecursive((wxWidgetCocoaImpl *)child->GetPeer(), enable);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@implementation wxNSView
 | 
			
		||||
 | 
			
		||||
+ (void)initialize
 | 
			
		||||
@@ -887,6 +911,24 @@ void wxWidgetCocoaImpl::SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEve
 | 
			
		||||
    return [super hitTest:aPoint];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void) viewWillMoveToWindow:(NSWindow *)newWindow
 | 
			
		||||
{
 | 
			
		||||
    wxWidgetCocoaImpl* viewimpl = (wxWidgetCocoaImpl*) wxWidgetImpl::FindFromWXWidget( self );
 | 
			
		||||
    if (viewimpl)
 | 
			
		||||
        SetDrawingEnabledIfFrozenRecursive(viewimpl, true);
 | 
			
		||||
 | 
			
		||||
    [super viewWillMoveToWindow:newWindow];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void) viewDidMoveToWindow
 | 
			
		||||
{
 | 
			
		||||
    wxWidgetCocoaImpl* viewimpl = (wxWidgetCocoaImpl*) wxWidgetImpl::FindFromWXWidget( self );
 | 
			
		||||
    if (viewimpl)
 | 
			
		||||
        SetDrawingEnabledIfFrozenRecursive(viewimpl, false);
 | 
			
		||||
 | 
			
		||||
    [super viewDidMoveToWindow];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end // wxNSView
 | 
			
		||||
 | 
			
		||||
// We need to adopt NSTextInputClient protocol in order to interpretKeyEvents: to work.
 | 
			
		||||
@@ -2486,7 +2528,7 @@ void wxWidgetCocoaImpl::Init()
 | 
			
		||||
wxWidgetCocoaImpl::~wxWidgetCocoaImpl()
 | 
			
		||||
{
 | 
			
		||||
    if ( GetWXPeer() && GetWXPeer()->IsFrozen() )
 | 
			
		||||
        [[m_osxView window] enableFlushWindow];
 | 
			
		||||
        SetDrawingEnabled(true);
 | 
			
		||||
    
 | 
			
		||||
    RemoveAssociations( this );
 | 
			
		||||
 | 
			
		||||
@@ -3034,6 +3076,10 @@ void wxWidgetCocoaImpl::SetDropTarget(wxDropTarget* target)
 | 
			
		||||
 | 
			
		||||
void wxWidgetCocoaImpl::RemoveFromParent()
 | 
			
		||||
{
 | 
			
		||||
    // User panes will be thawed in the removeFromSuperview call below
 | 
			
		||||
    if (!IsUserPane() && m_wxPeer->IsFrozen())
 | 
			
		||||
        SetDrawingEnabled(true);
 | 
			
		||||
 | 
			
		||||
    [m_osxView removeFromSuperview];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -3043,8 +3089,9 @@ void wxWidgetCocoaImpl::Embed( wxWidgetImpl *parent )
 | 
			
		||||
    wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
 | 
			
		||||
    [container addSubview:m_osxView];
 | 
			
		||||
    
 | 
			
		||||
    if( m_wxPeer->IsFrozen() )
 | 
			
		||||
        [[m_osxView window] disableFlushWindow];
 | 
			
		||||
    // User panes will be frozen elsewhere
 | 
			
		||||
    if( m_wxPeer->IsFrozen() && !IsUserPane() )
 | 
			
		||||
        SetDrawingEnabled(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wxWidgetCocoaImpl::SetBackgroundColour( const wxColour &col )
 | 
			
		||||
@@ -3693,6 +3740,9 @@ void wxWidgetCocoaImpl::SetFlipped(bool flipped)
 | 
			
		||||
 | 
			
		||||
void wxWidgetCocoaImpl::SetDrawingEnabled(bool enabled)
 | 
			
		||||
{
 | 
			
		||||
    if ( [m_osxView window] == nil )
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if ( enabled )
 | 
			
		||||
    {
 | 
			
		||||
        [[m_osxView window] enableFlushWindow];
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user