1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-10-02 23:37:08 +02:00

Add pid as addition check method if content...

... or the main app is still running
This commit is contained in:
Elias Steurer 2024-01-05 16:51:11 +01:00
parent bd5516fb41
commit 73932d8999
15 changed files with 191 additions and 43 deletions

View File

@ -92,7 +92,8 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(
"--volume", QString::number(static_cast<double>(volume)),
"--fillmode", QVariant::fromValue(fillMode).toString(),
"--type", QVariant::fromValue(type).toString(),
"--check", QString::number(m_settings->checkWallpaperVisible())
"--check", QString::number(m_settings->checkWallpaperVisible()),
"--mainapppid", QString::number(m_processManager.getCurrentPID())
};
// Fixes issue 84 media key overlay in Qt apps
@ -262,6 +263,14 @@ void ScreenPlayWallpaper::setSDKConnection(std::unique_ptr<SDKConnection> connec
QObject::connect(m_connection.get(), &SDKConnection::pingAliveReceived, this, [this]() {
m_pingAliveTimer.stop();
m_pingAliveTimer.start(GlobalVariables::contentPingAliveIntervalMS);
std::optional<bool> running = m_processManager.isRunning(m_processID);
if (running.has_value()) {
qInfo() << "running:" << running.value();
} else {
qInfo() << "INVALID PID:" << m_processID;
}
});
}

View File

@ -56,8 +56,7 @@ ScreenPlayWidget::ScreenPlayWidget(
QString::number(m_position.x()),
"--posY",
QString::number(m_position.y()),
"--debug",
"--false",
"--mainapppid", QString::number(m_processManager.getCurrentPID())
};
}
@ -113,6 +112,13 @@ void ScreenPlayWidget::setSDKConnection(std::unique_ptr<SDKConnection> connectio
QObject::connect(m_connection.get(), &SDKConnection::pingAliveReceived, this, [this]() {
m_pingAliveTimer.stop();
m_pingAliveTimer.start(GlobalVariables::contentPingAliveIntervalMS);
std::optional<bool> running = m_processManager.isRunning(m_processID);
if (running.has_value()) {
qInfo() << "running:" << running.value();
} else {
qInfo() << "INVALID PID:" << m_processID;
}
});
QObject::connect(&m_pingAliveTimer, &QTimer::timeout, this, [this]() {

View File

@ -20,7 +20,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC inc/public/)
target_link_libraries(
${PROJECT_NAME}
PRIVATE Qt6::Core
PUBLIC Qt6::Core
Qt6::Quick
Qt6::Gui
Qt6::Network)
Qt6::Network
ScreenPlayUtil)

View File

@ -2,6 +2,7 @@
#pragma once
#include "ScreenPlayUtil/processmanager.h"
#include <QByteArray>
#include <QJsonArray>
#include <QJsonDocument>
@ -26,11 +27,15 @@ public:
Q_PROPERTY(QString type READ type WRITE setType NOTIFY typeChanged)
Q_PROPERTY(bool isConnected READ isConnected WRITE setIsConnected NOTIFY isConnectedChanged)
Q_PROPERTY(QString appID READ appID WRITE setAppID NOTIFY appIDChanged)
Q_PROPERTY(qint64 mainAppPID READ mainAppPID WRITE setMainAppPID NOTIFY mainAppPIDChanged FINAL)
QString type() const { return m_type; }
bool isConnected() const { return m_isConnected; }
QString appID() const { return m_appID; }
qint64 mainAppPID() const;
void setMainAppPID(qint64 mainAppPID);
public slots:
void sendMessage(const QJsonObject& obj);
void connected();
@ -91,6 +96,8 @@ signals:
const QString type,
const bool checkWallpaperVisible);
void mainAppPIDChanged(qint64 mainAppPID);
private:
QLocalSocket m_socket;
@ -99,4 +106,6 @@ private:
QString m_appID;
QTimer m_pingAliveTimer;
qint64 m_mainAppPID { 0 };
ScreenPlay::ProcessManager m_processManager;
};

View File

