Browse Source

Crash on close workaround (for at least vitalium lv2)

Fixes #66

Signed-off-by: falkTX <falktx@falktx.com>
tags/2021-03-15
falkTX 1 year ago
parent
commit
8f7eed6403
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
3 changed files with 55 additions and 4 deletions
  1. +0
    -1
      libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp
  2. +53
    -3
      libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
  3. +2
    -0
      libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h

+ 0
- 1
libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp View File

@@ -27,7 +27,6 @@ namespace juce
{
extern void* createDraggingHandCursor();
extern ComponentPeer* getPeerFor (::Window);
//==============================================================================
class X11DragState


+ 53
- 3
libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp View File

@@ -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<ComponentPeer*> (peer);
@@ -3677,7 +3727,7 @@ void XWindowSystem::windowMessageReceive (XEvent& event)
if (! juce_handleXEmbedEvent (nullptr, &event))
#endif
{
if (auto* peer = dynamic_cast<LinuxComponentPeer*> (getPeerFor (event.xany.window)))
if (auto* peer = dynamic_cast<LinuxComponentPeer*> (getPeerFor (event.xany.window, true)))
{
XWindowSystem::getInstance()->handleWindowMessage (peer, event);
return;


+ 2
- 0
libs/juce-current/source/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h View File

@@ -261,4 +261,6 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XWindowSystem)
};
ComponentPeer* getPeerFor (::Window windowH, bool checkValidWindow = false);
} // namespace juce

Loading…
Cancel
Save