diff --git a/src/mumble/Overlay.cpp b/src/mumble/Overlay.cpp index 11023d9b9..055f47e03 100644 --- a/src/mumble/Overlay.cpp +++ b/src/mumble/Overlay.cpp @@ -185,11 +185,45 @@ QRectF OverlayGroup::boundingRect() const { } Overlay::Overlay() : QObject() { - d = NULL; + d = nullptr; - platformInit(); - forceSettings(); + m_initialized.store(false); + qlsServer = nullptr; + + QMetaObject::connectSlotsByName(this); +} + +Overlay::~Overlay() { + setActive(false); + if (d) { + delete d; + } + + // Need to be deleted first, since destructor references lingering QLocalSockets + foreach(OverlayClient *oc, qlClients) + { + // As we're the one closing the connection, we do not need to be + // notified of disconnects. This is important because on disconnect we + // also remove (and 'delete') the overlay client. + disconnect(oc->qlsSocket, SIGNAL(disconnected()), this, SLOT(disconnected())); + disconnect(oc->qlsSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(error(QLocalSocket::LocalSocketError))); + delete oc; + } +} + +void Overlay::setActive(bool act) { + if (!m_initialized.load()) { + platformInit(); + forceSettings(); + + m_initialized.store(true); + } + + setActiveInternal(act); +} + +void Overlay::createPipe() { qlsServer = new QLocalServer(this); // Allow anyone to access the pipe in order to communicate with the overlay qlsServer->setSocketOptions(QLocalServer::WorldAccessOption); @@ -224,31 +258,12 @@ Overlay::Overlay() : QObject() { qWarning() << "Overlay: Listening on" << qlsServer->fullServerName(); connect(qlsServer, SIGNAL(newConnection()), this, SLOT(newConnection())); } - - QMetaObject::connectSlotsByName(this); -} - -Overlay::~Overlay() { - setActive(false); - delete d; - - // Need to be deleted first, since destructor references lingering QLocalSockets - foreach(OverlayClient *oc, qlClients) - { - // As we're the one closing the connection, we do not need to be - // notified of disconnects. This is important because on disconnect we - // also remove (and 'delete') the overlay client. - disconnect(oc->qlsSocket, SIGNAL(disconnected()), this, SLOT(disconnected())); - disconnect(oc->qlsSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(error(QLocalSocket::LocalSocketError))); - delete oc; - } } void Overlay::newConnection() { - while (true) { + while (qlsServer && qlsServer->hasPendingConnections()) { QLocalSocket *qls = qlsServer->nextPendingConnection(); - if (! qls) - break; + OverlayClient *oc = new OverlayClient(qls, this); qlClients << oc; diff --git a/src/mumble/Overlay.h b/src/mumble/Overlay.h index c899a5b55..fb1bfb5a1 100644 --- a/src/mumble/Overlay.h +++ b/src/mumble/Overlay.h @@ -15,6 +15,8 @@ #include "OverlayText.h" #include "../../overlay/overlay.h" +#include + #include "ui_OverlayEditor.h" #ifdef Q_OS_MAC @@ -84,8 +86,14 @@ class Overlay : public QObject { QSet qsQueried; QSet qsQuery; + /// A flag indicating if the platformInit has been called already + std::atomic m_initialized; + // These 2 functions (among others) are implemented by the system-specific backend void platformInit(); + void setActiveInternal(bool act); + + void createPipe(); QMap qmOverlayHash; QLocalServer *qlsServer; diff --git a/src/mumble/Overlay_macx.mm b/src/mumble/Overlay_macx.mm index d12203bbd..a4a51ca16 100644 --- a/src/mumble/Overlay_macx.mm +++ b/src/mumble/Overlay_macx.mm @@ -175,8 +175,11 @@ void Overlay::platformInit() { d = new OverlayPrivateMac(this); } -void Overlay::setActive(bool act) { - static_cast(d)->setActive(act); +void Overlay::setActiveInternal(bool act) { + if (d) { + /// Only act if the private instance has been created already + static_cast(d)->setActive(act); + } } bool OverlayConfig::supportsInstallableOverlay() { diff --git a/src/mumble/Overlay_unix.cpp b/src/mumble/Overlay_unix.cpp index e16ce833f..a2b51890c 100644 --- a/src/mumble/Overlay_unix.cpp +++ b/src/mumble/Overlay_unix.cpp @@ -10,7 +10,7 @@ void Overlay::platformInit() { d = NULL; } -void Overlay::setActive(bool) { +void Overlay::setActiveInternal(bool) { } bool OverlayConfig::supportsInstallableOverlay() { diff --git a/src/mumble/Overlay_win.cpp b/src/mumble/Overlay_win.cpp index 044c70303..6da0304ec 100644 --- a/src/mumble/Overlay_win.cpp +++ b/src/mumble/Overlay_win.cpp @@ -320,8 +320,11 @@ void Overlay::platformInit() { d = new OverlayPrivateWin(this); } -void Overlay::setActive(bool act) { - static_cast(d)->setActive(act); +void Overlay::setActiveInternal(bool act) { + if (d) { + // Only act if the private instance has been created already + static_cast(d)->setActive(act); + } } bool OverlayConfig::supportsInstallableOverlay() {