@ -33,7 +33,7 @@ void ScreenPlaySDK::start()
connect(&m_socket, &QLocalSocket::disconnected, this, &ScreenPlaySDK::disconnected);
connect(&m_socket, &QLocalSocket::readyRead, this, &ScreenPlaySDK::readyRead);
connect(&m_socket, &QLocalSocket::errorOccurred, this, [this]() {
emit disconnected();
disconnected();
});
m_socket.connectToServer("ScreenPlay");
@ -59,7 +59,7 @@ void ScreenPlaySDK::connected()
if (m_appID.isEmpty() || m_type.isEmpty()) {
qCritical() << "Unable to connect with empyt: " << m_appID << m_type;
emit disconnected();
disconnected();
return;
}
@ -169,6 +169,16 @@ void ScreenPlaySDK::pingAlive()
qInfo() << "Cannot ping to main application. Closing!";
emit sdkDisconnected();
}
// Check if a PID is set first
if (m_mainAppPID != 0) {
std::optional<bool> running = m_processManager.isRunning(m_mainAppPID);
if (running.has_value()) {
if (running.value())
return;
}
emit sdkDisconnected();
}
}
void ScreenPlaySDK::ScreenPlaySDK::redirectMessageOutputToMainWindow(QtMsgType type, const QMessageLogContext& context, const QString& msg)
@ -204,3 +214,16 @@ void ScreenPlaySDK::ScreenPlaySDK::redirectMessageOutputToMainWindow(QtMsgType t
break;
}
}
qint64 ScreenPlaySDK::mainAppPID() const
{
return m_mainAppPID;
}
void ScreenPlaySDK::setMainAppPID(qint64 mainAppPID)
{
if (m_mainAppPID == mainAppPID)
return;
m_mainAppPID = mainAppPID;
emit mainAppPIDChanged(m_mainAppPID);
}

View File

@ -21,8 +21,31 @@ public:
Invalid_AppID,
Invalid_Setup_ProjectParsingError,
Invalid_Setup_Error,
Invalid_PID,
Invalid_Start_Windows_HandleError,
};
Q_ENUM(Code)
};
class WidgetExit : public QObject {
Q_OBJECT
QML_ELEMENT
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
public:
WidgetExit(QObject* parent = nullptr);
enum class Code {
Ok = 0,
Invalid_ArgumentSize,
Invalid_Path,
Invalid_InstalledType,
Invalid_POSX,
Invalid_POSY,
Invalid_DEBUG,
Invalid_AppID,
Invalid_Setup_ProjectParsingError,
Invalid_Setup_Error,
Invalid_PID,
};
Q_ENUM(Code)
};
}

View File

@ -15,7 +15,8 @@ namespace ScreenPlay {
class ProcessManager {
public:
std::optional<bool> isRunning(const qint64 pid);
bool terminateProcess(const qint64 pid);
std::optional<bool> isRunning(const qint64 pid) const;
bool terminateProcess(const qint64 pid) const;
const qint64 getCurrentPID() const;
};
}

View File

@ -6,4 +6,9 @@ WallpaperExit::WallpaperExit(QObject* parent)
: QObject(parent)
{
}
WidgetExit::WidgetExit(QObject* parent)
{
}
}

View File

@ -1,7 +1,7 @@
#include "processmanager.h"
namespace ScreenPlay {
std::optional<bool> ProcessManager::isRunning(const qint64 pid)
std::optional<bool> ProcessManager::isRunning(const qint64 pid) const
{
if (pid <= 0)
return std::nullopt;
@ -25,7 +25,7 @@ std::optional<bool> ProcessManager::isRunning(const qint64 pid)
#endif
return std::nullopt;
}
bool ProcessManager::terminateProcess(const qint64 pid)
bool ProcessManager::terminateProcess(const qint64 pid) const
{
if (pid <= 0)
return false;
@ -53,4 +53,12 @@ bool ProcessManager::terminateProcess(const qint64 pid)
#endif
}
const qint64 ProcessManager::getCurrentPID() const
{
#if defined(Q_OS_WIN)
return static_cast<qint64>(GetCurrentProcessId());
#elif defined(Q_OS_LINUX) || defined(Q_OS_MAC)
return static_cast<qint64>(getpid());
#endif
}
}

View File

