mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 03:00:46 +03:00
parent
7de5af83db
commit
65672d3dfb
4 changed files with 180 additions and 5 deletions
|
@ -199,6 +199,7 @@ set(SRC_FILES
|
|||
src/RoomList.cc
|
||||
src/RoomMessages.cc
|
||||
src/RoomState.cc
|
||||
src/RunGuard.cc
|
||||
src/SideBarActions.cc
|
||||
src/Splitter.cc
|
||||
src/TextInputWidget.cc
|
||||
|
|
31
include/RunGuard.h
Normal file
31
include/RunGuard.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
//
|
||||
// Taken from
|
||||
// https://stackoverflow.com/questions/5006547/qt-best-practice-for-a-single-instance-app-protection
|
||||
//
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedMemory>
|
||||
#include <QSystemSemaphore>
|
||||
|
||||
class RunGuard
|
||||
{
|
||||
public:
|
||||
RunGuard(const QString &key);
|
||||
~RunGuard();
|
||||
|
||||
bool isAnotherRunning();
|
||||
bool tryToRun();
|
||||
void release();
|
||||
|
||||
private:
|
||||
const QString key;
|
||||
const QString memLockKey;
|
||||
const QString sharedmemKey;
|
||||
|
||||
QSharedMemory sharedMem;
|
||||
QSystemSemaphore memLock;
|
||||
|
||||
Q_DISABLE_COPY(RunGuard)
|
||||
};
|
84
src/RunGuard.cc
Normal file
84
src/RunGuard.cc
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "RunGuard.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
|
||||
namespace {
|
||||
|
||||
QString
|
||||
generateKeyHash(const QString &key, const QString &salt)
|
||||
{
|
||||
QByteArray data;
|
||||
|
||||
data.append(key.toUtf8());
|
||||
data.append(salt.toUtf8());
|
||||
data = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex();
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
RunGuard::RunGuard(const QString &key)
|
||||
: key(key)
|
||||
, memLockKey(generateKeyHash(key, "_memLockKey"))
|
||||
, sharedmemKey(generateKeyHash(key, "_sharedmemKey"))
|
||||
, sharedMem(sharedmemKey)
|
||||
, memLock(memLockKey, 1)
|
||||
{
|
||||
memLock.acquire();
|
||||
{
|
||||
// Fix for *nix: http://habrahabr.ru/post/173281/
|
||||
QSharedMemory fix(sharedmemKey);
|
||||
fix.attach();
|
||||
}
|
||||
|
||||
memLock.release();
|
||||
}
|
||||
|
||||
RunGuard::~RunGuard() { release(); }
|
||||
|
||||
bool
|
||||
RunGuard::isAnotherRunning()
|
||||
{
|
||||
if (sharedMem.isAttached())
|
||||
return false;
|
||||
|
||||
memLock.acquire();
|
||||
const bool isRunning = sharedMem.attach();
|
||||
|
||||
if (isRunning)
|
||||
sharedMem.detach();
|
||||
|
||||
memLock.release();
|
||||
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
bool
|
||||
RunGuard::tryToRun()
|
||||
{
|
||||
// Extra check
|
||||
if (isAnotherRunning())
|
||||
return false;
|
||||
|
||||
memLock.acquire();
|
||||
const bool result = sharedMem.create(sizeof(quint64));
|
||||
memLock.release();
|
||||
|
||||
if (!result) {
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RunGuard::release()
|
||||
{
|
||||
memLock.acquire();
|
||||
|
||||
if (sharedMem.isAttached())
|
||||
sharedMem.detach();
|
||||
|
||||
memLock.release();
|
||||
}
|
69
src/main.cc
69
src/main.cc
|
@ -19,12 +19,31 @@
|
|||
#include <QDesktopWidget>
|
||||
#include <QFile>
|
||||
#include <QFontDatabase>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QLibraryInfo>
|
||||
#include <QNetworkProxy>
|
||||
#include <QPalette>
|
||||
#include <QPoint>
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
#include <QTranslator>
|
||||
|
||||
#include "Config.h"
|
||||
#include "MainWindow.h"
|
||||
#include "RaisedButton.h"
|
||||
#include "RunGuard.h"
|
||||
|
||||
QPoint
|
||||
screenCenter(int width, int height)
|
||||
{
|
||||
QRect screenGeometry = QApplication::desktop()->screenGeometry();
|
||||
|
||||
int x = (screenGeometry.width() - width) / 2;
|
||||
int y = (screenGeometry.height() - height) / 2;
|
||||
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
void
|
||||
setupProxy()
|
||||
|
@ -55,6 +74,50 @@ setupProxy()
|
|||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
RunGuard guard("run_guard");
|
||||
|
||||
if (!guard.tryToRun()) {
|
||||
QApplication a(argc, argv);
|
||||
|
||||
QFont font;
|
||||
font.setPointSize(15);
|
||||
font.setWeight(60);
|
||||
|
||||
QWidget widget;
|
||||
QVBoxLayout layout(&widget);
|
||||
layout.setContentsMargins(20, 10, 20, 20);
|
||||
layout.setSpacing(0);
|
||||
|
||||
QHBoxLayout btnLayout;
|
||||
|
||||
QLabel msg("Another instance of nheko is currently running.");
|
||||
msg.setWordWrap(true);
|
||||
msg.setFont(font);
|
||||
|
||||
QPalette pal;
|
||||
|
||||
RaisedButton submitBtn("OK");
|
||||
submitBtn.setBackgroundColor(pal.color(QPalette::Button));
|
||||
submitBtn.setForegroundColor(pal.color(QPalette::ButtonText));
|
||||
submitBtn.setMinimumSize(120, 35);
|
||||
submitBtn.setFontSize(conf::btn::fontSize);
|
||||
submitBtn.setCornerRadius(conf::btn::cornerRadius);
|
||||
|
||||
btnLayout.addStretch(1);
|
||||
btnLayout.addWidget(&submitBtn);
|
||||
|
||||
layout.addWidget(&msg);
|
||||
layout.addLayout(&btnLayout);
|
||||
|
||||
widget.setFixedSize(480, 180);
|
||||
widget.move(screenCenter(widget.width(), widget.height()));
|
||||
widget.show();
|
||||
|
||||
QObject::connect(&submitBtn, &QPushButton::clicked, &widget, &QWidget::close);
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
QCoreApplication::setApplicationName("nheko");
|
||||
QCoreApplication::setApplicationVersion("0.1.0");
|
||||
QCoreApplication::setOrganizationName("nheko");
|
||||
|
@ -95,11 +158,7 @@ main(int argc, char *argv[])
|
|||
MainWindow w;
|
||||
|
||||
// Move the MainWindow to the center
|
||||
QRect screenGeometry = QApplication::desktop()->screenGeometry();
|
||||
int x = (screenGeometry.width() - w.width()) / 2;
|
||||
int y = (screenGeometry.height() - w.height()) / 2;
|
||||
|
||||
w.move(x, y);
|
||||
w.move(screenCenter(w.width(), w.height()));
|
||||
w.show();
|
||||
|
||||
QObject::connect(&app, &QApplication::aboutToQuit, &w, &MainWindow::saveCurrentWindowSize);
|
||||
|
|
Loading…
Reference in a new issue