* When hiding a wxWindow make sure that none of its subviews are the first
responder. If one of them is, make it resign. If it refuses, don't hide
the window and return false.
* When showing a wxWindow that has been hidden, schedule a reconfiguration
of the key-view loop so that tabbing will work correctly.
* Add some comments about why wxCocoa does what it does.
This makes the widgets sample much more usable.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@52099 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -309,6 +309,12 @@ WX_IMPLEMENT_GET_OBJC_CLASS(wxDummyNSView,NSView)
|
|||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// wxWindowCocoaHider
|
// wxWindowCocoaHider
|
||||||
|
// NOTE: This class and method of hiding predates setHidden: support in
|
||||||
|
// the toolkit. The hack used here is to replace the view with a stand-in
|
||||||
|
// that will be subject to the usual Cocoa resizing rules.
|
||||||
|
// When possible (i.e. when running on 10.3 or higher) we make it hidden
|
||||||
|
// mostly as an optimization so Cocoa doesn't have to consider it when
|
||||||
|
// drawing or finding key views.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner)
|
wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner)
|
||||||
: m_owner(owner)
|
: m_owner(owner)
|
||||||
@@ -319,6 +325,9 @@ wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner)
|
|||||||
initWithFrame:[owner->GetNSViewForHiding() frame]];
|
initWithFrame:[owner->GetNSViewForHiding() frame]];
|
||||||
[m_dummyNSView setAutoresizingMask: [owner->GetNSViewForHiding() autoresizingMask]];
|
[m_dummyNSView setAutoresizingMask: [owner->GetNSViewForHiding() autoresizingMask]];
|
||||||
AssociateNSView(m_dummyNSView);
|
AssociateNSView(m_dummyNSView);
|
||||||
|
|
||||||
|
if([m_dummyNSView respondsToSelector:@selector(setHidden:)])
|
||||||
|
[m_dummyNSView setHidden:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
wxWindowCocoaHider::~wxWindowCocoaHider()
|
wxWindowCocoaHider::~wxWindowCocoaHider()
|
||||||
@@ -1403,17 +1412,48 @@ bool wxWindow::Show(bool show)
|
|||||||
// If state isn't changing, return false
|
// If state isn't changing, return false
|
||||||
if(!m_cocoaHider)
|
if(!m_cocoaHider)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Replace the stand-in view with the real one and destroy the dummy view
|
||||||
CocoaReplaceView(m_cocoaHider->GetNSView(), cocoaView);
|
CocoaReplaceView(m_cocoaHider->GetNSView(), cocoaView);
|
||||||
wxASSERT(![m_cocoaHider->GetNSView() superview]);
|
wxASSERT(![m_cocoaHider->GetNSView() superview]);
|
||||||
delete m_cocoaHider;
|
delete m_cocoaHider;
|
||||||
m_cocoaHider = NULL;
|
m_cocoaHider = NULL;
|
||||||
wxASSERT([cocoaView superview]);
|
wxASSERT([cocoaView superview]);
|
||||||
|
|
||||||
|
// Schedule an update of the key view loop (NOTE: 10.4+ only.. argh)
|
||||||
|
NSWindow *window = [cocoaView window];
|
||||||
|
if(window != nil)
|
||||||
|
{
|
||||||
|
// Delay this until returning to the event loop for a couple of reasons:
|
||||||
|
// 1. If a lot of stuff is shown/hidden we avoid recalculating needlessly
|
||||||
|
// 2. NSWindow does not seem to see the newly shown views if we do it right now.
|
||||||
|
if([window respondsToSelector:@selector(recalculateKeyViewLoop)])
|
||||||
|
[window performSelector:@selector(recalculateKeyViewLoop) withObject:nil afterDelay:0.0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If state isn't changing, return false
|
// If state isn't changing, return false
|
||||||
if(m_cocoaHider)
|
if(m_cocoaHider)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Handle the first responder
|
||||||
|
NSWindow *window = [cocoaView window];
|
||||||
|
if(window != nil)
|
||||||
|
{
|
||||||
|
NSResponder *firstResponder = [window firstResponder];
|
||||||
|
if([firstResponder isKindOfClass:[NSView class]] && [(NSView*)firstResponder isDescendantOf:cocoaView])
|
||||||
|
{
|
||||||
|
BOOL didResign = [window makeFirstResponder:nil];
|
||||||
|
// If the current first responder (one of our subviews) refuses to give
|
||||||
|
// up its status, then fail now and don't hide this view
|
||||||
|
if(didResign == NO)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new view to stand in for the real one (via wxWindowCocoaHider) and replace
|
||||||
|
// the real one with the stand in.
|
||||||
m_cocoaHider = new wxWindowCocoaHider(this);
|
m_cocoaHider = new wxWindowCocoaHider(this);
|
||||||
// NOTE: replaceSubview:with will cause m_cocaNSView to be
|
// NOTE: replaceSubview:with will cause m_cocaNSView to be
|
||||||
// (auto)released which balances out addSubview
|
// (auto)released which balances out addSubview
|
||||||
|
|||||||
Reference in New Issue
Block a user