From 7ea8aa377de05d5a049fee75781455a424b3bf5f Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 6 Mar 2021 13:21:31 +0000 Subject: [PATCH] Add vital patches Signed-off-by: falkTX --- .../patches/24_vital-needed-changes_pt2.patch | 144 ++++++ .../patches/24_vital-needed-changes_pt3.patch | 467 ++++++++++++++++++ .../25_x11-crash-on-close-workaround.patch | 104 ++++ 3 files changed, 715 insertions(+) create mode 100644 libs/juce-current/patches/24_vital-needed-changes_pt2.patch create mode 100644 libs/juce-current/patches/24_vital-needed-changes_pt3.patch create mode 100644 libs/juce-current/patches/25_x11-crash-on-close-workaround.patch diff --git a/libs/juce-current/patches/24_vital-needed-changes_pt2.patch b/libs/juce-current/patches/24_vital-needed-changes_pt2.patch new file mode 100644 index 00000000..5b72380e --- /dev/null +++ b/libs/juce-current/patches/24_vital-needed-changes_pt2.patch @@ -0,0 +1,144 @@ +diff --git a/modules/juce_opengl/juce_opengl.h b/modules/juce_opengl/juce_opengl.h +index f7bc806f8..d325d3e34 100644 +--- a/modules/juce_opengl/juce_opengl.h ++++ b/modules/juce_opengl/juce_opengl.h +@@ -124,7 +124,7 @@ + It's mandatory in OpenGL 3.0 to specify the GLSL version. + */ + #if JUCE_OPENGL3 +- #if JUCE_OPENGL_ES ++ #if JUCE_OPENGL_ES || OPENGL_ES + #define JUCE_GLSL_VERSION "#version 300 es" + #else + #define JUCE_GLSL_VERSION "#version 150" +diff --git a/modules/juce_opengl/native/juce_MissingGLDefinitions.h b/modules/juce_opengl/native/juce_MissingGLDefinitions.h +index c23ec097a..00c6cf565 100644 +--- a/modules/juce_opengl/native/juce_MissingGLDefinitions.h ++++ b/modules/juce_opengl/native/juce_MissingGLDefinitions.h +@@ -126,6 +126,14 @@ enum MissingOpenGLDefinitions + GL_DYNAMIC_DRAW = 0x88E8, + GL_STREAM_DRAW = 0x88E0, + ++ GL_GEOMETRY_SHADER = 0x8DD9, ++ GL_LINE_STRIP_ADJACENCY = 0x000B, ++ GL_INTERLEAVED_ATTRIBS = 0x8C8C, ++ GL_STATIC_READ = 0x88E5, ++ GL_TRANSFORM_FEEDBACK_BUFFER = 0x8C8E, ++ GL_RASTERIZER_DISCARD = 0x8C89, ++ GL_MAP_READ_BIT = 0x0001, ++ + WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000, + WGL_DRAW_TO_WINDOW_ARB = 0x2001, + WGL_ACCELERATION_ARB = 0x2003, +diff --git a/modules/juce_opengl/native/juce_OpenGL_linux_X11.h b/modules/juce_opengl/native/juce_OpenGL_linux_X11.h +index ef7eb852e..b4ba85cc4 100644 +--- a/modules/juce_opengl/native/juce_OpenGL_linux_X11.h ++++ b/modules/juce_opengl/native/juce_OpenGL_linux_X11.h +@@ -69,8 +69,8 @@ public: + + GLint attribs[] = + { +- GLX_RGBA, +- GLX_DOUBLEBUFFER, ++ GLX_RENDER_TYPE, GLX_RGBA_BIT, ++ GLX_DOUBLEBUFFER, True, + GLX_RED_SIZE, cPixelFormat.redBits, + GLX_GREEN_SIZE, cPixelFormat.greenBits, + GLX_BLUE_SIZE, cPixelFormat.blueBits, +@@ -81,13 +81,21 @@ public: + GLX_ACCUM_GREEN_SIZE, cPixelFormat.accumulationBufferGreenBits, + GLX_ACCUM_BLUE_SIZE, cPixelFormat.accumulationBufferBlueBits, + GLX_ACCUM_ALPHA_SIZE, cPixelFormat.accumulationBufferAlphaBits, ++ GLX_X_RENDERABLE, True, + None + }; + +- bestVisual = glXChooseVisual (display, X11Symbols::getInstance()->xDefaultScreen (display), attribs); +- if (bestVisual == nullptr) ++ int countFbConfigs; ++ fbConfig = glXChooseFBConfig (display, DefaultScreen (display), attribs, &countFbConfigs); ++ if (fbConfig == nullptr) + return; + ++ bestVisual = glXGetVisualFromFBConfig (display, *fbConfig); ++ if (bestVisual == nullptr) { ++ X11Symbols::getInstance()->xFree (fbConfig); ++ return; ++ } ++ + auto* peer = component.getPeer(); + jassert (peer != nullptr); + +@@ -139,6 +147,9 @@ public: + } + } + ++ if (fbConfig != nullptr) ++ X11Symbols::getInstance()->xFree (fbConfig); ++ + if (bestVisual != nullptr) + X11Symbols::getInstance()->xFree (bestVisual); + } +@@ -146,7 +157,18 @@ public: + bool initialiseOnRenderThread (OpenGLContext& c) + { + XWindowSystemUtilities::ScopedXLock xLock; +- renderContext = glXCreateContext (display, bestVisual, (GLXContext) contextToShareWith, GL_TRUE); ++ PFNGLXCREATECONTEXTATTRIBSARBPROC createContextAttribs; ++ int attribs[] = { ++ GLX_CONTEXT_MAJOR_VERSION_ARB, 3, ++ GLX_CONTEXT_MINOR_VERSION_ARB, 2, ++ GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, ++ 0 ++ }; ++ ++ createContextAttribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC) ++ OpenGLHelpers::getExtensionFunction("glXCreateContextAttribsARB"); ++ ++ renderContext = createContextAttribs (display, *fbConfig, (GLXContext) contextToShareWith, GL_TRUE, attribs); + c.makeActive(); + context = &c; + +@@ -240,6 +262,7 @@ private: + int swapFrames = 1; + Rectangle bounds; + XVisualInfo* bestVisual = nullptr; ++ GLXFBConfig* fbConfig = nullptr; + void* contextToShareWith; + + OpenGLContext* context = nullptr; +diff --git a/modules/juce_opengl/native/juce_OpenGL_win32.h b/modules/juce_opengl/native/juce_OpenGL_win32.h +index 6106fce54..7ba46c079 100644 +--- a/modules/juce_opengl/native/juce_OpenGL_win32.h ++++ b/modules/juce_opengl/native/juce_OpenGL_win32.h +@@ -285,6 +285,8 @@ private: + + atts[n++] = WGL_DRAW_TO_WINDOW_ARB; atts[n++] = GL_TRUE; + atts[n++] = WGL_SUPPORT_OPENGL_ARB; atts[n++] = GL_TRUE; ++ atts[n++] = WGL_CONTEXT_MAJOR_VERSION_ARB; atts[n++] = 3; ++ atts[n++] = WGL_CONTEXT_MINOR_VERSION_ARB; atts[n++] = 2; + atts[n++] = WGL_DOUBLE_BUFFER_ARB; atts[n++] = GL_TRUE; + atts[n++] = WGL_PIXEL_TYPE_ARB; atts[n++] = WGL_TYPE_RGBA_ARB; + atts[n++] = WGL_ACCELERATION_ARB; +diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp +index 97dc1f0b5..ad40fa640 100644 +--- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp ++++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp +@@ -83,7 +83,7 @@ void OpenGLHelpers::enableScissorTest (Rectangle clip) + + String OpenGLHelpers::translateVertexShaderToV3 (const String& code) + { +- #if JUCE_OPENGL3 ++ #if JUCE_OPENGL3 || OPENGL_ES + if (OpenGLShaderProgram::getLanguageVersion() > 1.2) + { + String output; +@@ -119,7 +119,7 @@ String OpenGLHelpers::translateVertexShaderToV3 (const String& code) + + String OpenGLHelpers::translateFragmentShaderToV3 (const String& code) + { +- #if JUCE_OPENGL3 ++ #if JUCE_OPENGL3 || OPENGL_ES + if (OpenGLShaderProgram::getLanguageVersion() > 1.2) + return JUCE_GLSL_VERSION "\n" + "out " JUCE_MEDIUMP " vec4 fragColor;\n" diff --git a/libs/juce-current/patches/24_vital-needed-changes_pt3.patch b/libs/juce-current/patches/24_vital-needed-changes_pt3.patch new file mode 100644 index 00000000..95f981e1 --- /dev/null +++ b/libs/juce-current/patches/24_vital-needed-changes_pt3.patch @@ -0,0 +1,467 @@ +diff --git a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp +index 7642040bd..ed02448b8 100644 +--- a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp ++++ b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp +@@ -842,6 +842,26 @@ namespace WavFileHelpers + return out.getMemoryBlock(); + } + }; ++ ++ //============================================================================== ++ struct Clm_Chunk ++ { ++ static MemoryBlock createFrom (const StringPairArray& values) ++ { ++ MemoryOutputStream out; ++ auto s = values["clm "]; ++ ++ if (s.isNotEmpty()) ++ { ++ out.writeString (s); ++ ++ if ((out.getDataSize() & 1) != 0) ++ out.writeByte(0); ++ } ++ ++ return out.getMemoryBlock(); ++ } ++ }; + + //============================================================================== + namespace AXMLChunk +@@ -1321,6 +1341,7 @@ public: + listInfoChunk = ListInfoChunk::createFrom (metadataValues); + acidChunk = AcidChunk::createFrom (metadataValues); + trckChunk = TracktionChunk::createFrom (metadataValues); ++ clm_Chunk = Clm_Chunk::createFrom (metadataValues); + } + + headerPosition = out->getPosition(); +@@ -1383,7 +1404,7 @@ public: + } + + private: +- MemoryBlock tempBlock, bwavChunk, axmlChunk, smplChunk, instChunk, cueChunk, listChunk, listInfoChunk, acidChunk, trckChunk; ++ MemoryBlock tempBlock, bwavChunk, axmlChunk, smplChunk, instChunk, cueChunk, listChunk, listInfoChunk, acidChunk, trckChunk, clm_Chunk; + uint64 lengthInSamples = 0, bytesWritten = 0; + int64 headerPosition = 0; + bool writeFailed = false; +@@ -1421,6 +1442,7 @@ private: + + chunkSize (listInfoChunk) + + chunkSize (acidChunk) + + chunkSize (trckChunk) ++ + chunkSize (clm_Chunk) + + (8 + 28)); // (ds64 chunk) + + riffChunkSize += (riffChunkSize & 1); +@@ -1503,6 +1525,7 @@ private: + writeChunk (listInfoChunk, chunkName ("LIST")); + writeChunk (acidChunk, chunkName ("acid")); + writeChunk (trckChunk, chunkName ("Trkn")); ++ writeChunk (clm_Chunk, chunkName ("clm ")); + + writeChunkHeader (chunkName ("data"), isRF64 ? -1 : (int) (lengthInSamples * bytesPerFrame)); + +diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +index 7909098c9..19eb385fd 100644 +--- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp ++++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +@@ -28,6 +28,9 @@ + + //============================================================================== + #if JucePlugin_Build_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) ++#if JUCE_LINUX^M ++ #include ^M ++#endif^M + + #if JUCE_PLUGINHOST_VST3 + #if JUCE_MAC +@@ -2618,6 +2621,9 @@ public: + //============================================================================== + void processParameterChanges (Vst::IParameterChanges& paramChanges) + { ++ if (juceVST3EditController == nullptr) ++ return; ++ + jassert (pluginInstance != nullptr); + + auto numParamsChanged = paramChanges.getParameterCount(); +diff --git a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp +index 50cae68ed..549d8edb8 100644 +--- a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp ++++ b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp +@@ -393,6 +393,7 @@ public: + AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, + TRANS("Error when trying to open audio device!"), + error); ++ resized(); + } + + bool showDeviceControlPanel() +@@ -1120,6 +1121,8 @@ void AudioDeviceSelectorComponent::updateMidiOutput() + deviceManager.setDefaultMidiOutputDevice ({}); + else + deviceManager.setDefaultMidiOutputDevice (currentMidiOutputs[selectedId - 1].identifier); ++ ++ resized(); + } + + void AudioDeviceSelectorComponent::changeListenerCallback (ChangeBroadcaster*) +diff --git a/modules/juce_core/native/juce_curl_Network.cpp b/modules/juce_core/native/juce_curl_Network.cpp +index 00d428350..dd3375ff7 100644 +--- a/modules/juce_core/native/juce_curl_Network.cpp ++++ b/modules/juce_core/native/juce_curl_Network.cpp +@@ -332,6 +332,9 @@ public: + // or 3) data is in the in buffer + while ((! finished) && curlBuffer.getSize() == 0) + { ++ if (Thread::currentThreadShouldExit()) ++ return false; ++ + { + const ScopedLock lock (cleanupLock); + +diff --git a/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h b/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h +index 7f64d433d..e9360e0de 100644 +--- a/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h ++++ b/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h +@@ -74,6 +74,7 @@ struct SIMDNativeOps + static forcedinline __m128 JUCE_VECTOR_CALLTYPE add (__m128 a, __m128 b) noexcept { return _mm_add_ps (a, b); } + static forcedinline __m128 JUCE_VECTOR_CALLTYPE sub (__m128 a, __m128 b) noexcept { return _mm_sub_ps (a, b); } + static forcedinline __m128 JUCE_VECTOR_CALLTYPE mul (__m128 a, __m128 b) noexcept { return _mm_mul_ps (a, b); } ++ static forcedinline __m128 JUCE_VECTOR_CALLTYPE div (__m128 a, __m128 b) noexcept { return _mm_div_ps (a, b); } + static forcedinline __m128 JUCE_VECTOR_CALLTYPE bit_and (__m128 a, __m128 b) noexcept { return _mm_and_ps (a, b); } + static forcedinline __m128 JUCE_VECTOR_CALLTYPE bit_or (__m128 a, __m128 b) noexcept { return _mm_or_ps (a, b); } + static forcedinline __m128 JUCE_VECTOR_CALLTYPE bit_xor (__m128 a, __m128 b) noexcept { return _mm_xor_ps (a, b); } +@@ -142,6 +143,7 @@ struct SIMDNativeOps + static forcedinline __m128d JUCE_VECTOR_CALLTYPE add (__m128d a, __m128d b) noexcept { return _mm_add_pd (a, b); } + static forcedinline __m128d JUCE_VECTOR_CALLTYPE sub (__m128d a, __m128d b) noexcept { return _mm_sub_pd (a, b); } + static forcedinline __m128d JUCE_VECTOR_CALLTYPE mul (__m128d a, __m128d b) noexcept { return _mm_mul_pd (a, b); } ++ static forcedinline __m128d JUCE_VECTOR_CALLTYPE div (__m128d a, __m128d b) noexcept { return _mm_div_pd (a, b); } + static forcedinline __m128d JUCE_VECTOR_CALLTYPE bit_and (__m128d a, __m128d b) noexcept { return _mm_and_pd (a, b); } + static forcedinline __m128d JUCE_VECTOR_CALLTYPE bit_or (__m128d a, __m128d b) noexcept { return _mm_or_pd (a, b); } + static forcedinline __m128d JUCE_VECTOR_CALLTYPE bit_xor (__m128d a, __m128d b) noexcept { return _mm_xor_pd (a, b); } +diff --git a/modules/juce_events/native/juce_mac_MessageManager.mm b/modules/juce_events/native/juce_mac_MessageManager.mm +index 7a0718868..9d83519ff 100644 +--- a/modules/juce_events/native/juce_mac_MessageManager.mm ++++ b/modules/juce_events/native/juce_mac_MessageManager.mm +@@ -369,6 +369,7 @@ void MessageManager::runDispatchLoop() + static void shutdownNSApp() + { + [NSApp stop: nil]; ++ [NSEvent stopPeriodicEvents]; + [NSEvent startPeriodicEventsAfterDelay: 0 withPeriod: 0.1]; + } + +diff --git a/modules/juce_gui_basics/buttons/juce_Button.cpp b/modules/juce_gui_basics/buttons/juce_Button.cpp +index 1df2d6e20..e5c243eda 100644 +--- a/modules/juce_gui_basics/buttons/juce_Button.cpp ++++ b/modules/juce_gui_basics/buttons/juce_Button.cpp +@@ -482,10 +482,7 @@ void Button::mouseDrag (const MouseEvent& e) + + bool Button::isMouseSourceOver (const MouseEvent& e) + { +- if (e.source.isTouch() || e.source.isPen()) +- return getLocalBounds().toFloat().contains (e.position); +- +- return isMouseOver(); ++ return getLocalBounds().toFloat().contains (e.position); + } + + void Button::focusGained (FocusChangeType) +diff --git a/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp b/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp +index 314544638..f3b61e2c3 100644 +--- a/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp ++++ b/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp +@@ -76,9 +76,6 @@ void ShapeButton::setShape (const Path& newShape, + shape = newShape; + maintainShapeProportions = maintainShapeProportions_; + +- shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 3, Point())); +- setComponentEffect (hasShadow ? &shadow : nullptr); +- + if (resizeNowToFitThisShape) + { + auto newBounds = shape.getBounds(); +diff --git a/modules/juce_gui_basics/buttons/juce_ShapeButton.h b/modules/juce_gui_basics/buttons/juce_ShapeButton.h +index 6863b1cab..5f9cee9ee 100644 +--- a/modules/juce_gui_basics/buttons/juce_ShapeButton.h ++++ b/modules/juce_gui_basics/buttons/juce_ShapeButton.h +@@ -88,6 +88,8 @@ public: + Colour overColourOn, + Colour downColourOn); + ++ void setShadowColour (Colour shadow) { shadowColour = shadow; } ++ + /** Set whether the button should use the 'on' set of colours when its toggle state is 'on'. + By default these will be the same as the normal colours but the setOnColours method can be + used to provide a different set of colours. +@@ -112,9 +114,8 @@ public: + private: + //============================================================================== + Colour normalColour, overColour, downColour, +- normalColourOn, overColourOn, downColourOn, outlineColour; ++ normalColourOn, overColourOn, downColourOn, outlineColour, shadowColour; + bool useOnColours; +- DropShadowEffect shadow; + Path shape; + BorderSize border; + bool maintainShapeProportions; +diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp +index fa8d3ccf5..b2d75c655 100644 +--- a/modules/juce_gui_basics/components/juce_Component.cpp ++++ b/modules/juce_gui_basics/components/juce_Component.cpp +@@ -3021,7 +3021,8 @@ void Component::modifierKeysChanged (const ModifierKeys& modifiers) + + void Component::internalModifierKeysChanged() + { +- sendFakeMouseMove(); ++ auto mainMouse = Desktop::getInstance().getMainMouseSource(); ++ mainMouse.triggerFakeMove(); + modifierKeysChanged (ModifierKeys::currentModifiers); + } + +diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h +index 3add1db6b..ca84bc80e 100644 +--- a/modules/juce_gui_basics/components/juce_Component.h ++++ b/modules/juce_gui_basics/components/juce_Component.h +@@ -439,7 +439,7 @@ public: + + @see setBounds, ComponentListener::componentMovedOrResized + */ +- void setTopLeftPosition (Point newTopLeftPosition); ++ virtual void setTopLeftPosition (Point newTopLeftPosition); + + /** Moves the component to a new position. + +diff --git a/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp b/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp +index 7c6b83fbf..a84cf5a91 100644 +--- a/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp ++++ b/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp +@@ -43,14 +43,9 @@ void CaretComponent::paint (Graphics& g) + g.fillRect (getLocalBounds()); + } + +-void CaretComponent::timerCallback() +-{ +- setVisible (shouldBeShown() && ! isVisible()); +-} + + void CaretComponent::setCaretPosition (const Rectangle& characterArea) + { +- startTimer (380); + setVisible (shouldBeShown()); + setBounds (characterArea.withWidth (2)); + } +diff --git a/modules/juce_gui_basics/keyboard/juce_CaretComponent.h b/modules/juce_gui_basics/keyboard/juce_CaretComponent.h +index a10b26c69..97894c075 100644 +--- a/modules/juce_gui_basics/keyboard/juce_CaretComponent.h ++++ b/modules/juce_gui_basics/keyboard/juce_CaretComponent.h +@@ -31,8 +31,7 @@ namespace juce + + @tags{GUI} + */ +-class JUCE_API CaretComponent : public Component, +- private Timer ++class JUCE_API CaretComponent : public Component + { + public: + //============================================================================== +@@ -73,7 +72,6 @@ private: + Component* owner; + + bool shouldBeShown() const; +- void timerCallback() override; + + JUCE_DECLARE_NON_COPYABLE (CaretComponent) + }; +diff --git a/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp b/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp +index 9ea63b215..7e8f14993 100644 +--- a/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp ++++ b/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp +@@ -271,23 +271,6 @@ void ComponentBoundsConstrainer::checkBounds (Rectangle& bounds, + bounds.setWidth (roundToInt (bounds.getHeight() * aspectRatio)); + } + } +- +- if ((isStretchingTop || isStretchingBottom) && ! (isStretchingLeft || isStretchingRight)) +- { +- bounds.setX (old.getX() + (old.getWidth() - bounds.getWidth()) / 2); +- } +- else if ((isStretchingLeft || isStretchingRight) && ! (isStretchingTop || isStretchingBottom)) +- { +- bounds.setY (old.getY() + (old.getHeight() - bounds.getHeight()) / 2); +- } +- else +- { +- if (isStretchingLeft) +- bounds.setX (old.getRight() - bounds.getWidth()); +- +- if (isStretchingTop) +- bounds.setY (old.getBottom() - bounds.getHeight()); +- } + } + + jassert (! bounds.isEmpty()); +diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp +index 738fed8c1..f9f79994c 100644 +--- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp ++++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp +@@ -41,8 +41,6 @@ LookAndFeel_V1::LookAndFeel_V1() + setColour (PopupMenu::highlightedBackgroundColourId, Colour (0xbfa4c2ce)); + setColour (PopupMenu::highlightedTextColourId, Colours::black); + setColour (TextEditor::focusedOutlineColourId, findColour (TextButton::buttonColourId)); +- +- scrollbarShadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 2, Point())); + } + + LookAndFeel_V1::~LookAndFeel_V1() +@@ -291,7 +289,7 @@ void LookAndFeel_V1::drawScrollbar (Graphics& g, ScrollBar& bar, + + ImageEffectFilter* LookAndFeel_V1::getScrollbarEffect() + { +- return &scrollbarShadow; ++ return nullptr; + } + + +@@ -477,7 +475,7 @@ Button* LookAndFeel_V1::createSliderButton (Slider&, const bool isIncrement) + + ImageEffectFilter* LookAndFeel_V1::getSliderEffect (Slider&) + { +- return &scrollbarShadow; ++ return nullptr; + } + + int LookAndFeel_V1::getSliderThumbRadius (Slider&) +diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h +index b6c05aed7..51508a57a 100644 +--- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h ++++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h +@@ -97,8 +97,6 @@ public: + bool positionTitleBarButtonsOnLeft) override; + + private: +- DropShadowEffect scrollbarShadow; +- + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V1) + }; + +diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp +index 21042d0b2..829fed8e6 100644 +--- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp ++++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp +@@ -1292,8 +1292,6 @@ void LookAndFeel_V4::drawCallOutBoxBackground (CallOutBox& box, Graphics& g, + { + cachedImage = { Image::ARGB, box.getWidth(), box.getHeight(), true }; + Graphics g2 (cachedImage); +- +- DropShadow (Colours::black.withAlpha (0.7f), 8, { 0, 2 }).drawForPath (g2, path); + } + + g.setColour (Colours::black); +diff --git a/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp b/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp +index 7c0848644..2017bccb5 100644 +--- a/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp ++++ b/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp +@@ -30,9 +30,6 @@ BubbleComponent::BubbleComponent() + : allowablePlacements (above | below | left | right) + { + setInterceptsMouseClicks (false, false); +- +- shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.35f), 5, Point())); +- setComponentEffect (&shadow); + } + + BubbleComponent::~BubbleComponent() {} +diff --git a/modules/juce_gui_basics/misc/juce_BubbleComponent.h b/modules/juce_gui_basics/misc/juce_BubbleComponent.h +index f086c8ff3..cca6205a3 100644 +--- a/modules/juce_gui_basics/misc/juce_BubbleComponent.h ++++ b/modules/juce_gui_basics/misc/juce_BubbleComponent.h +@@ -178,7 +178,6 @@ private: + Rectangle content; + Point arrowTip; + int allowablePlacements; +- DropShadowEffect shadow; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BubbleComponent) + }; +diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +index f18b890f4..e92e9af14 100644 +--- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp ++++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +@@ -1816,7 +1816,7 @@ public: + if (peerIsDeleted) + return S_FALSE; + +- peer.handleDragExit (dragInfo); ++ peer.handleDragDrop (dragInfo); + return S_OK; + } + +diff --git a/modules/juce_gui_basics/widgets/juce_Slider.cpp b/modules/juce_gui_basics/widgets/juce_Slider.cpp +index 731193ff1..0f68f6efa 100644 +--- a/modules/juce_gui_basics/widgets/juce_Slider.cpp ++++ b/modules/juce_gui_basics/widgets/juce_Slider.cpp +@@ -749,7 +749,7 @@ public: + ? e.position.x - mouseDragStartPos.x + : mouseDragStartPos.y - e.position.y; + +- newPos = owner.valueToProportionOfLength (valueOnMouseDown) ++ newPos = owner.valueToProportionOfLength (valueWhenLastDragged) + + mouseDiff * (1.0 / pixelsForFullDragExtent); + + if (style == IncDecButtons) +@@ -763,7 +763,7 @@ public: + auto mouseDiff = (e.position.x - mouseDragStartPos.x) + + (mouseDragStartPos.y - e.position.y); + +- newPos = owner.valueToProportionOfLength (valueOnMouseDown) ++ newPos = owner.valueToProportionOfLength (valueWhenLastDragged) + + mouseDiff * (1.0 / pixelsForFullDragExtent); + } + else +@@ -774,6 +774,7 @@ public: + newPos = 1.0 - newPos; + } + ++ mouseDragStartPos = e.position; + newPos = (isRotary() && ! rotaryParams.stopAtEnd) ? newPos - std::floor (newPos) + : jlimit (0.0, 1.0, newPos); + valueWhenLastDragged = owner.proportionOfLengthToValue (newPos); +diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +index 233c23305..70afc33a1 100644 +--- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp ++++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +@@ -833,6 +833,11 @@ struct TextEditor::TextHolderComponent : public Component, + { + owner.drawContent (g); + } ++ ++ void setTopLeftPosition(Point new_position) override { ++ Component::setTopLeftPosition(new_position); ++ owner.textChanged(); ++ } + + void restartTimer() + { +@@ -1558,6 +1563,9 @@ void TextEditor::moveCaretTo (const int newPosition, const bool isSelecting) + moveCaret (newPosition); + selection = Range::emptyRange (getCaretPosition()); + } ++ ++ if (listeners.size() != 0 || onTextChange != nullptr) ++ postCommandMessage (TextEditorDefs::textChangeMessageId); + } + + int TextEditor::getTextIndexAt (const int x, const int y) +@@ -2141,6 +2149,9 @@ void TextEditor::focusGained (FocusChangeType cause) + + repaint(); + updateCaretPosition(); ++ ++ if (listeners.size() != 0 || onTextChange != nullptr) ++ postCommandMessage (TextEditorDefs::textChangeMessageId); + } + + void TextEditor::focusLost (FocusChangeType) diff --git a/libs/juce-current/patches/25_x11-crash-on-close-workaround.patch b/libs/juce-current/patches/25_x11-crash-on-close-workaround.patch new file mode 100644 index 00000000..21577dce --- /dev/null +++ b/libs/juce-current/patches/25_x11-crash-on-close-workaround.patch @@ -0,0 +1,104 @@ +diff --git a/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp b/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp +index d6508e09f..3964201a3 100644 +--- a/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp ++++ b/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp +@@ -27,7 +27,6 @@ namespace juce + { + + extern void* createDraggingHandCursor(); +-extern ComponentPeer* getPeerFor (::Window); + + //============================================================================== + class X11DragState +diff --git a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp +index 490a3a792..e2194f65e 100644 +--- a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp ++++ b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp +@@ -1378,7 +1378,49 @@ namespace ClipboardHelpers + } + + //============================================================================== +-ComponentPeer* getPeerFor (::Window windowH) ++/* Workaround JUCE saving context in wrong Windows. ++ * JUCE is storing pointers as X11 Window context, but these pointers are sometimes in separate, multiple windows. ++ * This leads to double-free. ++ * Maybe X11 is the one in the wrong? It shouldn't be giving valid Window context pointers for invalid Windows... ++ */ ++class ValidWindowChecker ++{ ++public: ++ ValidWindowChecker (::Window windowH) ++ : oldErrorHandler (X11Symbols::getInstance()->xSetErrorHandler (s_errorCallback)), ++ wmhints (XGetWMHints (XWindowSystem::getInstance()->getDisplay(), (XID) windowH)), ++ errored (s_errorTriggered) {} ++ ++ ~ValidWindowChecker() ++ { ++ if (wmhints != nullptr) ++ XFree (wmhints); ++ ++ X11Symbols::getInstance()->xSetErrorHandler (oldErrorHandler); ++ s_errorTriggered = false; ++ } ++ ++ bool isInvalid() const noexcept ++ { ++ return errored; ++ } ++ ++private: ++ const XErrorHandler oldErrorHandler; ++ XWMHints* const wmhints; ++ const bool errored; ++ ++ static bool s_errorTriggered; ++ static int s_errorCallback(::Display*, XErrorEvent*) ++ { ++ s_errorTriggered = true; ++ return 0; ++ } ++}; ++bool ValidWindowChecker::s_errorTriggered = false; ++ ++//============================================================================== ++ComponentPeer* getPeerFor (::Window windowH, bool checkValidWindow) + { + if (windowH == 0) + return nullptr; +@@ -1388,7 +1430,15 @@ ComponentPeer* getPeerFor (::Window windowH) + if (auto* display = XWindowSystem::getInstance()->getDisplay()) + { + XWindowSystemUtilities::ScopedXLock xLock; +- X11Symbols::getInstance()->xFindContext (display, (XID) windowH, windowHandleXContext, &peer); ++ int ret = X11Symbols::getInstance()->xFindContext (display, (XID) windowH, windowHandleXContext, &peer); ++ ++ if (ret == 0 && checkValidWindow) ++ { ++ const ValidWindowChecker vwc (windowH); ++ ++ if (vwc.isInvalid()) ++ peer = nullptr; ++ } + } + + return unalignedPointerCast (peer); +@@ -3677,7 +3727,7 @@ void XWindowSystem::windowMessageReceive (XEvent& event) + if (! juce_handleXEmbedEvent (nullptr, &event)) + #endif + { +- if (auto* peer = dynamic_cast (getPeerFor (event.xany.window))) ++ if (auto* peer = dynamic_cast (getPeerFor (event.xany.window, true))) + { + XWindowSystem::getInstance()->handleWindowMessage (peer, event); + return; +diff --git a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h +index 3f804a2fc..5eb22f993 100644 +--- a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h ++++ b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h +@@ -261,4 +261,6 @@ private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XWindowSystem) + }; + ++ComponentPeer* getPeerFor (::Window windowH, bool checkValidWindow = false); ++ + } // namespace juce