Skip to content

Commit

Permalink
refactor(IPC): Remove activate's handler reliance on global state
Browse files Browse the repository at this point in the history
Register in Widget's constructor so that handler can always get back to
Widget.

Add unregistration functionality so that the handler doesn't run when
we've returned to the login window or when exiting.
  • Loading branch information
anthonybilinski committed May 22, 2022
1 parent 6ad92bb commit 40b339b
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 29 deletions.
8 changes: 8 additions & 0 deletions src/ipc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,16 @@ bool IPC::isCurrentOwner()
*/
void IPC::registerEventHandler(const QString& name, IPCEventHandler handler, void* userData)
{
const std::lock_guard<std::mutex> lock(eventHandlersMutex);
eventHandlers[name] = {handler, userData};
}

void IPC::unregisterEventHandler(const QString& name)
{
const std::lock_guard<std::mutex> lock(eventHandlersMutex);
eventHandlers.remove(name);
}

bool IPC::isEventAccepted(time_t time)
{
bool result = false;
Expand Down Expand Up @@ -309,6 +316,7 @@ void IPC::processEvents()
// Non-main instance is limited to events destined for specific profile it runs
}

const std::lock_guard<std::mutex> lock(eventHandlersMutex);
while (IPCEvent* evt = fetchEvent()) {
QString name = QString::fromUtf8(evt->name);
auto it = eventHandlers.find(name);
Expand Down
5 changes: 4 additions & 1 deletion src/ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QTimer>
#include <ctime>
#include <functional>
#include <mutex>

using IPCEventHandler = std::function<bool(const QByteArray&, void*)>;

Expand All @@ -42,7 +43,7 @@ class IPC : public QObject
static const int OWNERSHIP_TIMEOUT_S = 5;

public:
IPC(uint32_t profileId_);
explicit IPC(uint32_t profileId_);
~IPC();

struct IPCEvent
Expand All @@ -69,6 +70,7 @@ class IPC : public QObject
time_t postEvent(const QString& name, const QByteArray& data = QByteArray(), uint32_t dest = 0);
bool isCurrentOwner();
void registerEventHandler(const QString& name, IPCEventHandler handler, void* userData);
void unregisterEventHandler(const QString& name);
bool isEventAccepted(time_t time);
bool waitUntilAccepted(time_t time, int32_t timeout = -1);
bool isAttached() const;
Expand All @@ -93,5 +95,6 @@ public slots:
uint64_t globalId;
uint32_t profileId;
QSharedMemory globalMemory;
mutable std::mutex eventHandlersMutex;
QMap<QString, Callback> eventHandlers;
};
11 changes: 6 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ int main(int argc, char* argv[])
if (firstParam.startsWith("tox:")) {
eventType = "uri";
} else if (firstParam.endsWith(".tox")) {
eventType = "save";
eventType = ToxSave::eventHandlerKey;
} else {
qCritical() << "Invalid argument";
return EXIT_FAILURE;
Expand Down Expand Up @@ -403,6 +403,7 @@ int main(int argc, char* argv[])
// cannot be integrated into a central model object yet
nexus.setSettings(settings.get());
nexus.setMessageBoxManager(messageBoxManager.get());
nexus.setIpc(&ipc);
auto& cameraSource = Nexus::getCameraSource();
// Autologin
// TODO (kriby): Shift responsibility of linking views to model objects from nexus
Expand All @@ -427,19 +428,19 @@ int main(int argc, char* argv[])
}

uriDialog = std::unique_ptr<ToxURIDialog>(new ToxURIDialog(nullptr, profile->getCore(), *messageBoxManager));
toxSave = std::unique_ptr<ToxSave>(new ToxSave{*settings});
toxSave = std::unique_ptr<ToxSave>(new ToxSave{*settings, ipc});

