Refactor the remote hotkeys to avoid round trips

The previous implementation was hard to follow and maintain. Instead of
doing intentional rounds trips, we use now a two way approach. GUI is
automatically forwarding remote actions by calling "callHotkeyActionRemotely"
through DBus. Core on the other hand, emits a signal "remoteHotkeyAction"
that is processed in a different function in GUI.
On both sides, actions from the same local machine are filtered.

ref T402
This commit is contained in:
Roland Winklmeier
2018-10-16 17:17:43 +02:00
committed by Klaus Basan
parent 9bb75a6f2e
commit 1addcf631a
9 changed files with 38 additions and 24 deletions

View File

@@ -112,23 +112,13 @@ namespace BlackCore
s = connect(sApp->getInputManager(), &CInputManager::remoteActionFromLocal, this, [ = ](const QString & action, bool argument) s = connect(sApp->getInputManager(), &CInputManager::remoteActionFromLocal, this, [ = ](const QString & action, bool argument)
{ {
if (!myself) { return; } if (!myself) { return; }
this->callHotkeyAction(action, argument, {}); this->callHotkeyActionRemotely(action, argument, {});
}, },
Qt::QueuedConnection); Qt::QueuedConnection);
Q_ASSERT_X(s, Q_FUNC_INFO, "Connect remote action failed"); Q_ASSERT_X(s, Q_FUNC_INFO, "Connect remote action failed");
Q_UNUSED(s); Q_UNUSED(s);
s = connect(this, &IContextApplication::remoteHotkeyAction, [ = ](const QString & action, bool argument, const CIdentifier & origin)
{
if (!myself) { return; }
if (origin.isFromLocalMachine()) { return; }
sApp->getInputManager()->callFunctionsBy(action, argument);
CLogMessage(this, CLogCategory::contextSlot()).debug() << "Calling function" << action << "from origin" << origin.getMachineName();
});
Q_ASSERT_X(s, Q_FUNC_INFO, "Connect remote hotkey action failed");
Q_UNUSED(s);
// Enable event forwarding from GUI process to core // Enable event forwarding from GUI process to core
sApp->getInputManager()->setForwarding(true); sApp->getInputManager()->setForwarding(true);
} }
@@ -158,7 +148,7 @@ namespace BlackCore
qFatal("Not implemented"); // avoid losing a change during context interface construction qFatal("Not implemented"); // avoid losing a change during context interface construction
} }
void IContextApplication::callHotkeyAction(const QString &action, bool argument, const CIdentifier &origin) void IContextApplication::callHotkeyActionRemotely(const QString &action, bool argument, const CIdentifier &origin)
{ {
Q_UNUSED(action); Q_UNUSED(action);
Q_UNUSED(argument); Q_UNUSED(argument);

View File

@@ -182,7 +182,7 @@ namespace BlackCore
//! Call a hotkey action on a remote process //! Call a hotkey action on a remote process
//! \note Not pure because it can be called from the base class constructor. //! \note Not pure because it can be called from the base class constructor.
//! \note This is the function which relays action calls via DBus //! \note This is the function which relays action calls via DBus
virtual void callHotkeyAction(const QString &action, bool argument, const BlackMisc::CIdentifier &origin); virtual void callHotkeyActionRemotely(const QString &action, bool argument, const BlackMisc::CIdentifier &origin);
//! Register application, can also be used for ping //! Register application, can also be used for ping
virtual BlackMisc::CIdentifier registerApplication(const BlackMisc::CIdentifier &application) = 0; virtual BlackMisc::CIdentifier registerApplication(const BlackMisc::CIdentifier &application) = 0;

View File

@@ -135,7 +135,7 @@ namespace BlackCore
} }
//! \copydoc IContextApplication::callHotkeyAction //! \copydoc IContextApplication::callHotkeyAction
virtual void callHotkeyAction(const QString &action, bool argument, const BlackMisc::CIdentifier &origin) override virtual void callHotkeyActionRemotely(const QString &action, bool argument, const BlackMisc::CIdentifier &origin) override
{ {
Q_UNUSED(action); Q_UNUSED(action);
Q_UNUSED(argument); Q_UNUSED(argument);

View File

@@ -131,10 +131,22 @@ namespace BlackCore
emit this->hotkeyActionsRegistered(actions, origin); emit this->hotkeyActionsRegistered(actions, origin);
} }
void CContextApplication::callHotkeyAction(const QString &action, bool argument, const CIdentifier &origin) void CContextApplication::callHotkeyActionRemotely(const QString &action, bool argument, const CIdentifier &origin)
{ {
// Intentionally don't check for round trip here if (origin.hasApplicationProcessId())
emit this->remoteHotkeyAction(action, argument, origin); {
// If it originated from this process, then we are going to emit a signal
emit this->remoteHotkeyAction(action, argument, origin);
}
else
{
// action came from a different process but on the same machine. Ignore
if (origin.isFromLocalMachine()) { return; }
// Different process and different machine. Process it.
// However, it should not emit a remote action itself.
sApp->getInputManager()->callFunctionsBy(action, argument, false);
}
} }
bool CContextApplication::writeToFile(const QString &fileName, const QString &content) bool CContextApplication::writeToFile(const QString &fileName, const QString &content)

