diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index c67a5d80ce..a8c426d66b 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -61,7 +61,7 @@ static NSRect flippedScreenRect (NSRect r) noexcept } #if JUCE_MODULE_AVAILABLE_juce_opengl -void componentPeerAboutToBeRemovedFromScreen (ComponentPeer&); +void componentPeerAboutToChange (ComponentPeer&, bool); #endif //============================================================================== @@ -173,7 +173,10 @@ public: setOwner (view, nullptr); if ([view superview] != nil) + { + redirectWillMoveToWindow (nullptr); [view removeFromSuperview]; + } [view release]; @@ -668,8 +671,8 @@ public: void redirectWillMoveToWindow (NSWindow* newWindow) { #if JUCE_MODULE_AVAILABLE_juce_opengl - if ([view window] == window && newWindow == nullptr) - componentPeerAboutToBeRemovedFromScreen (*this); + if ([view window] == window) + componentPeerAboutToChange (*this, (newWindow == nullptr)); #else ignoreUnused (newWindow); #endif diff --git a/modules/juce_opengl/native/juce_OpenGL_osx.h b/modules/juce_opengl/native/juce_OpenGL_osx.h index 3bc4bc5a10..dbbcbc0ea2 100644 --- a/modules/juce_opengl/native/juce_OpenGL_osx.h +++ b/modules/juce_opengl/native/juce_OpenGL_osx.h @@ -247,7 +247,7 @@ bool OpenGLHelpers::isContextActive() } //============================================================================== -void componentPeerAboutToBeRemovedFromScreen (ComponentPeer& peer) +void componentPeerAboutToChange (ComponentPeer& peer, bool shouldSuspend) { Array stack; stack.add (&peer.getComponent()); @@ -262,6 +262,6 @@ void componentPeerAboutToBeRemovedFromScreen (ComponentPeer& peer) stack.add (child); if (OpenGLContext* context = OpenGLContext::getContextAttachedTo (comp)) - context->detach(); + context->overrideCanBeAttached (shouldSuspend); } } diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index a92c32c8c8..495ea985d2 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -664,16 +664,9 @@ public: void detach() { - stopTimer(); - Component& comp = *getComponent(); - #if JUCE_MAC - [[(NSView*) comp.getWindowHandle() window] disableScreenUpdatesUntilFlush]; - #endif - - if (CachedImage* const oldCachedImage = CachedImage::get (comp)) - oldCachedImage->stop(); // (must stop this before detaching it from the component) + stop(); comp.setCachedComponentImage (nullptr); context.nativeContext = nullptr; @@ -732,12 +725,22 @@ public: } #endif + void update() + { + Component& comp = *getComponent(); + + if (canBeAttached (comp)) + start(); + else + stop(); + } + private: OpenGLContext& context; - static bool canBeAttached (const Component& comp) noexcept + bool canBeAttached (const Component& comp) noexcept { - return comp.getWidth() > 0 && comp.getHeight() > 0 && isShowingOrMinimised (comp); + return (! context.overrideCanAttach) && comp.getWidth() > 0 && comp.getHeight() > 0 && isShowingOrMinimised (comp); } static bool isShowingOrMinimised (const Component& c) @@ -763,10 +766,35 @@ private: context.openGLPixelFormat, context.contextToShareWith); comp.setCachedComponentImage (newCachedImage); - newCachedImage->start(); // (must wait until this is attached before starting its thread) - newCachedImage->updateViewportSize (true); - startTimer (400); + start(); + } + + void stop() + { + stopTimer(); + + Component& comp = *getComponent(); + + #if JUCE_MAC + [[(NSView*) comp.getWindowHandle() window] disableScreenUpdatesUntilFlush]; + #endif + + if (CachedImage* const oldCachedImage = CachedImage::get (comp)) + oldCachedImage->stop(); // (must stop this before detaching it from the component) + } + + void start() + { + Component& comp = *getComponent(); + + if (CachedImage* const cachedImage = CachedImage::get (comp)) + { + cachedImage->start(); // (must wait until this is attached before starting its thread) + cachedImage->updateViewportSize (true); + + startTimer (400); + } } void timerCallback() override @@ -784,7 +812,8 @@ OpenGLContext::OpenGLContext() imageCacheMaxSize (8 * 1024 * 1024), renderComponents (true), useMultisampling (false), - continuousRepaint (false) + continuousRepaint (false), + overrideCanAttach (false) { } @@ -1024,6 +1053,17 @@ void OpenGLContext::execute (OpenGLContext::AsyncWorker::Ptr workerToUse, bool s jassertfalse; // You must have attached the context to a component } +void OpenGLContext::overrideCanBeAttached (bool newCanAttach) +{ + if (overrideCanAttach != newCanAttach) + { + overrideCanAttach = newCanAttach; + + if (Attachment* a = attachment) + a->update(); + } +} + //============================================================================== struct DepthTestDisabler { diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.h b/modules/juce_opengl/opengl/juce_OpenGLContext.h index a3c43d09c8..7c444d1398 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.h @@ -308,7 +308,7 @@ private: void* contextToShareWith; OpenGLVersion versionRequired; size_t imageCacheMaxSize; - bool renderComponents, useMultisampling, continuousRepaint; + bool renderComponents, useMultisampling, continuousRepaint, overrideCanAttach; //============================================================================== struct AsyncWorker : ReferenceCountedObject @@ -328,6 +328,10 @@ private: JUCE_DECLARE_NON_COPYABLE(AsyncWorkerFunctor) }; + //============================================================================== + friend void componentPeerAboutToChange (ComponentPeer&, bool); + void overrideCanBeAttached (bool); + //============================================================================== CachedImage* getCachedImage() const noexcept; void execute (AsyncWorker::Ptr, bool);