From 828b9b3be6f7363903dd6e28a1388cc172eb2358 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 11 Oct 2017 09:10:13 +0100 Subject: [PATCH] When opening an X display, made it attempt a retry if the first attempt fails. --- .../juce_gui_basics/native/juce_linux_X11.cpp | 71 ++++++++++--------- .../juce_gui_basics/native/juce_linux_X11.h | 44 ++++++------ 2 files changed, 57 insertions(+), 58 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_linux_X11.cpp b/modules/juce_gui_basics/native/juce_linux_X11.cpp index e9625b65df..22dfbba5b7 100644 --- a/modules/juce_gui_basics/native/juce_linux_X11.cpp +++ b/modules/juce_gui_basics/native/juce_linux_X11.cpp @@ -34,14 +34,13 @@ typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); SelectionRequestCallback handleSelectionRequest = nullptr; ::Window juce_messageWindowHandle; - XContext windowHandleXContext; //============================================================================== namespace X11ErrorHandling { - static XErrorHandler oldErrorHandler = (XErrorHandler) 0; - static XIOErrorHandler oldIOErrorHandler = (XIOErrorHandler) 0; + static XErrorHandler oldErrorHandler = {}; + static XIOErrorHandler oldIOErrorHandler = {}; //============================================================================== // Usually happens when client-server connection is broken @@ -52,8 +51,6 @@ namespace X11ErrorHandling if (JUCEApplicationBase::isStandaloneApp()) MessageManager::getInstance()->stopDispatchLoop(); - // set this somewhere - // errorOccurred = true; return 0; } @@ -83,16 +80,15 @@ namespace X11ErrorHandling void removeXErrorHandlers() { XSetIOErrorHandler (oldIOErrorHandler); - oldIOErrorHandler = 0; + oldIOErrorHandler = {}; XSetErrorHandler (oldErrorHandler); - oldErrorHandler = 0; + oldErrorHandler = {}; } } //============================================================================== XWindowSystem::XWindowSystem() noexcept - : display (nullptr) { if (JUCEApplicationBase::isStandaloneApp()) { @@ -124,21 +120,31 @@ XWindowSystem::~XWindowSystem() noexcept clearSingletonInstance(); } - ::Display* XWindowSystem::displayRef() noexcept { - if (++displayCount - 1 == 0) + if (++displayCount == 1) { + jassert (display == nullptr); + String displayName (getenv ("DISPLAY")); + if (displayName.isEmpty()) displayName = ":0.0"; - display = XOpenDisplay (displayName.toUTF8()); + // it seems that on some systems XOpenDisplay will occasionally + // fail the first time, but succeed on a second attempt.. + for (int retries = 2; --retries >= 0;) + { + display = XOpenDisplay (displayName.toUTF8()); + + if (display != nullptr) + break; + } initialiseXDisplay(); } - return this->display; + return display; } ::Display* XWindowSystem::displayUnref() noexcept @@ -183,9 +189,10 @@ void XWindowSystem::initialiseXDisplay() noexcept // Setup input event handler int fd = XConnectionNumber (display); - LinuxEventLoop::setWindowSystemFd - (fd, - [this](int /*fd*/) { + + LinuxEventLoop::setWindowSystemFd (fd, + [this](int /*fd*/) + { do { XEvent evt; @@ -200,11 +207,15 @@ void XWindowSystem::initialiseXDisplay() noexcept } if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle - && handleSelectionRequest != nullptr) + && handleSelectionRequest != nullptr) + { handleSelectionRequest (evt.xselectionrequest); + } else if (evt.xany.window != juce_messageWindowHandle - && dispatchWindowMessage != nullptr) + && dispatchWindowMessage != nullptr) + { dispatchWindowMessage (evt); + } } while (display != nullptr); @@ -215,13 +226,9 @@ void XWindowSystem::initialiseXDisplay() noexcept void XWindowSystem::destroyXDisplay() noexcept { ScopedXLock xlock (display); - XDestroyWindow (display, juce_messageWindowHandle); - juce_messageWindowHandle = 0; - XSync (display, True); - LinuxEventLoop::removeWindowSystemFd(); } @@ -238,18 +245,20 @@ ScopedXDisplay::~ScopedXDisplay() } //============================================================================== -ScopedXLock::ScopedXLock(::Display* d) : display (d) +ScopedXLock::ScopedXLock (::Display* d) : display (d) { - if (display != nullptr) XLockDisplay (display); + if (display != nullptr) + XLockDisplay (display); } ScopedXLock::~ScopedXLock() { - if (display != nullptr) XUnlockDisplay (display); + if (display != nullptr) + XUnlockDisplay (display); } //============================================================================== -Atoms::Atoms(::Display* display) +Atoms::Atoms (::Display* display) { protocols = getIfExists (display, "WM_PROTOCOLS"); protocolList [TAKE_FOCUS] = getIfExists (display, "WM_TAKE_FOCUS"); @@ -293,15 +302,8 @@ Atoms::Atoms(::Display* display) allowedActions[4] = XdndActionPrivate; } -Atom Atoms::getIfExists (::Display* display, const char* name) -{ - return XInternAtom (display, name, True); -} - -Atom Atoms::getCreating (::Display* display, const char* name) -{ - return XInternAtom (display, name, False); -} +Atom Atoms::getIfExists (::Display* display, const char* name) { return XInternAtom (display, name, True); } +Atom Atoms::getCreating (::Display* display, const char* name) { return XInternAtom (display, name, False); } String Atoms::getName (::Display* display, const Atom atom) { @@ -323,7 +325,6 @@ const unsigned long Atoms::DndVersion = 3; GetXProperty::GetXProperty (::Display* display, Window window, Atom atom, long offset, long length, bool shouldDelete, Atom requestedType) - : data (nullptr) { success = (XGetWindowProperty (display, window, atom, offset, length, (Bool) shouldDelete, requestedType, &actualType, diff --git a/modules/juce_gui_basics/native/juce_linux_X11.h b/modules/juce_gui_basics/native/juce_linux_X11.h index f4235a7b9e..111126bb54 100644 --- a/modules/juce_gui_basics/native/juce_linux_X11.h +++ b/modules/juce_gui_basics/native/juce_linux_X11.h @@ -31,8 +31,8 @@ namespace juce typedef ::_XDisplay* XDisplay; -typedef unsigned long ATOM_TYPE; -typedef unsigned long WINDOW_TYPE; +typedef unsigned long AtomType; +typedef unsigned long WindowType; //============================================================================== @@ -45,7 +45,7 @@ public: juce_DeclareSingleton (XWindowSystem, false) private: - XDisplay display; + XDisplay display = {}; Atomic displayCount; XWindowSystem() noexcept; @@ -56,9 +56,9 @@ private: }; //============================================================================== -class ScopedXDisplay +/** Creates and holds a reference to the X display. */ +struct ScopedXDisplay { -public: ScopedXDisplay(); ~ScopedXDisplay(); @@ -99,41 +99,39 @@ struct Atoms PING = 2 }; - ATOM_TYPE protocols, protocolList[3], changeState, state, userTime, - activeWin, pid, windowType, windowState, - XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus, - XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList, - XdndActionDescription, XdndActionCopy, XdndActionPrivate, - XembedMsgType, XembedInfo, - allowedActions[5], - allowedMimeTypes[4]; + AtomType protocols, protocolList[3], changeState, state, userTime, + activeWin, pid, windowType, windowState, + XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus, + XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList, + XdndActionDescription, XdndActionCopy, XdndActionPrivate, + XembedMsgType, XembedInfo, + allowedActions[5], + allowedMimeTypes[4]; static const unsigned long DndVersion; - static ATOM_TYPE getIfExists (XDisplay, const char* name); - static ATOM_TYPE getCreating (XDisplay, const char* name); + static AtomType getIfExists (XDisplay, const char* name); + static AtomType getCreating (XDisplay, const char* name); - static String getName (XDisplay, ATOM_TYPE atom); + static String getName (XDisplay, AtomType); - static bool isMimeTypeFile (XDisplay, ATOM_TYPE atom); + static bool isMimeTypeFile (XDisplay, AtomType); }; //============================================================================== struct GetXProperty { - GetXProperty (XDisplay, WINDOW_TYPE window, ATOM_TYPE atom, + GetXProperty (XDisplay, WindowType, AtomType, long offset, long length, bool shouldDelete, - ATOM_TYPE requestedType); + AtomType requestedType); ~GetXProperty(); bool success; - unsigned char* data; + unsigned char* data = nullptr; unsigned long numItems, bytesLeft; - ATOM_TYPE actualType; + AtomType actualType; int actualFormat; }; -#undef ATOM_TYPE - } // namespace juce