* 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:
David Elliott
2008-02-26 05:57:42 +00:00
parent 877b5c30d6
commit dee851ec9f

View File

@@ -309,6 +309,12 @@ WX_IMPLEMENT_GET_OBJC_CLASS(wxDummyNSView,NSView)
// ========================================================================
// 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)
: m_owner(owner)
@@ -319,6 +325,9 @@ wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner)
initWithFrame:[owner->GetNSViewForHiding() frame]];
[m_dummyNSView setAutoresizingMask: [owner->GetNSViewForHiding() autoresizingMask]];
AssociateNSView(m_dummyNSView);
if([m_dummyNSView respondsToSelector:@selector(setHidden:)])
[m_dummyNSView setHidden:YES];
}
wxWindowCocoaHider::~wxWindowCocoaHider()
@@ -1403,17 +1412,48 @@ bool wxWindow::Show(bool show)
// If state isn't changing, return false
if(!m_cocoaHider)
return false;
// Replace the stand-in view with the real one and destroy the dummy view
CocoaReplaceView(m_cocoaHider->GetNSView(), cocoaView);
wxASSERT(![m_cocoaHider->GetNSView() superview]);
delete m_cocoaHider;
m_cocoaHider = NULL;
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
{
// If state isn't changing, return false
if(m_cocoaHider)
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);
// NOTE: replaceSubview:with will cause m_cocaNSView to be
// (auto)released which balances out addSubview