X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/19253261f5c6127f5448078295d4cbe1521d469f..04ce16a8707de253826da7b46d03896307a51625:/src/cocoa/window.mm diff --git a/src/cocoa/window.mm b/src/cocoa/window.mm index bb25bcc333..fe1ea122e1 100644 --- a/src/cocoa/window.mm +++ b/src/cocoa/window.mm @@ -26,7 +26,7 @@ #include "wx/cocoa/string.h" #include "wx/cocoa/trackingrectmanager.h" #include "wx/cocoa/private/scrollview.h" -#include "wx/mac/corefoundation/cfref.h" +#include "wx/osx/core/cfref.h" #include "wx/cocoa/ObjcRef.h" #import @@ -152,7 +152,7 @@ namespace { // file namespace class wxCocoaPrivateScreenCoordinateTransformer { - DECLARE_NO_COPY_CLASS(wxCocoaPrivateScreenCoordinateTransformer) + wxDECLARE_NO_COPY_CLASS(wxCocoaPrivateScreenCoordinateTransformer); public: wxCocoaPrivateScreenCoordinateTransformer(); ~wxCocoaPrivateScreenCoordinateTransformer(); @@ -273,7 +273,7 @@ NSPoint wxWindowCocoa::OriginInCocoaScreenCoordinatesForRectInWxDisplayCoordinat // ======================================================================== class wxWindowCocoaHider: protected wxCocoaNSView { - DECLARE_NO_COPY_CLASS(wxWindowCocoaHider) + wxDECLARE_NO_COPY_CLASS(wxWindowCocoaHider); public: wxWindowCocoaHider(wxWindow *owner); virtual ~wxWindowCocoaHider(); @@ -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() @@ -903,7 +912,14 @@ void wxWindowCocoaScrollView::Cocoa_FrameChanged(void) wxSizeEvent event(m_owner->GetSize(), m_owner->GetId()); event.SetEventObject(m_owner); m_owner->HandleWindowEvent(event); - UpdateSizes(); + + /* If the view is not a native one then it's being managed by wx. In this case the control + may decide to change its virtual size and we must update the document view's size to + match. For native views the virtual size will never have been set so we do not want + to use it at all. + */ + if(!m_isNativeView) + UpdateSizes(); } // ======================================================================== @@ -927,7 +943,6 @@ void wxWindowCocoa::Init() m_cocoaNSView = NULL; m_cocoaHider = NULL; m_wxCocoaScrollView = NULL; - m_isBeingDeleted = false; m_isInPaint = false; m_visibleTrackingRectManager = NULL; } @@ -1396,17 +1411,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 @@ -1771,7 +1817,7 @@ static char const * const comparisonresultStrings[] = class CocoaWindowCompareContext { - DECLARE_NO_COPY_CLASS(CocoaWindowCompareContext) + wxDECLARE_NO_COPY_CLASS(CocoaWindowCompareContext); public: CocoaWindowCompareContext(); // Not implemented CocoaWindowCompareContext(NSView *target, NSArray *subviews) @@ -1962,7 +2008,7 @@ wxWindow* wxFindWindowAtPointer(wxPoint& pt) */ class wxCocoaMouseMovedEventSynthesizer { - DECLARE_NO_COPY_CLASS(wxCocoaMouseMovedEventSynthesizer) + wxDECLARE_NO_COPY_CLASS(wxCocoaMouseMovedEventSynthesizer); public: wxCocoaMouseMovedEventSynthesizer() { m_lastScreenMouseLocation = NSZeroPoint;