View File

@@ -60,7 +60,7 @@ namespace BlackCore
virtual BlackMisc::CStatusMessage saveSettingsByKey(const QStringList &keys) override; virtual BlackMisc::CStatusMessage saveSettingsByKey(const QStringList &keys) override;
virtual BlackMisc::CStatusMessage loadSettings() override; virtual BlackMisc::CStatusMessage loadSettings() override;
virtual void registerHotkeyActions(const QStringList &actions, const BlackMisc::CIdentifier &origin) override; virtual void registerHotkeyActions(const QStringList &actions, const BlackMisc::CIdentifier &origin) override;
virtual void callHotkeyAction(const QString &action, bool argument, const BlackMisc::CIdentifier &origin) override; virtual void callHotkeyActionRemotely(const QString &action, bool argument, const BlackMisc::CIdentifier &origin) override;
virtual bool writeToFile(const QString &fileName, const QString &content) override; virtual bool writeToFile(const QString &fileName, const QString &content) override;
virtual BlackMisc::CIdentifier registerApplication(const BlackMisc::CIdentifier &application) override; virtual BlackMisc::CIdentifier registerApplication(const BlackMisc::CIdentifier &application) override;
virtual void unregisterApplication(const BlackMisc::CIdentifier &application) override; virtual void unregisterApplication(const BlackMisc::CIdentifier &application) override;

View File

@@ -7,6 +7,7 @@
* contained in the LICENSE file. * contained in the LICENSE file.
*/ */
#include "blackcore/application.h"
#include "blackcore/context/contextapplicationproxy.h" #include "blackcore/context/contextapplicationproxy.h"
#include "blackmisc/dbus.h" #include "blackmisc/dbus.h"
#include "blackmisc/dbusserver.h" #include "blackmisc/dbusserver.h"
@@ -38,6 +39,8 @@ namespace BlackCore
} }
}); });
connect(this, &CContextApplicationProxy::remoteHotkeyAction, this, &CContextApplicationProxy::processRemoteHotkeyActionCall);
m_pingTimer.setObjectName(serviceName + "::m_pingTimer"); m_pingTimer.setObjectName(serviceName + "::m_pingTimer");
connect(&m_pingTimer, &QTimer::timeout, this, &CContextApplicationProxy::reRegisterApplications); connect(&m_pingTimer, &QTimer::timeout, this, &CContextApplicationProxy::reRegisterApplications);
m_pingTimer.start(PingIdentifiersMs); m_pingTimer.start(PingIdentifiersMs);
@@ -158,9 +161,9 @@ namespace BlackCore
m_dBusInterface->callDBus(QLatin1String("registerHotkeyActions"), actions, origin); m_dBusInterface->callDBus(QLatin1String("registerHotkeyActions"), actions, origin);
} }
void CContextApplicationProxy::callHotkeyAction(const QString &action, bool argument, const CIdentifier &origin) void CContextApplicationProxy::callHotkeyActionRemotely(const QString &action, bool argument, const CIdentifier &origin)
{ {
m_dBusInterface->callDBus(QLatin1String("callHotkeyAction"), action, argument, origin); m_dBusInterface->callDBus(QLatin1String("callHotkeyActionRemotely"), action, argument, origin);
} }
CIdentifier CContextApplicationProxy::registerApplication(const CIdentifier &application) CIdentifier CContextApplicationProxy::registerApplication(const CIdentifier &application)
@@ -243,5 +246,12 @@ namespace BlackCore
CDBusServer::disconnectFromDBus(connection, dBusAddress); CDBusServer::disconnectFromDBus(connection, dBusAddress);
return ok; return ok;
} }
void CContextApplicationProxy::processRemoteHotkeyActionCall(const QString &action, bool argument, const BlackMisc::CIdentifier &origin)
{
if (origin.isFromLocalMachine()) { return; }
sApp->getInputManager()->callFunctionsBy(action, argument);
CLogMessage(this, CLogCategory::contextSlot()).debug() << "Calling function" << action << "from origin" << origin.getMachineName();
}
} // namespace } // namespace
} // namespace } // namespace

