src/mumble/Overlay*: Don't hook into any process before the Overlay is active

Right now the Overlay will start hooking into processes on its
construction. This will cause this to happen even if the overlay is
actually disabled. This is a rather intrusive behavior and can lead to
warnings of the OS (for now macOS only - #3552).

This commit refactors the Overlay class so that it will only start
hooking into processes, if it is actually enabled (that is setActive is
called with true).
This commit is contained in:
Robert Adam 2020-04-05 09:33:47 +02:00
parent 62c2735c48
commit aac3214d4b
5 changed files with 58 additions and 29 deletions

View File

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

View File

@ -15,6 +15,8 @@
#include "OverlayText.h"
#include "../../overlay/overlay.h"
#include <atomic>
#include "ui_OverlayEditor.h"
#ifdef Q_OS_MAC
@ -84,8 +86,14 @@ class Overlay : public QObject {
QSet<unsigned int> qsQueried;
QSet<unsigned int> qsQuery;
/// A flag indicating if the platformInit has been called already
std::atomic<bool> m_initialized;
// These 2 functions (among others) are implemented by the system-specific backend
void platformInit();
void setActiveInternal(bool act);
void createPipe();
QMap<QString, QString> qmOverlayHash;
QLocalServer *qlsServer;

View File

@ -175,8 +175,11 @@ void Overlay::platformInit() {
d = new OverlayPrivateMac(this);
}
void Overlay::setActive(bool act) {
static_cast<OverlayPrivateMac *>(d)->setActive(act);
void Overlay::setActiveInternal(bool act) {
if (d) {
/// Only act if the private instance has been created already
static_cast<OverlayPrivateMac *>(d)->setActive(act);
}
}
bool OverlayConfig::supportsInstallableOverlay() {

View File

@ -10,7 +10,7 @@ void Overlay::platformInit() {
d = NULL;
}
void Overlay::setActive(bool) {
void Overlay::setActiveInternal(bool) {
}
bool OverlayConfig::supportsInstallableOverlay() {

View File

@ -320,8 +320,11 @@ void Overlay::platformInit() {
d = new OverlayPrivateWin(this);
}
void Overlay::setActive(bool act) {
static_cast<OverlayPrivateWin *>(d)->setActive(act);
void Overlay::setActiveInternal(bool act) {
if (d) {
// Only act if the private instance has been created already
static_cast<OverlayPrivateWin *>(d)->setActive(act);
}
}
bool OverlayConfig::supportsInstallableOverlay() {