mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
refactor(IPC): Remove activate's handler reliance on global state
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.
This commit is contained in:
parent
6ad92bb637
commit
40b339b367
@ -191,9 +191,16 @@ bool IPC::isCurrentOwner()
|
|||||||
*/
|
*/
|
||||||
void IPC::registerEventHandler(const QString& name, IPCEventHandler handler, void* userData)
|
void IPC::registerEventHandler(const QString& name, IPCEventHandler handler, void* userData)
|
||||||
{
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(eventHandlersMutex);
|
||||||
eventHandlers[name] = {handler, userData};
|
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 IPC::isEventAccepted(time_t time)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@ -309,6 +316,7 @@ void IPC::processEvents()
|
|||||||
// Non-main instance is limited to events destined for specific profile it runs
|
// 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()) {
|
while (IPCEvent* evt = fetchEvent()) {
|
||||||
QString name = QString::fromUtf8(evt->name);
|
QString name = QString::fromUtf8(evt->name);
|
||||||
auto it = eventHandlers.find(name);
|
auto it = eventHandlers.find(name);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
using IPCEventHandler = std::function<bool(const QByteArray&, void*)>;
|
using IPCEventHandler = std::function<bool(const QByteArray&, void*)>;
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ protected:
|
|||||||
static const int OWNERSHIP_TIMEOUT_S = 5;
|
static const int OWNERSHIP_TIMEOUT_S = 5;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IPC(uint32_t profileId_);
|
explicit IPC(uint32_t profileId_);
|
||||||
~IPC();
|
~IPC();
|
||||||
|
|
||||||
struct IPCEvent
|
struct IPCEvent
|
||||||
@ -69,6 +70,7 @@ public:
|
|||||||
time_t postEvent(const QString& name, const QByteArray& data = QByteArray(), uint32_t dest = 0);
|
time_t postEvent(const QString& name, const QByteArray& data = QByteArray(), uint32_t dest = 0);
|
||||||
bool isCurrentOwner();
|
bool isCurrentOwner();
|
||||||
void registerEventHandler(const QString& name, IPCEventHandler handler, void* userData);
|
void registerEventHandler(const QString& name, IPCEventHandler handler, void* userData);
|
||||||
|
void unregisterEventHandler(const QString& name);
|
||||||
bool isEventAccepted(time_t time);
|
bool isEventAccepted(time_t time);
|
||||||
bool waitUntilAccepted(time_t time, int32_t timeout = -1);
|
bool waitUntilAccepted(time_t time, int32_t timeout = -1);
|
||||||
bool isAttached() const;
|
bool isAttached() const;
|
||||||
@ -93,5 +95,6 @@ private:
|
|||||||
uint64_t globalId;
|
uint64_t globalId;
|
||||||
uint32_t profileId;
|
uint32_t profileId;
|
||||||
QSharedMemory globalMemory;
|
QSharedMemory globalMemory;
|
||||||
|
mutable std::mutex eventHandlersMutex;
|
||||||
QMap<QString, Callback> eventHandlers;
|
QMap<QString, Callback> eventHandlers;
|
||||||
};
|
};
|
||||||
|
11
src/main.cpp
11
src/main.cpp
@ -369,7 +369,7 @@ int main(int argc, char* argv[])
|
|||||||
if (firstParam.startsWith("tox:")) {
|
if (firstParam.startsWith("tox:")) {
|
||||||
eventType = "uri";
|
eventType = "uri";
|
||||||
} else if (firstParam.endsWith(".tox")) {
|
} else if (firstParam.endsWith(".tox")) {
|
||||||
eventType = "save";
|
eventType = ToxSave::eventHandlerKey;
|
||||||
} else {
|
} else {
|
||||||
qCritical() << "Invalid argument";
|
qCritical() << "Invalid argument";
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -403,6 +403,7 @@ int main(int argc, char* argv[])
|
|||||||
// cannot be integrated into a central model object yet
|
// cannot be integrated into a central model object yet
|
||||||
nexus.setSettings(settings.get());
|
nexus.setSettings(settings.get());
|
||||||
nexus.setMessageBoxManager(messageBoxManager.get());
|
nexus.setMessageBoxManager(messageBoxManager.get());
|
||||||
|
nexus.setIpc(&ipc);
|
||||||
auto& cameraSource = Nexus::getCameraSource();
|
auto& cameraSource = Nexus::getCameraSource();
|
||||||
// Autologin
|
// Autologin
|
||||||
// TODO (kriby): Shift responsibility of linking views to model objects from nexus
|
// TODO (kriby): Shift responsibility of linking views to model objects from nexus
|
||||||
@ -427,19 +428,19 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
uriDialog = std::unique_ptr<ToxURIDialog>(new ToxURIDialog(nullptr, profile->getCore(), *messageBoxManager));
|
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()) {
|
if (ipc.isAttached()) {
|
||||||
// Start to accept Inter-process communication
|
// Start to accept Inter-process communication
|
||||||
ipc.registerEventHandler("uri", &toxURIEventHandler, uriDialog.get());
|
ipc.registerEventHandler("uri", &toxURIEventHandler, uriDialog.get());
|
||||||
ipc.registerEventHandler("save", &ToxSave::toxSaveEventHandler, toxSave.get());
|
ipc.registerEventHandler(ToxSave::eventHandlerKey, &ToxSave::toxSaveEventHandler, toxSave.get());
|
||||||
ipc.registerEventHandler("activate", &toxActivateEventHandler, nullptr);
|
nexus.registerActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event was not handled by already running instance therefore we handle it ourselves
|
// Event was not handled by already running instance therefore we handle it ourselves
|
||||||
if (eventType == "uri") {
|
if (eventType == "uri") {
|
||||||
uriDialog->handleToxURI(firstParam);
|
uriDialog->handleToxURI(firstParam);
|
||||||
} else if (eventType == "save") {
|
} else if (eventType == ToxSave::eventHandlerKey) {
|
||||||
toxSave->handleToxSave(firstParam);
|
toxSave->handleToxSave(firstParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,8 @@ void Nexus::showMainGUI()
|
|||||||
assert(profile);
|
assert(profile);
|
||||||
|
|
||||||
// Create GUI
|
// Create GUI
|
||||||
widget = new Widget(*profile, *audioControl, *cameraSource, *settings, *style);
|
widget = new Widget(*profile, *audioControl, *cameraSource, *settings, *style,
|
||||||
|
*ipc);
|
||||||
|
|
||||||
// Start GUI
|
// Start GUI
|
||||||
widget->init();
|
widget->init();
|
||||||
@ -349,6 +350,16 @@ void Nexus::setMessageBoxManager(IMessageBoxManager* messageBoxManager_)
|
|||||||
messageBoxManager = messageBoxManager_;
|
messageBoxManager = messageBoxManager_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Nexus::setIpc(IPC* ipc_)
|
||||||
|
{
|
||||||
|
ipc = ipc_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nexus::registerActivate()
|
||||||
|
{
|
||||||
|
widget->registerActivate();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
void Nexus::retranslateUi()
|
void Nexus::retranslateUi()
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,7 @@ class QCommandLineParser;
|
|||||||
class CameraSource;
|
class CameraSource;
|
||||||
class Style;
|
class Style;
|
||||||
class IMessageBoxManager;
|
class IMessageBoxManager;
|
||||||
|
class IPC;
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
class QMenuBar;
|
class QMenuBar;
|
||||||
@ -53,12 +54,14 @@ public:
|
|||||||
void showMainGUI();
|
void showMainGUI();
|
||||||
void setSettings(Settings* settings_);
|
void setSettings(Settings* settings_);
|
||||||
void setMessageBoxManager(IMessageBoxManager* messageBoxManager);
|
void setMessageBoxManager(IMessageBoxManager* messageBoxManager);
|
||||||
|
void setIpc(IPC* ipc);
|
||||||
void setParser(QCommandLineParser* parser_);
|
void setParser(QCommandLineParser* parser_);
|
||||||
static Nexus& getInstance();
|
static Nexus& getInstance();
|
||||||
static void destroyInstance();
|
static void destroyInstance();
|
||||||
Profile* getProfile();
|
Profile* getProfile();
|
||||||
static Widget* getDesktopGUI();
|
static Widget* getDesktopGUI();
|
||||||
static CameraSource& getCameraSource();
|
static CameraSource& getCameraSource();
|
||||||
|
void registerActivate();
|
||||||
|
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
@ -113,4 +116,5 @@ private:
|
|||||||
std::unique_ptr<CameraSource> cameraSource;
|
std::unique_ptr<CameraSource> cameraSource;
|
||||||
std::unique_ptr<Style> style;
|
std::unique_ptr<Style> style;
|
||||||
IMessageBoxManager* messageBoxManager = nullptr;
|
IMessageBoxManager* messageBoxManager = nullptr;
|
||||||
|
IPC* ipc = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -21,13 +21,23 @@
|
|||||||
#include "src/persistence/settings.h"
|
#include "src/persistence/settings.h"
|
||||||
#include "src/widget/widget.h"
|
#include "src/widget/widget.h"
|
||||||
#include "src/nexus.h"
|
#include "src/nexus.h"
|
||||||
|
#include "src/ipc.h"
|
||||||
#include "src/widget/tool/profileimporter.h"
|
#include "src/widget/tool/profileimporter.h"
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
ToxSave::ToxSave(Settings& settings_)
|
const QString ToxSave::eventHandlerKey = QStringLiteral("save");
|
||||||
|
|
||||||
|
ToxSave::ToxSave(Settings& settings_, IPC& ipc_)
|
||||||
: settings{settings_}
|
: settings{settings_}
|
||||||
|
, ipc{ipc_}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
ToxSave::~ToxSave()
|
||||||
|
{
|
||||||
|
ipc.unregisterEventHandler(eventHandlerKey);
|
||||||
|
}
|
||||||
|
|
||||||
bool ToxSave::toxSaveEventHandler(const QByteArray& eventData, void* userData)
|
bool ToxSave::toxSaveEventHandler(const QByteArray& eventData, void* userData)
|
||||||
{
|
{
|
||||||
auto toxSave = static_cast<ToxSave*>(userData);
|
auto toxSave = static_cast<ToxSave*>(userData);
|
||||||
|
@ -22,14 +22,19 @@
|
|||||||
class QString;
|
class QString;
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
class Settings;
|
class Settings;
|
||||||
|
class IPC;
|
||||||
|
class QString;
|
||||||
|
|
||||||
class ToxSave
|
class ToxSave
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ToxSave(Settings& settings);
|
const static QString eventHandlerKey;
|
||||||
|
ToxSave(Settings& settings, IPC& ipc);
|
||||||
|
~ToxSave();
|
||||||
bool handleToxSave(const QString& path);
|
bool handleToxSave(const QString& path);
|
||||||
static bool toxSaveEventHandler(const QByteArray& eventData, void* userData);
|
static bool toxSaveEventHandler(const QByteArray& eventData, void* userData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Settings& settings;
|
Settings& settings;
|
||||||
|
IPC& ipc;
|
||||||
};
|
};
|
||||||
|
@ -81,21 +81,7 @@
|
|||||||
#include "src/widget/tool/messageboxmanager.h"
|
#include "src/widget/tool/messageboxmanager.h"
|
||||||
#include "tool/removechatdialog.h"
|
#include "tool/removechatdialog.h"
|
||||||
#include "src/persistence/smileypack.h"
|
#include "src/persistence/smileypack.h"
|
||||||
|
#include "src/ipc.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -111,8 +97,20 @@ bool tryRemoveFile(const QString& filepath)
|
|||||||
tmp.remove();
|
tmp.remove();
|
||||||
return writable;
|
return writable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString activateHandlerKey("activate");
|
||||||
|
|
||||||
} // namespace
|
} // 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)
|
void Widget::acceptFileTransfer(const ToxFile& file, const QString& path)
|
||||||
{
|
{
|
||||||
QString filepath;
|
QString filepath;
|
||||||
@ -142,7 +140,7 @@ void Widget::acceptFileTransfer(const ToxFile& file, const QString& path)
|
|||||||
Widget* Widget::instance{nullptr};
|
Widget* Widget::instance{nullptr};
|
||||||
|
|
||||||
Widget::Widget(Profile &profile_, IAudioControl& audio_, CameraSource& cameraSource_,
|
Widget::Widget(Profile &profile_, IAudioControl& audio_, CameraSource& cameraSource_,
|
||||||
Settings& settings_, Style& style_, QWidget* parent)
|
Settings& settings_, Style& style_, IPC& ipc_, QWidget* parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
, profile{profile_}
|
, profile{profile_}
|
||||||
, trayMenu{nullptr}
|
, trayMenu{nullptr}
|
||||||
@ -163,6 +161,7 @@ Widget::Widget(Profile &profile_, IAudioControl& audio_, CameraSource& cameraSou
|
|||||||
, friendList(new FriendList())
|
, friendList(new FriendList())
|
||||||
, groupList(new GroupList())
|
, groupList(new GroupList())
|
||||||
, contentDialogManager(new ContentDialogManager(*friendList))
|
, contentDialogManager(new ContentDialogManager(*friendList))
|
||||||
|
, ipc{ipc_}
|
||||||
{
|
{
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
QString locale = settings.getTranslation();
|
QString locale = settings.getTranslation();
|
||||||
@ -608,6 +607,8 @@ void Widget::updateIcons()
|
|||||||
|
|
||||||
Widget::~Widget()
|
Widget::~Widget()
|
||||||
{
|
{
|
||||||
|
ipc.unregisterEventHandler(activateHandlerKey);
|
||||||
|
|
||||||
QWidgetList windowList = QApplication::topLevelWidgets();
|
QWidgetList windowList = QApplication::topLevelWidgets();
|
||||||
|
|
||||||
for (QWidget* window : windowList) {
|
for (QWidget* window : windowList) {
|
||||||
@ -2755,3 +2756,8 @@ void Widget::formatWindowTitle(const QString& content)
|
|||||||
setWindowTitle(content + " - qTox");
|
setWindowTitle(content + " - qTox");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::registerActivate()
|
||||||
|
{
|
||||||
|
ipc.registerEventHandler(activateHandlerKey, &toxActivateEventHandler, this);
|
||||||
|
}
|
||||||
|
@ -90,7 +90,7 @@ class IMessageBoxManager;
|
|||||||
class ContentDialogManager;
|
class ContentDialogManager;
|
||||||
class FriendList;
|
class FriendList;
|
||||||
class GroupList;
|
class GroupList;
|
||||||
class RemoveChatDialog;
|
class IPC;
|
||||||
|
|
||||||
class Widget final : public QMainWindow
|
class Widget final : public QMainWindow
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Widget(Profile& profile_, IAudioControl& audio_, CameraSource& cameraSource,
|
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;
|
~Widget() override;
|
||||||
void init();
|
void init();
|
||||||
void setCentralWidget(QWidget* widget, const QString& widgetName);
|
void setCentralWidget(QWidget* widget, const QString& widgetName);
|
||||||
@ -154,6 +154,8 @@ public:
|
|||||||
bool groupsVisible() const;
|
bool groupsVisible() const;
|
||||||
|
|
||||||
void resetIcon();
|
void resetIcon();
|
||||||
|
void registerActivate();
|
||||||
|
static bool toxActivateEventHandler(const QByteArray& data, void* userData);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reloadTheme();
|
void reloadTheme();
|
||||||
@ -397,6 +399,5 @@ private:
|
|||||||
std::unique_ptr<FriendList> friendList;
|
std::unique_ptr<FriendList> friendList;
|
||||||
std::unique_ptr<GroupList> groupList;
|
std::unique_ptr<GroupList> groupList;
|
||||||
std::unique_ptr<ContentDialogManager> contentDialogManager;
|
std::unique_ptr<ContentDialogManager> contentDialogManager;
|
||||||
|
IPC& ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool toxActivateEventHandler(const QByteArray& data, void* userData);
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user