diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index d05cf60d2b..489189784d 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -1726,26 +1726,16 @@ const Result Result::fail (const String& errorMessage) noexcept return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage); } -bool Result::wasOk() const noexcept -{ - return errorMessage.isEmpty(); -} - -bool Result::failed() const noexcept -{ - return errorMessage.isNotEmpty(); -} - -Result::operator bool() const noexcept -{ - return errorMessage.isEmpty(); -} - const String Result::getErrorMessage() const noexcept { return errorMessage; } +bool Result::wasOk() const noexcept { return errorMessage.isEmpty(); } +Result::operator bool() const noexcept { return errorMessage.isEmpty(); } +bool Result::failed() const noexcept { return errorMessage.isNotEmpty(); } +bool Result::operator!() const noexcept { return errorMessage.isNotEmpty(); } + END_JUCE_NAMESPACE /*** End of inlined file: juce_Result.cpp ***/ @@ -48506,6 +48496,7 @@ void ComboBox::lookAndFeelChanged() } addAndMakeVisible (label); + setWantsKeyboardFocus (! label->isEditable()); label->addListener (this); label->addMouseListener (this, false); @@ -76902,6 +76893,14 @@ public: while (owner.renderAndSwapBuffers() && ! threadShouldExit()) owner.waitAfterSwapping(); + owner.releaseOpenGLContext(); + + #if JUCE_LINUX + owner.deleteContext(); + #else + owner.makeCurrentContextInactive(); + #endif + triggerAsyncUpdate(); } @@ -76933,17 +76932,13 @@ public: void componentPeerChanged() { - const ScopedLock sl (owner->getContextLock()); owner->stopRendering(); } void componentVisibilityChanged() { if (! owner->isShowing()) - { - const ScopedLock sl (owner->getContextLock()); owner->stopRendering(); - } } private: @@ -76955,7 +76950,8 @@ private: OpenGLComponent::OpenGLComponent (const OpenGLType type_) : type (type_), contextToShareListsWith (nullptr), - needToUpdateViewport (true) + needToUpdateViewport (true), + useThread (false) { setOpaque (true); componentWatcher = new OpenGLComponentWatcher (this); @@ -76963,7 +76959,8 @@ OpenGLComponent::OpenGLComponent (const OpenGLType type_) OpenGLComponent::~OpenGLComponent() { - deleteContext(); + stopRendering(); + renderThread = nullptr; componentWatcher = nullptr; } @@ -77079,14 +77076,29 @@ void OpenGLComponent::paint (Graphics&) renderThread = new OpenGLComponentRenderThread (*this); if (! renderThread->isThreadRunning()) + { + renderThread->handleUpdateNowIfNeeded(); // may still be shutting down as well + + #if ! JUCE_LINUX + // Except for Linux, create the context etc. first + const ScopedLock sl (contextLock); + + if (makeCurrentContextActive()) // Make active just to create + makeCurrentContextInactive(); + #endif + renderThread->startThread (6); + } // fall-through and update the masking region } else { - if (renderThread != nullptr && renderThread->isThreadRunning()) - renderThread->stopThread (5000); + if (renderThread != nullptr) + { + stopRendering(); + renderThread = nullptr; + } if (! renderAndSwapBuffers()) return; @@ -77127,26 +77139,19 @@ void OpenGLComponent::waitAfterSwapping() Thread::sleep (20); } -bool OpenGLComponent::stopRendering() +void OpenGLComponent::stopRendering() { - const ScopedLock sl (contextLock); + if (renderThread != nullptr) + renderThread->stopThread (5000); - if (! makeCurrentContextActive()) - return false; - - releaseOpenGLContext(); // callback to allow for shutdown - - if (renderThread != nullptr && Thread::getCurrentThread() == renderThread) + if (context != nullptr && makeCurrentContextActive()) { - // make the context inactive - if we're on a thread, this will release the context, - // so the main thread can take it and do shutdown + // On Linux, when threaded, context will have already been cleared + const ScopedLock sl (contextLock); - makeCurrentContextInactive(); + releaseOpenGLContext(); + deleteContext(); } - else if (context != nullptr) - context->deleteContext(); - - return true; } void OpenGLComponent::internalRepaint (int x, int y, int w, int h) diff --git a/juce_amalgamated.h b/juce_amalgamated.h index c0b5d9eb58..23fdd540d0 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 77 +#define JUCE_BUILDNUMBER 78 /** Current Juce version number. @@ -12059,6 +12059,11 @@ public: */ operator bool() const noexcept; + /** Returns true if this result indicates a failure. + This is equivalent to calling failed(). + */ + bool operator!() const noexcept; + /** Returns the error message that was set when this result was created. For a successful result, this will be an empty string; */ @@ -12074,6 +12079,10 @@ private: String errorMessage; explicit Result (const String& errorMessage) noexcept; + + // These casts are private to prevent people trying to use the Result object in numeric contexts + operator int() const; + operator void*() const; }; #endif // __JUCE_RESULT_JUCEHEADER__ @@ -63926,15 +63935,9 @@ public: Used when rendering is running on a thread. The default is 20 millseconds, giving a nominal frame rate of just under 50 fps. - */ + */ virtual void waitAfterSwapping(); - /** Stop Rendering. - - Use to shut down an openGLComponent properly, whether on a thread or not. - */ - virtual bool stopRendering(); - /** This returns a critical section that can be used to lock the current context. Because the context that is used by this component can change, e.g. when the @@ -63980,6 +63983,7 @@ private: OpenGLContext* createContext(); void updateContextPosition(); void internalRepaint (int x, int y, int w, int h); + void stopRendering(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent); }; diff --git a/src/core/juce_Result.cpp b/src/core/juce_Result.cpp index c78205f7bf..7c64f3763f 100644 --- a/src/core/juce_Result.cpp +++ b/src/core/juce_Result.cpp @@ -67,26 +67,15 @@ const Result Result::fail (const String& errorMessage) noexcept return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage); } -//============================================================================== -bool Result::wasOk() const noexcept -{ - return errorMessage.isEmpty(); -} - -bool Result::failed() const noexcept -{ - return errorMessage.isNotEmpty(); -} - -Result::operator bool() const noexcept -{ - return errorMessage.isEmpty(); -} - const String Result::getErrorMessage() const noexcept { return errorMessage; } +bool Result::wasOk() const noexcept { return errorMessage.isEmpty(); } +Result::operator bool() const noexcept { return errorMessage.isEmpty(); } +bool Result::failed() const noexcept { return errorMessage.isNotEmpty(); } +bool Result::operator!() const noexcept { return errorMessage.isNotEmpty(); } + END_JUCE_NAMESPACE diff --git a/src/core/juce_Result.h b/src/core/juce_Result.h index 1e5ea53259..8c964f3c9a 100644 --- a/src/core/juce_Result.h +++ b/src/core/juce_Result.h @@ -85,6 +85,11 @@ public: */ operator bool() const noexcept; + /** Returns true if this result indicates a failure. + This is equivalent to calling failed(). + */ + bool operator!() const noexcept; + /** Returns the error message that was set when this result was created. For a successful result, this will be an empty string; */ @@ -101,6 +106,10 @@ private: String errorMessage; explicit Result (const String& errorMessage) noexcept; + + // These casts are private to prevent people trying to use the Result object in numeric contexts + operator int() const; + operator void*() const; }; diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 1aa8781c4b..73cafa75e9 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 77 +#define JUCE_BUILDNUMBER 78 /** Current Juce version number. diff --git a/src/gui/components/controls/juce_ComboBox.cpp b/src/gui/components/controls/juce_ComboBox.cpp index c1a9923e7d..2455ef7ada 100644 --- a/src/gui/components/controls/juce_ComboBox.cpp +++ b/src/gui/components/controls/juce_ComboBox.cpp @@ -432,6 +432,7 @@ void ComboBox::lookAndFeelChanged() } addAndMakeVisible (label); + setWantsKeyboardFocus (! label->isEditable()); label->addListener (this); label->addMouseListener (this, false); diff --git a/src/gui/components/special/juce_OpenGLComponent.cpp b/src/gui/components/special/juce_OpenGLComponent.cpp index cefa12b136..affff2a94a 100644 --- a/src/gui/components/special/juce_OpenGLComponent.cpp +++ b/src/gui/components/special/juce_OpenGLComponent.cpp @@ -148,6 +148,14 @@ public: while (owner.renderAndSwapBuffers() && ! threadShouldExit()) owner.waitAfterSwapping(); + owner.releaseOpenGLContext(); + + #if JUCE_LINUX + owner.deleteContext(); + #else + owner.makeCurrentContextInactive(); + #endif + triggerAsyncUpdate(); } @@ -184,17 +192,13 @@ public: void componentPeerChanged() { - const ScopedLock sl (owner->getContextLock()); owner->stopRendering(); } void componentVisibilityChanged() { if (! owner->isShowing()) - { - const ScopedLock sl (owner->getContextLock()); owner->stopRendering(); - } } //============================================================================== @@ -208,7 +212,8 @@ private: OpenGLComponent::OpenGLComponent (const OpenGLType type_) : type (type_), contextToShareListsWith (nullptr), - needToUpdateViewport (true) + needToUpdateViewport (true), + useThread (false) { setOpaque (true); componentWatcher = new OpenGLComponentWatcher (this); @@ -216,7 +221,8 @@ OpenGLComponent::OpenGLComponent (const OpenGLType type_) OpenGLComponent::~OpenGLComponent() { - deleteContext(); + stopRendering(); + renderThread = nullptr; componentWatcher = nullptr; } @@ -332,14 +338,29 @@ void OpenGLComponent::paint (Graphics&) renderThread = new OpenGLComponentRenderThread (*this); if (! renderThread->isThreadRunning()) + { + renderThread->handleUpdateNowIfNeeded(); // may still be shutting down as well + + #if ! JUCE_LINUX + // Except for Linux, create the context etc. first + const ScopedLock sl (contextLock); + + if (makeCurrentContextActive()) // Make active just to create + makeCurrentContextInactive(); + #endif + renderThread->startThread (6); + } // fall-through and update the masking region } else { - if (renderThread != nullptr && renderThread->isThreadRunning()) - renderThread->stopThread (5000); + if (renderThread != nullptr) + { + stopRendering(); + renderThread = nullptr; + } if (! renderAndSwapBuffers()) return; @@ -380,26 +401,19 @@ void OpenGLComponent::waitAfterSwapping() Thread::sleep (20); } -bool OpenGLComponent::stopRendering() +void OpenGLComponent::stopRendering() { - const ScopedLock sl (contextLock); - - if (! makeCurrentContextActive()) - return false; + if (renderThread != nullptr) + renderThread->stopThread (5000); - releaseOpenGLContext(); // callback to allow for shutdown - - if (renderThread != nullptr && Thread::getCurrentThread() == renderThread) + if (context != nullptr && makeCurrentContextActive()) { - // make the context inactive - if we're on a thread, this will release the context, - // so the main thread can take it and do shutdown + // On Linux, when threaded, context will have already been cleared + const ScopedLock sl (contextLock); - makeCurrentContextInactive(); + releaseOpenGLContext(); + deleteContext(); } - else if (context != nullptr) - context->deleteContext(); - - return true; } void OpenGLComponent::internalRepaint (int x, int y, int w, int h) diff --git a/src/gui/components/special/juce_OpenGLComponent.h b/src/gui/components/special/juce_OpenGLComponent.h index 796f31d5fe..9d9a01760d 100644 --- a/src/gui/components/special/juce_OpenGLComponent.h +++ b/src/gui/components/special/juce_OpenGLComponent.h @@ -346,15 +346,9 @@ public: Used when rendering is running on a thread. The default is 20 millseconds, giving a nominal frame rate of just under 50 fps. - */ + */ virtual void waitAfterSwapping(); - /** Stop Rendering. - - Use to shut down an openGLComponent properly, whether on a thread or not. - */ - virtual bool stopRendering(); - /** This returns a critical section that can be used to lock the current context. Because the context that is used by this component can change, e.g. when the @@ -403,6 +397,7 @@ private: OpenGLContext* createContext(); void updateContextPosition(); void internalRepaint (int x, int y, int w, int h); + void stopRendering(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent); };