45 lines
2.4 KiB
C++
45 lines
2.4 KiB
C++
/* Один GUI на каталог профиля: QLockFile защищает данные, локальный канал передаёт
|
|
* запрос показа владельцу. start вызывается один раз до чтения конфига/запуска ядра.
|
|
* Объект живёт до уничтожения окон; все вызовы — GUI-поток. */
|
|
#pragma once
|
|
|
|
#include <QObject>
|
|
#include <QString>
|
|
#include <QLockFile>
|
|
#include <QLocalServer>
|
|
#include <QPointer>
|
|
|
|
class QWidget;
|
|
|
|
/* Показать окно, сохранив maximized/fullscreen, и активировать его модальный диалог, если он есть. */
|
|
void showAndActivateWindow(QWidget* window);
|
|
|
|
class SingleInstance : public QObject {
|
|
public:
|
|
enum Result { Error = -1, Primary, Activated };
|
|
|
|
/* profileDirectory — существующий каталог конфига; parent владеет объектом по правилам QObject. */
|
|
explicit SingleInstance(const QString& profileDirectory, QObject* parent = nullptr);
|
|
~SingleInstance() override;
|
|
|
|
/* Получить блокировку и открыть канал либо дождаться ACK владельца (до 5 секунд).
|
|
* Primary: продолжить запуск; Activated: завершить второй процесс с 0; Error: errorString(). */
|
|
Result start();
|
|
/* Текущее окно: мастер настройки или MainWindow. nullptr откладывает показ до следующего setWindow. */
|
|
void setWindow(QWidget* window);
|
|
QString errorString() const { return m_error; }
|
|
QString serverName() const { return m_name; }
|
|
|
|
private:
|
|
Result fail(const QString& error);
|
|
Result activatePrimary();
|
|
void acceptConnections();
|
|
|
|
QLockFile m_lock; // Защита профиля на весь срок жизни первого экземпляра.
|
|
QLocalServer m_server; // Только текущий пользователь; имя связано с каноническим путём профиля.
|
|
QString m_name, m_error;
|
|
QPointer<QWidget> m_window; // Заимствованное окно; обнуляется при уничтожении мастера/GUI.
|
|
bool m_started = false;
|
|
bool m_pending = false; // Запрос принят до создания окна; повторные запросы объединяются.
|
|
};
|