mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-01-14 00:39:53 -05:00
parent
9f819061cd
commit
d1310b3337
@ -198,6 +198,7 @@ if(WITH_TESTS)
|
|||||||
endif(WITH_TESTS)
|
endif(WITH_TESTS)
|
||||||
|
|
||||||
find_package(Qt5Core 5.2 REQUIRED)
|
find_package(Qt5Core 5.2 REQUIRED)
|
||||||
|
find_package(Qt5Network 5.2 REQUIRED)
|
||||||
find_package(Qt5Concurrent 5.2 REQUIRED)
|
find_package(Qt5Concurrent 5.2 REQUIRED)
|
||||||
find_package(Qt5Widgets 5.2 REQUIRED)
|
find_package(Qt5Widgets 5.2 REQUIRED)
|
||||||
find_package(Qt5Test 5.2 REQUIRED)
|
find_package(Qt5Test 5.2 REQUIRED)
|
||||||
|
@ -195,6 +195,7 @@ target_link_libraries(keepassx_core
|
|||||||
${YUBIKEY_LIBRARIES}
|
${YUBIKEY_LIBRARIES}
|
||||||
zxcvbn
|
zxcvbn
|
||||||
Qt5::Core
|
Qt5::Core
|
||||||
|
Qt5::Network
|
||||||
Qt5::Concurrent
|
Qt5::Concurrent
|
||||||
Qt5::Widgets
|
Qt5::Widgets
|
||||||
${GCRYPT_LIBRARIES}
|
${GCRYPT_LIBRARIES}
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
#include <QAbstractNativeEventFilter>
|
#include <QAbstractNativeEventFilter>
|
||||||
#include <QFileOpenEvent>
|
#include <QFileOpenEvent>
|
||||||
#include <QSocketNotifier>
|
#include <QSocketNotifier>
|
||||||
|
#include <QLockFile>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QtNetwork/QLocalSocket>
|
||||||
|
|
||||||
#include "autotype/AutoType.h"
|
#include "autotype/AutoType.h"
|
||||||
|
|
||||||
@ -76,6 +79,8 @@ Application::Application(int& argc, char** argv)
|
|||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
, m_unixSignalNotifier(nullptr)
|
, m_unixSignalNotifier(nullptr)
|
||||||
#endif
|
#endif
|
||||||
|
, alreadyRunning(false)
|
||||||
|
, lock(nullptr)
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
|
#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
|
||||||
installNativeEventFilter(new XcbEventFilter());
|
installNativeEventFilter(new XcbEventFilter());
|
||||||
@ -85,6 +90,58 @@ Application::Application(int& argc, char** argv)
|
|||||||
#if defined(Q_OS_UNIX)
|
#if defined(Q_OS_UNIX)
|
||||||
registerUnixSignals();
|
registerUnixSignals();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString userName = qgetenv("USER");
|
||||||
|
if (userName.isEmpty()) {
|
||||||
|
userName = qgetenv("USERNAME");
|
||||||
|
}
|
||||||
|
QString identifier = "keepassx2";
|
||||||
|
if (!userName.isEmpty()) {
|
||||||
|
identifier.append("-");
|
||||||
|
identifier.append(userName);
|
||||||
|
}
|
||||||
|
QString socketName = identifier + ".socket";
|
||||||
|
QString lockName = identifier + ".lock";
|
||||||
|
|
||||||
|
// According to documentation we should use RuntimeLocation on *nixes, but even Qt doesn't respect
|
||||||
|
// this and creates sockets in TempLocation, so let's be consistent.
|
||||||
|
lock = new QLockFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + lockName);
|
||||||
|
lock->setStaleLockTime(0);
|
||||||
|
lock->tryLock();
|
||||||
|
switch (lock->error()) {
|
||||||
|
case QLockFile::NoError:
|
||||||
|
server.setSocketOptions(QLocalServer::UserAccessOption);
|
||||||
|
server.listen(socketName);
|
||||||
|
connect(&server, SIGNAL(newConnection()), this, SIGNAL(anotherInstanceStarted()));
|
||||||
|
break;
|
||||||
|
case QLockFile::LockFailedError: {
|
||||||
|
alreadyRunning = true;
|
||||||
|
// notify the other instance
|
||||||
|
// try several times, in case the other instance is still starting up
|
||||||
|
QLocalSocket client;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
client.connectToServer(socketName);
|
||||||
|
if (client.waitForConnected(150)) {
|
||||||
|
client.abort();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
qWarning() << QCoreApplication::translate("Main",
|
||||||
|
"The lock file could not be created. Single-instance mode disabled.")
|
||||||
|
.toUtf8().constData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Application::~Application()
|
||||||
|
{
|
||||||
|
server.close();
|
||||||
|
if (lock) {
|
||||||
|
lock->unlock();
|
||||||
|
delete lock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* Application::mainWindow() const
|
QWidget* Application::mainWindow() const
|
||||||
@ -171,3 +228,9 @@ void Application::quitBySignal()
|
|||||||
static_cast<MainWindow*>(m_mainWindow)->appExit();
|
static_cast<MainWindow*>(m_mainWindow)->appExit();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool Application::isAlreadyRunning() const
|
||||||
|
{
|
||||||
|
return alreadyRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#define KEEPASSX_APPLICATION_H
|
#define KEEPASSX_APPLICATION_H
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QtNetwork/QLocalServer>
|
||||||
|
class QLockFile;
|
||||||
|
|
||||||
class QSocketNotifier;
|
class QSocketNotifier;
|
||||||
|
|
||||||
@ -30,12 +32,15 @@ class Application : public QApplication
|
|||||||
public:
|
public:
|
||||||
Application(int& argc, char** argv);
|
Application(int& argc, char** argv);
|
||||||
QWidget* mainWindow() const;
|
QWidget* mainWindow() const;
|
||||||
|
~Application();
|
||||||
void setMainWindow(QWidget* mainWindow);
|
void setMainWindow(QWidget* mainWindow);
|
||||||
|
|
||||||
bool event(QEvent* event) override;
|
bool event(QEvent* event) override;
|
||||||
|
bool isAlreadyRunning() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void openFile(const QString& filename);
|
void openFile(const QString& filename);
|
||||||
|
void anotherInstanceStarted();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
#if defined(Q_OS_UNIX)
|
#if defined(Q_OS_UNIX)
|
||||||
@ -54,6 +59,9 @@ private:
|
|||||||
static void handleUnixSignal(int sig);
|
static void handleUnixSignal(int sig);
|
||||||
static int unixSignalSocket[2];
|
static int unixSignalSocket[2];
|
||||||
#endif
|
#endif
|
||||||
|
bool alreadyRunning;
|
||||||
|
QLockFile* lock;
|
||||||
|
QLocalServer server;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_APPLICATION_H
|
#endif // KEEPASSX_APPLICATION_H
|
||||||
|
15
src/main.cpp
15
src/main.cpp
@ -56,6 +56,11 @@ int main(int argc, char** argv)
|
|||||||
// don't set organizationName as that changes the return value of
|
// don't set organizationName as that changes the return value of
|
||||||
// QStandardPaths::writableLocation(QDesktopServices::DataLocation)
|
// QStandardPaths::writableLocation(QDesktopServices::DataLocation)
|
||||||
|
|
||||||
|
if (app.isAlreadyRunning()) {
|
||||||
|
qWarning() << QCoreApplication::translate("Main", "Another instance of KeePassX 2 is already running.").toUtf8().constData();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QApplication::setQuitOnLastWindowClosed(false);
|
QApplication::setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
if (!Crypto::init()) {
|
if (!Crypto::init()) {
|
||||||
@ -102,7 +107,15 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
MainWindow mainWindow;
|
MainWindow mainWindow;
|
||||||
app.setMainWindow(&mainWindow);
|
app.setMainWindow(&mainWindow);
|
||||||
|
|
||||||
|
QObject::connect(&app, &Application::anotherInstanceStarted,
|
||||||
|
[&]() {
|
||||||
|
mainWindow.ensurePolished();
|
||||||
|
mainWindow.setWindowState(mainWindow.windowState() & ~Qt::WindowMinimized);
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.raise();
|
||||||
|
mainWindow.activateWindow();
|
||||||
|
});
|
||||||
QObject::connect(&app, SIGNAL(openFile(QString)), &mainWindow, SLOT(openDatabase(QString)));
|
QObject::connect(&app, SIGNAL(openFile(QString)), &mainWindow, SLOT(openDatabase(QString)));
|
||||||
|
|
||||||
// start minimized if configured
|
// start minimized if configured
|
||||||
|
Loading…
Reference in New Issue
Block a user