feat: single instance check for StatusWindow

This commit is contained in:
Andrei Smirnov 2021-07-21 11:57:33 +03:00 committed by Michał
parent 1c3bbe1b8e
commit 8c095ec628
3 changed files with 47 additions and 1 deletions

View File

@ -10,6 +10,7 @@ nimcache
.idea
*.orig
doc
cmake-build-*
# libraries
*.a

View File

@ -4,6 +4,8 @@
#include <QQuickWindow>
#include <QScreen>
class QLocalServer;
class StatusWindow: public QQuickWindow
{
Q_OBJECT
@ -13,6 +15,7 @@ class StatusWindow: public QQuickWindow
public:
explicit StatusWindow(QWindow *parent = nullptr);
~StatusWindow();
Q_INVOKABLE void toggleFullScreen();
@ -27,14 +30,17 @@ public:
signals:
void isFullScreenChanged();
void secondInstanceDetected();
private:
void checkSingleInstance();
void removeTitleBar();
void showTitleBar();
void initCallbacks();
private:
bool m_isFullScreen;
QLocalServer *m_localServer;
};
#endif // STATUSWINDOW_H

View File

@ -1,9 +1,16 @@
#include "DOtherSide/DOtherSideStatusWindow.h"
#include <QLocalServer>
#include <QLocalSocket>
#include <QDir>
#include <QCryptographicHash>
StatusWindow::StatusWindow(QWindow *parent)
: QQuickWindow(parent),
m_isFullScreen(false)
m_isFullScreen(false),
m_localServer(new QLocalServer(this))
{
checkSingleInstance();
removeTitleBar();
connect(this, &QQuickWindow::windowStateChanged, [&](Qt::WindowState windowState) {
@ -19,6 +26,13 @@ StatusWindow::StatusWindow(QWindow *parent)
});
}
StatusWindow::~StatusWindow()
{
if (m_localServer->isListening()) {
m_localServer->close();
}
}
void StatusWindow::toggleFullScreen()
{
if (m_isFullScreen) {
@ -32,3 +46,28 @@ bool StatusWindow::isFullScreen() const
{
return m_isFullScreen;
}
void StatusWindow::checkSingleInstance()
{
const auto currentDir = QDir::currentPath();
auto socketName = QString(QCryptographicHash::hash(currentDir.toUtf8(), QCryptographicHash::Md5).toHex());
#ifndef Q_OS_WIN
socketName = QString("/tmp/%1").arg(socketName);
#endif
QLocalSocket localSocket;
localSocket.connectToServer(socketName);
// the first instance start will be delayed by this timeout (ms) to ensure there are no other instances.
// note: this is an ad-hoc timeout value selected based on prior experience.
const bool connected = localSocket.waitForConnected(100);
if (!connected) {
connect(m_localServer, &QLocalServer::newConnection, this, &StatusWindow::secondInstanceDetected);
if (!m_localServer->listen(socketName)) {
qWarning() << "QLocalServer::listen(" << socketName << ") failed";
}
} else {
qFatal("Terminating app as the second running instance...");
}
}