View File

@@ -65,7 +65,7 @@ namespace BlackCore
virtual BlackMisc::CStatusMessage saveSettingsByKey(const QStringList &keys) override; virtual BlackMisc::CStatusMessage saveSettingsByKey(const QStringList &keys) override;
virtual BlackMisc::CStatusMessage loadSettings() override; virtual BlackMisc::CStatusMessage loadSettings() override;
virtual void registerHotkeyActions(const QStringList &actions, const BlackMisc::CIdentifier &origin) override; virtual void registerHotkeyActions(const QStringList &actions, const BlackMisc::CIdentifier &origin) override;
virtual void callHotkeyAction(const QString &action, bool argument, const BlackMisc::CIdentifier &origin) override; virtual void callHotkeyActionRemotely(const QString &action, bool argument, const BlackMisc::CIdentifier &origin) override;
virtual BlackMisc::CIdentifier registerApplication(const BlackMisc::CIdentifier &application) override; virtual BlackMisc::CIdentifier registerApplication(const BlackMisc::CIdentifier &application) override;
virtual void unregisterApplication(const BlackMisc::CIdentifier &application) override; virtual void unregisterApplication(const BlackMisc::CIdentifier &application) override;
virtual BlackMisc::CIdentifierList getRegisteredApplications() const override; virtual BlackMisc::CIdentifierList getRegisteredApplications() const override;
@@ -98,6 +98,8 @@ namespace BlackCore
//! Ping/heartbeat identifiers //! Ping/heartbeat identifiers
void reRegisterApplications(); void reRegisterApplications();
void processRemoteHotkeyActionCall(const QString &action, bool argument, const BlackMisc::CIdentifier &origin);
}; };
} // ns } // ns
} // ns } // ns

View File

@@ -95,10 +95,10 @@ namespace BlackCore
m_capturedCombination = {}; m_capturedCombination = {};
} }
void CInputManager::callFunctionsBy(const QString &action, bool isKeyDown) void CInputManager::callFunctionsBy(const QString &action, bool isKeyDown, bool shouldEmit)
{ {
if (action.isEmpty()) { return; } if (action.isEmpty()) { return; }
if (m_actionRelayingEnabled) emit remoteActionFromLocal(action, isKeyDown); if (m_actionRelayingEnabled && shouldEmit) { emit remoteActionFromLocal(action, isKeyDown); }
for (const auto &boundAction : as_const(m_boundActions)) for (const auto &boundAction : as_const(m_boundActions))
{ {

View File

@@ -85,7 +85,7 @@ namespace BlackCore
void setForwarding(bool enabled) { m_actionRelayingEnabled = enabled; } void setForwarding(bool enabled) { m_actionRelayingEnabled = enabled; }
//! Call functions by hotkeyfunction //! Call functions by hotkeyfunction
void callFunctionsBy(const QString &action, bool isKeyDown); void callFunctionsBy(const QString &action, bool isKeyDown, bool shouldEmit = true);
//! Triggers a key event manually and calls the registered functions. //! Triggers a key event manually and calls the registered functions.
void triggerKey(const BlackMisc::Input::CHotkeyCombination &combination, bool isPressed); void triggerKey(const BlackMisc::Input::CHotkeyCombination &combination, bool isPressed);