diff --git a/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm b/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm index ff769d08cf..ff9cdca8d9 100644 --- a/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm @@ -28,18 +28,30 @@ class NSViewAttachment : public ReferenceCountedObject, public: NSViewAttachment (NSView* const v, Component& comp) : ComponentMovementWatcher (&comp), - view (v), - owner (comp), - currentPeer (nullptr) + view (v), owner (comp), + currentPeer (nullptr), frameChangeCallback (nullptr) { [view retain]; + [view setPostsFrameChangedNotifications: YES]; if (owner.isShowing()) componentPeerChanged(); + + static ViewFrameChangeCallbackClass cls; + frameChangeCallback = [cls.createInstance() init]; + ViewFrameChangeCallbackClass::setTarget (frameChangeCallback, &owner); + + [[NSNotificationCenter defaultCenter] addObserver: frameChangeCallback + selector: @selector (frameChanged:) + name: NSViewFrameDidChangeNotification + object: view]; } ~NSViewAttachment() { + [[NSNotificationCenter defaultCenter] removeObserver: frameChangeCallback]; + [frameChangeCallback release]; + removeFromParent(); [view release]; } @@ -96,6 +108,7 @@ public: private: Component& owner; ComponentPeer* currentPeer; + id frameChangeCallback; void removeFromParent() { @@ -104,6 +117,31 @@ private: // override the call and use it as a sign that they're being deleted, which breaks everything.. } + //============================================================================== + struct ViewFrameChangeCallbackClass : public ObjCClass + { + ViewFrameChangeCallbackClass() : ObjCClass ("JUCE_NSViewCallback_") + { + addIvar ("target"); + addMethod (@selector (frameChanged:), frameChanged, "v@:@"); + registerClass(); + } + + static void setTarget (id self, Component* c) + { + object_setInstanceVariable (self, "target", c); + } + + private: + static void frameChanged (id self, SEL, NSNotification*) + { + if (Component* const target = getIvar (self, "target")) + target->childBoundsChanged (nullptr); + } + + JUCE_DECLARE_NON_COPYABLE (ViewFrameChangeCallbackClass); + }; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewAttachment) }; @@ -124,7 +162,7 @@ void NSViewComponent::setView (void* const view) void* NSViewComponent::getView() const { - return attachment != nullptr ? static_cast (attachment.get())->view + return attachment != nullptr ? static_cast (attachment.get())->view : nullptr; } @@ -132,7 +170,7 @@ void NSViewComponent::resizeToFitView() { if (attachment != nullptr) { - NSRect r = [static_cast (attachment.get())->view frame]; + NSRect r = [static_cast (attachment.get())->view frame]; setBounds (Rectangle ((int) r.size.width, (int) r.size.height)); } }