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 .idea
*.orig *.orig
doc doc
cmake-build-*
# libraries # libraries
*.a *.a

View File

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

View File

@ -1,9 +1,16 @@
#include "DOtherSide/DOtherSideStatusWindow.h" #include "DOtherSide/DOtherSideStatusWindow.h"
#include <QLocalServer>
#include <QLocalSocket>
#include <QDir>
#include <QCryptographicHash>
StatusWindow::StatusWindow(QWindow *parent) StatusWindow::StatusWindow(QWindow *parent)
: QQuickWindow(parent), : QQuickWindow(parent),
m_isFullScreen(false) m_isFullScreen(false),
m_localServer(new QLocalServer(this))
{ {
checkSingleInstance();
removeTitleBar(); removeTitleBar();
connect(this, &QQuickWindow::windowStateChanged, [&](Qt::WindowState windowState) { 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() void StatusWindow::toggleFullScreen()
{ {
if (m_isFullScreen) { if (m_isFullScreen) {
@ -32,3 +46,28 @@ bool StatusWindow::isFullScreen() const
{ {
return m_isFullScreen; 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...");
}
}