mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 20:48:52 +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/RoomList.cc
|
||||||
src/RoomMessages.cc
|
src/RoomMessages.cc
|
||||||
src/RoomState.cc
|
src/RoomState.cc
|
||||||
|
src/RunGuard.cc
|
||||||
src/SideBarActions.cc
|
src/SideBarActions.cc
|
||||||
src/Splitter.cc
|
src/Splitter.cc
|
||||||
src/TextInputWidget.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 <QDesktopWidget>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLayout>
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
|
#include <QPalette>
|
||||||
|
#include <QPoint>
|
||||||
|
#include <QPushButton>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
#include "MainWindow.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
|
void
|
||||||
setupProxy()
|
setupProxy()
|
||||||
|
@ -55,6 +74,50 @@ setupProxy()
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
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::setApplicationName("nheko");
|
||||||
QCoreApplication::setApplicationVersion("0.1.0");
|
QCoreApplication::setApplicationVersion("0.1.0");
|
||||||
QCoreApplication::setOrganizationName("nheko");
|
QCoreApplication::setOrganizationName("nheko");
|
||||||
|
@ -95,11 +158,7 @@ main(int argc, char *argv[])
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
|
|
||||||
// Move the MainWindow to the center
|
// Move the MainWindow to the center
|
||||||
QRect screenGeometry = QApplication::desktop()->screenGeometry();
|
w.move(screenCenter(w.width(), w.height()));
|
||||||
int x = (screenGeometry.width() - w.width()) / 2;
|
|
||||||
int y = (screenGeometry.height() - w.height()) / 2;
|
|
||||||
|
|
||||||
w.move(x, y);
|
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
QObject::connect(&app, &QApplication::aboutToQuit, &w, &MainWindow::saveCurrentWindowSize);
|
QObject::connect(&app, &QApplication::aboutToQuit, &w, &MainWindow::saveCurrentWindowSize);
|
||||||
|
|
Loading…
Reference in a new issue