@ -28,7 +28,6 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayUtilPlugin)
int main(int argc, char* argv[])
{
using namespace ScreenPlay;
// Lets keep using it until: https://bugreports.qt.io/browse/QTBUG-109401
QtWebEngineQuick::initialize();
#if defined(Q_OS_WIN)
@ -83,7 +82,8 @@ int main(int argc, char* argv[])
"--volume", "1",
"--fillmode", "Contain",
"--type", "VideoWallpaper",
"--check", "0" });
"--check", "0",
"--mainapppid", "1" });
} else {
argumentList = app.arguments();
}
@ -100,6 +100,7 @@ int main(int argc, char* argv[])
QCommandLineOption fillmodeOption("fillmode", "Set fill mode.", "fillmode");
QCommandLineOption typeOption("type", "Set the type.", "type");
QCommandLineOption checkOption("check", "Set check value.", "check");
QCommandLineOption mainAppPidOption("mainapppid", "pid of the main ScreenPlay app. User to check if we are still alive.", "mainapppid");
// Add the options to the parser
parser.addOption(pathOption);
@ -109,6 +110,7 @@ int main(int argc, char* argv[])
parser.addOption(fillmodeOption);
parser.addOption(typeOption);
parser.addOption(checkOption);
parser.addOption(mainAppPidOption);
// Process the actual command line arguments given by the user
parser.process(argumentList);
@ -120,7 +122,8 @@ int main(int argc, char* argv[])
|| !parser.isSet(volumeOption)
|| !parser.isSet(fillmodeOption)
|| !parser.isSet(typeOption)
|| !parser.isSet(checkOption)) {
|| !parser.isSet(checkOption)
|| !parser.isSet(mainAppPidOption)) {
qCritical() << "Missing required arguments. Please provide all arguments."
<< argumentList
<< "pathOption" << parser.value(pathOption)
@ -129,7 +132,8 @@ int main(int argc, char* argv[])
<< "volumeOption" << parser.value(volumeOption)
<< "fillmodeOption" << parser.value(fillmodeOption)
<< "typeOption" << parser.value(typeOption)
<< "checkOption" << parser.value(checkOption);
<< "checkOption" << parser.value(checkOption)
<< "mainAppPidOption" << parser.value(mainAppPidOption);
return -1;
}
@ -140,6 +144,7 @@ int main(int argc, char* argv[])
QString fillmode = parser.value(fillmodeOption);
QString type = parser.value(typeOption);
QString check = parser.value(checkOption);
QString pid = parser.value(mainAppPidOption);
ScreenPlay::Util util;
@ -169,6 +174,13 @@ int main(int argc, char* argv[])
return static_cast<int>(WallpaperExit::Code::Invalid_Volume);
}
bool okPid = false;
const qint64 mainAppPidInt = pid.toInt(&okPid);
if (!okPid) {
qCritical("Could not parse mainAppPid");
return static_cast<int>(WallpaperExit::Code::Invalid_PID);
}
// Set the properties of the window object
window->setActiveScreensList(activeScreensList.value());
window->setProjectPath(path);
@ -178,6 +190,7 @@ int main(int argc, char* argv[])
window->setType(installedType.value());
window->setCheckWallpaperVisible(checkWallpaperVisible);
window->setDebugMode(false);
window->setMainAppPID(mainAppPidInt);
const auto setupStatus = window->setup();
if (setupStatus != WallpaperExit::Code::Ok) {

View File

@ -64,6 +64,7 @@ WallpaperExit::Code BaseWindow::setup()
// directly without an running ScreenPlay
if (!debugMode()) {
m_sdk = std::make_unique<ScreenPlaySDK>(appID(), QVariant::fromValue(type()).toString());
m_sdk->setMainAppPID(m_mainAppPID);
connect(m_sdk.get(), &ScreenPlaySDK::incommingMessage, this, &BaseWindow::messageReceived);
connect(m_sdk.get(), &ScreenPlaySDK::replaceWallpaper, this, &BaseWindow::replaceWallpaper);
sdk()->start();
@ -241,6 +242,19 @@ void BaseWindow::setVideoCodec(ScreenPlay::Video::VideoCodec newVideoCodec)
m_videoCodec = newVideoCodec;
emit videoCodecChanged(newVideoCodec);
}
qint64 BaseWindow::mainAppPID() const
{
return m_mainAppPID;
}
void BaseWindow::setMainAppPID(qint64 mainAppPID)
{
if (m_mainAppPID == mainAppPID)
return;
m_mainAppPID = mainAppPID;
emit mainAppPIDChanged(m_mainAppPID);
}
}
#include "moc_basewindow.cpp"

