1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-23 01:44:22 +00:00

When opening an X display, made it attempt a retry if the first attempt fails.

This commit is contained in:
jules 2017-10-11 09:10:13 +01:00
parent 9ac84e07b4
commit 828b9b3be6
2 changed files with 57 additions and 58 deletions

View file

@ -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,

View file

@ -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<int> 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