if (ipc.isAttached()) {
// Start to accept Inter-process communication
ipc.registerEventHandler("uri", &toxURIEventHandler, uriDialog.get());
ipc.registerEventHandler("save", &ToxSave::toxSaveEventHandler, toxSave.get());
ipc.registerEventHandler("activate", &toxActivateEventHandler, nullptr);
ipc.registerEventHandler(ToxSave::eventHandlerKey, &ToxSave::toxSaveEventHandler, toxSave.get());
nexus.registerActivate();
}

// Event was not handled by already running instance therefore we handle it ourselves
if (eventType == "uri") {
uriDialog->handleToxURI(firstParam);
} else if (eventType == "save") {
} else if (eventType == ToxSave::eventHandlerKey) {
toxSave->handleToxSave(firstParam);
}

Expand Down
13 changes: 12 additions & 1 deletion src/nexus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ void Nexus::showMainGUI()
assert(profile);

// Create GUI
widget = new Widget(*profile, *audioControl, *cameraSource, *settings, *style);
widget = new Widget(*profile, *audioControl, *cameraSource, *settings, *style,
*ipc);

// Start GUI
widget->init();
Expand Down Expand Up @@ -349,6 +350,16 @@ void Nexus::setMessageBoxManager(IMessageBoxManager* messageBoxManager_)
messageBoxManager = messageBoxManager_;
}

void Nexus::setIpc(IPC* ipc_)
{
ipc = ipc_;
}

void Nexus::registerActivate()
{
widget->registerActivate();
}

#ifdef Q_OS_MAC
void Nexus::retranslateUi()
{
Expand Down
4 changes: 4 additions & 0 deletions src/nexus.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class QCommandLineParser;
class CameraSource;
class Style;
class IMessageBoxManager;
class IPC;

#ifdef Q_OS_MAC
class QMenuBar;
Expand All @@ -53,12 +54,14 @@ class Nexus : public QObject
void showMainGUI();
void setSettings(Settings* settings_);
void setMessageBoxManager(IMessageBoxManager* messageBoxManager);
void setIpc(IPC* ipc);
void setParser(QCommandLineParser* parser_);
static Nexus& getInstance();
static void destroyInstance();
Profile* getProfile();
static Widget* getDesktopGUI();
static CameraSource& getCameraSource();
void registerActivate();


#ifdef Q_OS_MAC
Expand Down Expand Up @@ -113,4 +116,5 @@ public slots:
std::unique_ptr<CameraSource> cameraSource;
std::unique_ptr<Style> style;
IMessageBoxManager* messageBoxManager = nullptr;
IPC* ipc = nullptr;
};
12 changes: 11 additions & 1 deletion src/persistence/toxsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,23 @@
#include "src/persistence/settings.h"
#include "src/widget/widget.h"
#include "src/nexus.h"
#include "src/ipc.h"
#include "src/widget/tool/profileimporter.h"
#include <QCoreApplication>
#include <QString>

ToxSave::ToxSave(Settings& settings_)
const QString ToxSave::eventHandlerKey = QStringLiteral("save");

ToxSave::ToxSave(Settings& settings_, IPC& ipc_)
: settings{settings_}
, ipc{ipc_}
{}

ToxSave::~ToxSave()
{
ipc.unregisterEventHandler(eventHandlerKey);
}

bool ToxSave::toxSaveEventHandler(const QByteArray& eventData, void* userData)
{
auto toxSave = static_cast<ToxSave*>(userData);
Expand Down
7 changes: 6 additions & 1 deletion src/persistence/toxsave.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@
class QString;
class QByteArray;
class Settings;
class IPC;
class QString;

class ToxSave
{
public:
explicit ToxSave(Settings& settings);
const static QString eventHandlerKey;
ToxSave(Settings& settings, IPC& ipc);
~ToxSave();
bool handleToxSave(const QString& path);
static bool toxSaveEventHandler(const QByteArray& eventData, void* userData);

private:
Settings& settings;
IPC& ipc;
};
38 changes: 22 additions & 16 deletions src/widget/widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,7 @@
#include "src/widget/tool/messageboxmanager.h"
#include "tool/removechatdialog.h"
#include "src/persistence/smileypack.h"

bool toxActivateEventHandler(const QByteArray& data, void* userData)
{
std::ignore = data;
std::ignore = userData;
Widget* widget = Nexus::getDesktopGUI();
if (!widget) {
return true;
}

qDebug() << "Handling [activate] event from other instance";
widget->forceShow();

return true;
}
#include "src/ipc.h"

namespace {

Expand All @@ -111,8 +97,20 @@ bool tryRemoveFile(const QString& filepath)
tmp.remove();
return writable;
}

const QString activateHandlerKey("activate");

} // namespace

