mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2026-03-11 08:54:48 +00:00
Factor out common socket messaging code to simplify adding new single instance commands
This commit is contained in:
parent
db0f091536
commit
dcdd599622
2 changed files with 33 additions and 43 deletions
|
|
@ -47,6 +47,12 @@ namespace
|
|||
int g_OriginalFontSize = 0;
|
||||
} // namespace
|
||||
|
||||
enum Application::SocketCmd : quint32
|
||||
{
|
||||
OpenFiles = 1,
|
||||
LockAll,
|
||||
};
|
||||
|
||||
Application::Application(int& argc, char** argv)
|
||||
: QApplication(argc, argv)
|
||||
#ifdef Q_OS_UNIX
|
||||
|
|
@ -54,11 +60,7 @@ Application::Application(int& argc, char** argv)
|
|||
#endif
|
||||
, m_alreadyRunning(false)
|
||||
, m_lockFile(nullptr)
|
||||
#if defined(Q_OS_WIN) || (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
|
||||
{
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
#if defined(Q_OS_UNIX)
|
||||
registerUnixSignals();
|
||||
#endif
|
||||
|
|
@ -324,13 +326,13 @@ void Application::socketReadyRead()
|
|||
return;
|
||||
}
|
||||
|
||||
QStringList fileNames;
|
||||
quint32 id;
|
||||
in >> id;
|
||||
SocketCmd id;
|
||||
// manual reinterpret_cast not needed for Qt 5.14+
|
||||
in >> reinterpret_cast<typename std::underlying_type<SocketCmd>::type&>(id);
|
||||
|
||||
// TODO: move constants to enum
|
||||
switch (id) {
|
||||
case 1:
|
||||
case SocketCmd::OpenFiles: {
|
||||
QStringList fileNames;
|
||||
in >> fileNames;
|
||||
for (const QString& fileName : asConst(fileNames)) {
|
||||
const QFileInfo fInfo(fileName);
|
||||
|
|
@ -338,9 +340,9 @@ void Application::socketReadyRead()
|
|||
emit openFile(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
}
|
||||
case SocketCmd::LockAll:
|
||||
getMainWindow()->lockAllDatabases();
|
||||
break;
|
||||
}
|
||||
|
|
@ -357,13 +359,7 @@ bool Application::isAlreadyRunning() const
|
|||
return config()->get(Config::SingleInstance).toBool() && m_alreadyRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send to-open file names to the running UI instance
|
||||
*
|
||||
* @param fileNames - list of file names to open
|
||||
* @return true if all operations succeeded (connection made, data sent, connection closed)
|
||||
*/
|
||||
bool Application::sendFileNamesToRunningInstance(const QStringList& fileNames)
|
||||
bool Application::sendSocketCommand(SocketCmd id, const std::function<void(QDataStream&)>& caller)
|
||||
{
|
||||
QLocalSocket client;
|
||||
client.connectToServer(m_socketName);
|
||||
|
|
@ -376,8 +372,8 @@ bool Application::sendFileNamesToRunningInstance(const QStringList& fileNames)
|
|||
QDataStream out(&data, QIODevice::WriteOnly);
|
||||
out.setVersion(QDataStream::Qt_5_0);
|
||||
out << quint32(0); // reserve space for block size
|
||||
out << quint32(1); // ID for file name send. TODO: move to enum
|
||||
out << fileNames; // send file names to be opened
|
||||
out << id; // ID of command being sent.
|
||||
caller(out); // Pass to caller to add any additional data
|
||||
out.device()->seek(0);
|
||||
out << quint32(data.size() - sizeof(quint32)); // replace the previous constant 0 with block size
|
||||
|
||||
|
|
@ -388,6 +384,17 @@ bool Application::sendFileNamesToRunningInstance(const QStringList& fileNames)
|
|||
return writeOk && disconnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send to-open file names to the running UI instance
|
||||
*
|
||||
* @param fileNames - list of file names to open
|
||||
* @return true if all operations succeeded (connection made, data sent, connection closed)
|
||||
*/
|
||||
bool Application::sendFileNamesToRunningInstance(const QStringList& fileNames)
|
||||
{
|
||||
return this->sendSocketCommand(SocketCmd::OpenFiles, [fileNames](QDataStream& out) { out << fileNames; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks all open databases in the running instance
|
||||
*
|
||||
|
|
@ -395,29 +402,7 @@ bool Application::sendFileNamesToRunningInstance(const QStringList& fileNames)
|
|||
*/
|
||||
bool Application::sendLockToInstance()
|
||||
{
|
||||
// Make a connection to avoid SIGSEGV
|
||||
QLocalSocket client;
|
||||
client.connectToServer(m_socketName);
|
||||
const bool connected = client.waitForConnected(WaitTimeoutMSec);
|
||||
if (!connected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send lock signal
|
||||
QByteArray data;
|
||||
QDataStream out(&data, QIODevice::WriteOnly);
|
||||
out.setVersion(QDataStream::Qt_5_0);
|
||||
out << quint32(0); // reserve space for block size
|
||||
out << quint32(2); // ID for database lock. TODO: move to enum
|
||||
out.device()->seek(0);
|
||||
out << quint32(data.size() - sizeof(quint32)); // replace the previous constant 0 with block size
|
||||
|
||||
// Finish gracefully
|
||||
const bool writeOk = client.write(data) != -1 && client.waitForBytesWritten(WaitTimeoutMSec);
|
||||
client.disconnectFromServer();
|
||||
const bool disconnected =
|
||||
client.state() == QLocalSocket::UnconnectedState || client.waitForConnected(WaitTimeoutMSec);
|
||||
return writeOk && disconnected;
|
||||
return this->sendSocketCommand(SocketCmd::LockAll, [](QDataStream&) { /* No Data */ });
|
||||
}
|
||||
|
||||
bool Application::isDarkTheme() const
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <QApplication>
|
||||
#include <QString>
|
||||
#include <QtNetwork/qlocalserver.h>
|
||||
#include <functional>
|
||||
|
||||
#if defined(Q_OS_WIN) || (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
|
||||
|
||||
|
|
@ -78,6 +79,10 @@ private:
|
|||
static void handleUnixSignal(int sig);
|
||||
static int unixSignalSocket[2];
|
||||
#endif
|
||||
|
||||
enum SocketCmd : quint32;
|
||||
bool sendSocketCommand(SocketCmd id, const std::function<void(QDataStream&)>&);
|
||||
|
||||
bool m_alreadyRunning;
|
||||
bool m_darkTheme = false;
|
||||
QLockFile* m_lockFile;
|
||||
|
|
|
|||
Loading…
Reference in a new issue