View File

@ -15,6 +15,7 @@
#include "ScreenPlaySDK/screenplaysdk.h"
#include "ScreenPlayUtil/exitcodes.h"
#include "ScreenPlayUtil/processmanager.h"
#include "ScreenPlayUtil/util.h"
#include <memory>
@ -29,36 +30,29 @@ public:
virtual WallpaperExit::Code setup() final;
virtual WallpaperExit::Code start() = 0;
Q_PROPERTY(qint64 mainAppPID READ mainAppPID WRITE setMainAppPID NOTIFY mainAppPIDChanged FINAL)
Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged)
Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged)
Q_PROPERTY(QVector<int> activeScreensList READ activeScreensList WRITE setActiveScreensList NOTIFY activeScreensListChanged)
Q_PROPERTY(QString appID READ appID WRITE setAppID NOTIFY appIDChanged)
Q_PROPERTY(QString fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
Q_PROPERTY(QString projectPath READ projectPath WRITE setProjectPath NOTIFY projectPathChanged)
Q_PROPERTY(QString projectSourceFile READ projectSourceFile WRITE setProjectSourceFile NOTIFY projectSourceFileChanged)
Q_PROPERTY(QUrl projectSourceFileAbsolute READ projectSourceFileAbsolute WRITE setProjectSourceFileAbsolute NOTIFY projectSourceFileAbsoluteChanged)
Q_PROPERTY(bool loops READ loops WRITE setLoops NOTIFY loopsChanged)
Q_PROPERTY(bool isPlaying READ isPlaying WRITE setIsPlaying NOTIFY isPlayingChanged)
Q_PROPERTY(bool muted READ muted WRITE setMuted NOTIFY mutedChanged)
Q_PROPERTY(bool canFade READ canFade WRITE setCanFade NOTIFY canFadeChanged)
Q_PROPERTY(bool debugMode READ debugMode WRITE setDebugMode NOTIFY debugModeChanged)
// Save performance by checking if the wallpaper is visible (video wallpaper only for now)
Q_PROPERTY(bool checkWallpaperVisible READ checkWallpaperVisible WRITE setCheckWallpaperVisible NOTIFY checkWallpaperVisibleChanged)
Q_PROPERTY(bool visualsPaused READ visualsPaused WRITE setVisualsPaused NOTIFY visualsPausedChanged)
Q_PROPERTY(float volume READ volume WRITE setVolume NOTIFY volumeChanged)
Q_PROPERTY(float playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged)
Q_PROPERTY(float currentTime READ currentTime WRITE setCurrentTime NOTIFY currentTimeChanged)
Q_PROPERTY(ScreenPlay::ContentTypes::InstalledType type READ type WRITE setType NOTIFY typeChanged)
Q_PROPERTY(ScreenPlay::Video::VideoCodec videoCodec READ videoCodec WRITE setVideoCodec NOTIFY videoCodecChanged)
Q_PROPERTY(QString OSVersion READ OSVersion WRITE setOSVersion NOTIFY OSVersionChanged)
Q_PROPERTY(ScreenPlaySDK* sdk READ sdk WRITE setSdk NOTIFY sdkChanged)
bool loops() const { return m_loops; }
@ -86,6 +80,9 @@ public:
ScreenPlay::Video::VideoCodec videoCodec() const;
void setVideoCodec(ScreenPlay::Video::VideoCodec newVideoCodec);
qint64 mainAppPID() const;
void setMainAppPID(qint64 mainAppPID);
signals:
void qmlStart();
void qmlExit();
@ -118,6 +115,8 @@ signals:
void projectSourceFileAbsoluteChanged(const QUrl& rojectSourceFileAbsolute);
void videoCodecChanged(ScreenPlay::Video::VideoCodec codec);
void mainAppPIDChanged(qint64 mainAppPID);
public slots:
void requestFadeIn();
virtual void destroyThis() { }
@ -348,7 +347,9 @@ protected:
int m_width { 0 };
int m_height { 0 };
qint64 m_mainAppPID { 0 };
ProcessManager m_processManager;
ScreenPlay::ContentTypes::InstalledType m_type = ScreenPlay::ContentTypes::InstalledType::Unknown;
QVector<int> m_activeScreensList;
QFileSystemWatcher m_fileSystemWatcher;

View File

@ -9,6 +9,7 @@
#include <QtWebEngineQuick>
#include "ScreenPlayUtil/contenttypes.h"
#include "ScreenPlayUtil/exitcodes.h"
#include "ScreenPlayUtil/logginghandler.h"
#include "src/widgetwindow.h"
@ -25,6 +26,7 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayUtilPlugin)
int main(int argc, char* argv[])
{
using namespace ScreenPlay;
// Lets keep using it until: https://bugreports.qt.io/browse/QTBUG-109401
QtWebEngineQuick::initialize();
@ -73,7 +75,7 @@ int main(int argc, char* argv[])
"--type", type,
"--posX", QString::number(center.x()),
"--posY", QString::number(center.y()),
"--debug", "1" });
"--mainapppid", "1" });
} else {
argumentList = app.arguments();
}
@ -86,63 +88,69 @@ int main(int argc, char* argv[])
QCommandLineOption typeOption("type", "Content type", "type");
QCommandLineOption posXOption("posX", "X position", "positionX");
QCommandLineOption posYOption("posY", "Y position", "positionY");
QCommandLineOption debugOption("debug", "debug enabled", "debug");
QCommandLineOption mainAppPidOption("mainapppid", "pid of the main ScreenPlay app. User to check if we are still alive.", "mainapppid");
// Add the options to the parser
parser.addOption(pathOption);
parser.addOption(appIDOption);
parser.addOption(typeOption);
parser.addOption(posXOption);
parser.addOption(posYOption);
parser.addOption(debugOption);
parser.addOption(mainAppPidOption);
// Process the actual command line arguments given by the user
parser.process(argumentList);
// Check if all required options are provided
// debug option is optional
if (!parser.isSet(pathOption)
|| !parser.isSet(appIDOption)
|| !parser.isSet(typeOption)
|| !parser.isSet(posXOption)
|| !parser.isSet(posYOption)) {
|| !parser.isSet(posYOption)
|| !parser.isSet(mainAppPidOption)) {
qCritical() << "Missing required arguments. Please provide all arguments."
<< argumentList
<< "pathOption" << parser.value(pathOption)
<< "appIDOption" << parser.value(appIDOption)
<< "typeOption" << parser.value(typeOption)
<< "posXOption" << parser.value(posXOption)
<< "posYOption" << parser.value(posYOption);
return -1;
<< "posYOption" << parser.value(posYOption)
<< "mainAppPidOption" << parser.value(mainAppPidOption);
return static_cast<int>(WidgetExit::Code::Invalid_ArgumentSize);
}
QString pid = parser.value(mainAppPidOption);
QString appID = parser.value(appIDOption);
QString projectPath = parser.value(pathOption);
QString type = parser.value(typeOption);
bool okPosX = false, okPosY = false;
const int positionX = parser.value(posXOption).toInt(&okPosX);
if (!okPosX) {
qWarning() << "Could not parse PositionX value to int: " << parser.value(posXOption);
return -1;
return static_cast<int>(WidgetExit::Code::Invalid_POSX);
}
const int positionY = parser.value(posYOption).toInt(&okPosY);
if (!okPosY) {
qWarning() << "Could not parse PositionY value to int: " << parser.value(posYOption);
return -1;
return static_cast<int>(WidgetExit::Code::Invalid_POSY);
}
bool debugOk = false;
const int debug = parser.value(debugOption).toInt(&debugOk);
if (!debugOk) {
qWarning() << "Could not parse debugOk value to bool: " << parser.value(posYOption);
bool okPid = false;
const qint64 mainAppPidInt = pid.toInt(&okPid);
if (!okPid) {
qCritical("Could not parse mainAppPid");
return static_cast<int>(WidgetExit::Code::Invalid_PID);
}
QString appID = parser.value(appIDOption);
QString projectPath = parser.value(pathOption);
QString type = parser.value(typeOption);
WidgetWindow spwmw(
projectPath,
appID,
type,
QPoint { positionX, positionY },
debug);
mainAppPidInt,
false);
#if defined(Q_OS_MACOS)
MacUtils::showDockIcon(false);