bool Widget::toxActivateEventHandler(const QByteArray& data, void* userData)
{
std::ignore = data;

qDebug() << "Handling" << activateHandlerKey << "event from other instance";
static_cast<Widget*>(userData)->forceShow();
return true;
}

void Widget::acceptFileTransfer(const ToxFile& file, const QString& path)
{
QString filepath;
Expand Down Expand Up @@ -142,7 +140,7 @@ void Widget::acceptFileTransfer(const ToxFile& file, const QString& path)
Widget* Widget::instance{nullptr};

Widget::Widget(Profile &profile_, IAudioControl& audio_, CameraSource& cameraSource_,
Settings& settings_, Style& style_, QWidget* parent)
Settings& settings_, Style& style_, IPC& ipc_, QWidget* parent)
: QMainWindow(parent)
, profile{profile_}
, trayMenu{nullptr}
Expand All @@ -163,6 +161,7 @@ Widget::Widget(Profile &profile_, IAudioControl& audio_, CameraSource& cameraSou
, friendList(new FriendList())
, groupList(new GroupList())
, contentDialogManager(new ContentDialogManager(*friendList))
, ipc{ipc_}
{
installEventFilter(this);
QString locale = settings.getTranslation();
Expand Down Expand Up @@ -608,6 +607,8 @@ void Widget::updateIcons()

Widget::~Widget()
{
ipc.unregisterEventHandler(activateHandlerKey);

QWidgetList windowList = QApplication::topLevelWidgets();

for (QWidget* window : windowList) {
Expand Down Expand Up @@ -2755,3 +2756,8 @@ void Widget::formatWindowTitle(const QString& content)
setWindowTitle(content + " - qTox");
}
}

void Widget::registerActivate()
{
ipc.registerEventHandler(activateHandlerKey, &toxActivateEventHandler, this);
}
9 changes: 5 additions & 4 deletions src/widget/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class IMessageBoxManager;
class ContentDialogManager;
class FriendList;
class GroupList;
class RemoveChatDialog;
class IPC;

class Widget final : public QMainWindow
{
Expand Down Expand Up @@ -126,7 +126,7 @@ class Widget final : public QMainWindow

public:
Widget(Profile& profile_, IAudioControl& audio_, CameraSource& cameraSource,
Settings& settings, Style& style, QWidget* parent = nullptr);
Settings& settings, Style& style, IPC& ipc, QWidget* parent = nullptr);
~Widget() override;
void init();
void setCentralWidget(QWidget* widget, const QString& widgetName);
Expand Down Expand Up @@ -154,6 +154,8 @@ class Widget final : public QMainWindow
bool groupsVisible() const;

void resetIcon();
void registerActivate();
static bool toxActivateEventHandler(const QByteArray& data, void* userData);

public slots:
void reloadTheme();
Expand Down Expand Up @@ -397,6 +399,5 @@ private slots:
std::unique_ptr<FriendList> friendList;
std::unique_ptr<GroupList> groupList;
std::unique_ptr<ContentDialogManager> contentDialogManager;
IPC& ipc;
};

bool toxActivateEventHandler(const QByteArray& data, void* userData);

0 comments on commit 40b339b

Please sign in to comment.