View File

@ -6,8 +6,10 @@
#include <QSysInfo>
#include "ScreenPlayUtil/contenttypes.h"
#include "ScreenPlayUtil/processmanager.h"
#include "ScreenPlayUtil/util.h"
namespace ScreenPlay {
/*!
\module ScreenPlayWidget
\title ScreenPlayWidget
@ -25,13 +27,14 @@ WidgetWindow::WidgetWindow(
const QString& appID,
const QString& type,
const QPoint& position,
const qint64 mainAppPID,
const bool debugMode)
: QObject(nullptr)
, m_appID { appID }
, m_position { position }
, m_sdk { std::make_unique<ScreenPlaySDK>(appID, type) }
, m_debugMode { debugMode }
{
setMainAppPID(mainAppPID);
Qt::WindowFlags flags = m_window.flags();
if (QSysInfo::productType() == "macos") {
// Setting it as a SlashScreen causes the window to hide on focus lost
@ -80,6 +83,8 @@ WidgetWindow::WidgetWindow(
// Debug mode means we directly start the ScreenPlayWallpaper for easy debugging.
// This means we do not have a running ScreenPlay instance to connect to.
if (!m_debugMode) {
m_sdk = std::make_unique<ScreenPlaySDK>(appID, type);
m_sdk->setMainAppPID(mainAppPID);
QObject::connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &WidgetWindow::qmlExit);
QObject::connect(m_sdk.get(), &ScreenPlaySDK::incommingMessage, this, &WidgetWindow::messageReceived);
sdk()->start();
@ -217,5 +222,17 @@ void WidgetWindow::setupLiveReloading()
m_fileSystemWatcher.addPath(projectFilesIter.next());
}
}
qint64 WidgetWindow::mainAppPID() const
{
return m_mainAppPID;
}
void WidgetWindow::setMainAppPID(qint64 mainAppPID)
{
if (m_mainAppPID == mainAppPID)
return;
m_mainAppPID = mainAppPID;
emit mainAppPIDChanged(m_mainAppPID);
}
}
#include "moc_widgetwindow.cpp"

View File

@ -27,6 +27,7 @@
#include "ScreenPlayUtil/util.h"
#include <memory>
namespace ScreenPlay {
class WidgetWindow : public QObject {
Q_OBJECT
@ -36,8 +37,10 @@ public:
const QString& appid,
const QString& type,
const QPoint& position,
const qint64 mainAppPID,
const bool debugMode = false);
Q_PROPERTY(qint64 mainAppPID READ mainAppPID WRITE setMainAppPID NOTIFY mainAppPIDChanged FINAL)
Q_PROPERTY(QString appID READ appID WRITE setAppID NOTIFY appIDChanged)
Q_PROPERTY(QString projectPath READ projectPath WRITE setProjectPath NOTIFY projectPathChanged)
Q_PROPERTY(QString projectSourceFile READ projectSourceFile WRITE setProjectSourceFile NOTIFY projectSourceFileChanged)
@ -56,6 +59,9 @@ public:
ScreenPlaySDK* sdk() const { return m_sdk.get(); }
bool debugMode() const { return m_debugMode; }
qint64 mainAppPID() const;
void setMainAppPID(qint64 mainAppPID);
signals:
void qmlExit();
void reloadQML(const ScreenPlay::ContentTypes::InstalledType oldType);
@ -69,6 +75,8 @@ signals:
void sdkChanged(ScreenPlaySDK* sdk);
void debugModeChanged(bool debugMode);
void mainAppPIDChanged(qint64 mainAppPID);
public slots:
void setSize(QSize size);
void destroyThis();
@ -155,6 +163,7 @@ private:
void setupLiveReloading();
private:
qint64 m_mainAppPID { 0 };
QString m_appID;
QString m_projectPath;
QString m_projectSourceFile;
@ -174,3 +183,4 @@ private:
#endif
bool m_debugMode = false;
};
}