mirror of
https://gitee.com/spark-store-project/spark-web-app-runtime.git
synced 2025-07-04 04:36:00 +08:00
correct: SparkWebAppRunTime -> SparkWebAppRuntime Log: correct typo when parsing config file
350 lines
12 KiB
C++
350 lines
12 KiB
C++
/**
|
||
* Spark WebApp Runtime
|
||
* 星火网页应用运行环境
|
||
*/
|
||
#include "application.h"
|
||
#include "mainwindow.h"
|
||
#include "webengineview.h"
|
||
#include "httpd.h"
|
||
|
||
#include <DSysInfo>
|
||
#include <DApplicationSettings>
|
||
|
||
#include <QCommandLineParser>
|
||
#include <QCommandLineOption>
|
||
#include <QFileInfo>
|
||
#include <QSettings>
|
||
|
||
#include <unistd.h>
|
||
|
||
int main(int argc, char *argv[])
|
||
{
|
||
// 龙芯机器配置,使得 DApplication 能正确加载 QTWEBENGINE
|
||
qputenv("DTK_FORCE_RASTER_WIDGETS", "FALSE");
|
||
|
||
// 开启 HiDPI 缩放支持
|
||
DApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||
|
||
// 强制使用 DTK 平台插件
|
||
int fakeArgc = argc + 2;
|
||
QVector<char *> fakeArgv(fakeArgc);
|
||
fakeArgv[0] = argv[0];
|
||
fakeArgv[1] = const_cast<char *>("-platformtheme");
|
||
fakeArgv[2] = const_cast<char *>("deepin");
|
||
for (int i = 1; i < argc; i++) {
|
||
fakeArgv[i + 2] = argv[i];
|
||
}
|
||
Application a(fakeArgc, fakeArgv.data());
|
||
|
||
// 解析命令行启动参数
|
||
QCommandLineParser parser;
|
||
|
||
parser.setApplicationDescription(QObject::tr("Description: %1").arg(DEFAULT_TITLE));
|
||
parser.addHelpOption();
|
||
parser.addVersionOption();
|
||
|
||
QCommandLineOption optParser(QStringList() << "p"
|
||
<< "parser",
|
||
QObject::tr("Enable CommandLineParser. Default is false."));
|
||
parser.addOption(optParser);
|
||
|
||
QCommandLineOption optTitle(QStringList() << "t"
|
||
<< "title",
|
||
QObject::tr("The Title of Application. Default is %1.").arg(DEFAULT_TITLE),
|
||
"title",
|
||
DEFAULT_TITLE);
|
||
parser.addOption(optTitle);
|
||
|
||
QCommandLineOption optUrl(QStringList() << "u"
|
||
<< "url",
|
||
QObject::tr("The target URL. Default is Blank."),
|
||
"url",
|
||
DEFAULT_URL);
|
||
parser.addOption(optUrl);
|
||
|
||
QCommandLineOption optWidth(QStringList() << "w"
|
||
<< "width",
|
||
QObject::tr("The Width of Application. Default is %1.").arg(DEFAULT_WIDTH),
|
||
"width",
|
||
QString::number(DEFAULT_WIDTH));
|
||
parser.addOption(optWidth);
|
||
|
||
QCommandLineOption optHeight(QStringList() << "H"
|
||
<< "height",
|
||
QObject::tr("The Height of Application. Default is %1.").arg(DEFAULT_HEIGHT),
|
||
"height",
|
||
QString::number(DEFAULT_HEIGHT));
|
||
parser.addOption(optHeight);
|
||
|
||
QCommandLineOption optTray(QStringList() << "T"
|
||
<< "tray",
|
||
QObject::tr("Enable Tray Icon. Default is false."));
|
||
parser.addOption(optTray);
|
||
|
||
QCommandLineOption optFullScreen("full-screen",
|
||
QObject::tr("Run in Fullscreen Mode. Default is false."));
|
||
parser.addOption(optFullScreen);
|
||
|
||
QCommandLineOption optFixSize("fix-size",
|
||
QObject::tr("Fix Window Size. Default is false."));
|
||
parser.addOption(optFixSize);
|
||
|
||
QCommandLineOption optHideButtons("hide-buttons",
|
||
QObject::tr("Hide Control Buttons. Default is false."));
|
||
parser.addOption(optHideButtons);
|
||
|
||
QCommandLineOption optIcon(QStringList() << "i"
|
||
<< "ico",
|
||
QObject::tr("The ICON of Application."),
|
||
"ico",
|
||
DEFAULT_ICON);
|
||
parser.addOption(optIcon);
|
||
|
||
QCommandLineOption optDesc(QStringList() << "d"
|
||
<< "desc",
|
||
QObject::tr("The Description of Application."),
|
||
"desc",
|
||
DEFAULT_DESC);
|
||
parser.addOption(optDesc);
|
||
|
||
QCommandLineOption optCfgFile(QStringList() << "c"
|
||
<< "cfg",
|
||
QObject::tr("The Configuration file of Application."),
|
||
"cfg",
|
||
DEFAULT_CFG);
|
||
parser.addOption(optCfgFile);
|
||
|
||
QCommandLineOption optRootPath(QStringList() << "r"
|
||
<< "root",
|
||
QObject::tr("The root path of the program web service."),
|
||
"root",
|
||
DEFAULT_ROOT);
|
||
parser.addOption(optRootPath);
|
||
|
||
QCommandLineOption optPort(QStringList() << "P"
|
||
<< "port",
|
||
QObject::tr("The port number of the program web service."),
|
||
"port",
|
||
QString::number(DEFAULT_PORT));
|
||
parser.addOption(optPort);
|
||
|
||
QCommandLineOption useGPU(QStringList() << "G"
|
||
<< "GPU",
|
||
QObject::tr("To use GPU instead of CPU to decoding. Default True."),
|
||
"GPU",
|
||
QString::number(DEFAULT_GPU));
|
||
parser.addOption(useGPU);
|
||
|
||
#if SSL_SERVER
|
||
QCommandLineOption optSSLPort(QStringList() << "s"
|
||
<< "sslport",
|
||
QObject::tr("The ssl port number of the program web service."),
|
||
"sslport",
|
||
DEFAULT_PORT);
|
||
parser.addOption(optSSLPort);
|
||
#endif
|
||
|
||
parser.process(a);
|
||
|
||
QString szTitle = DEFAULT_TITLE;
|
||
QString szUrl = DEFAULT_URL;
|
||
int width = DEFAULT_WIDTH;
|
||
int height = DEFAULT_HEIGHT;
|
||
bool tray = false;
|
||
bool fullScreen = false;
|
||
bool fixSize = false;
|
||
bool hideButtons = false;
|
||
QString szIcon = DEFAULT_ICON;
|
||
QString szDesc = DEFAULT_DESC;
|
||
QString szRootPath = DEFAULT_ROOT;
|
||
quint16 u16Port = DEFAULT_PORT;
|
||
bool toUseGPU = DEFAULT_GPU;
|
||
#if SSL_SERVER
|
||
quint16 u16sslPort = 0;
|
||
#endif
|
||
QString szDefaultDesc = QObject::tr("Presented By Spark developers # HadesStudio");
|
||
|
||
// 解析可能存在的配置文件
|
||
QString szCfgFile = DEFAULT_CFG;
|
||
if (parser.isSet(optCfgFile)) {
|
||
szCfgFile = parser.value(optCfgFile);
|
||
if (!szCfgFile.isEmpty()) {
|
||
if (QFileInfo(szCfgFile).exists()) {
|
||
QSettings settings(szCfgFile, QSettings::IniFormat);
|
||
szTitle = settings.value("SparkWebAppRuntime/Title", DEFAULT_TITLE).toString();
|
||
szUrl = settings.value("SparkWebAppRuntime/URL", DEFAULT_TITLE).toString();
|
||
width = settings.value("SparkWebAppRuntime/Width", DEFAULT_WIDTH).toInt();
|
||
height = settings.value("SparkWebAppRuntime/Height", DEFAULT_HEIGHT).toInt();
|
||
tray = settings.value("SparkWebAppRuntime/Tray", false).toBool();
|
||
fullScreen = settings.value("SparkWebAppRuntime/FullScreen", false).toBool();
|
||
fixSize = settings.value("SparkWebAppRuntime/FixSize", false).toBool();
|
||
hideButtons = settings.value("SparkWebAppRuntime/HideButtons", false).toBool();
|
||
szIcon = settings.value("SparkWebAppRuntime/Ico", DEFAULT_ICON).toString();
|
||
szDesc = QString("%1<br/><br/>%2")
|
||
.arg(settings.value("SparkWebAppRuntime/Desc", QString()).toString())
|
||
.arg(szDefaultDesc);
|
||
szRootPath = settings.value("SparkWebAppRuntime/RootPath", QString()).toString();
|
||
u16Port = static_cast<quint16>(settings.value("SparkWebAppRuntime/Port", 0).toUInt());
|
||
#if SSL_SERVER
|
||
u16sslPort = settings.value("SparkWebAppRuntime/SSLPort", 0).toUInt();
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
// 命令行级别优先, 覆盖配置文件的设置
|
||
if (parser.isSet(optTitle)) {
|
||
szTitle = parser.value(optTitle);
|
||
}
|
||
if (parser.isSet(optUrl)) {
|
||
szUrl = parser.value(optUrl);
|
||
}
|
||
if (parser.isSet(optWidth)) {
|
||
width = parser.value(optWidth).toInt();
|
||
}
|
||
if (parser.isSet(optHeight)) {
|
||
height = parser.value(optHeight).toInt();
|
||
}
|
||
|
||
if (parser.isSet(optTray)) {
|
||
tray = true;
|
||
}
|
||
if (parser.isSet(optFullScreen)) {
|
||
fullScreen = true;
|
||
}
|
||
if (parser.isSet(optFixSize)) {
|
||
fixSize = true;
|
||
}
|
||
if (parser.isSet(optHideButtons)) {
|
||
hideButtons = true;
|
||
}
|
||
|
||
if (parser.isSet(optIcon)) {
|
||
szIcon = parser.value(optIcon);
|
||
}
|
||
if (parser.isSet(optDesc)) {
|
||
szDesc = QString("%1<br/><br/>%2").arg(parser.value(optDesc)).arg(szDefaultDesc);
|
||
}
|
||
|
||
if (parser.isSet(optRootPath)) {
|
||
szRootPath = parser.value(optRootPath);
|
||
}
|
||
|
||
if (parser.isSet(optPort)) {
|
||
u16Port = static_cast<quint16>(parser.value(optPort).toUInt());
|
||
}
|
||
|
||
if (parser.isSet(useGPU)) {
|
||
toUseGPU = parser.value(useGPU).toUInt();
|
||
}
|
||
|
||
QStringList chromium_flags = {"--disable-web-security"};
|
||
#if defined __sw_64__ || __loongarch__
|
||
chromium_flags << "--no-sandbox";
|
||
#endif
|
||
if (toUseGPU == true) {
|
||
chromium_flags << "--ignore-gpu-blocklist"
|
||
<< "--enable-gpu-rasterization"
|
||
<< "--enable-native-gpu-memory-buffers"
|
||
<< "--enable-accelerated-video-decode";
|
||
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", chromium_flags.join(" ").toUtf8());
|
||
qDebug() << "Setting GPU to True.";
|
||
}
|
||
// 初始化 QtWebEngine 深色模式环境变量
|
||
WebEngineView::handleChromiumFlags();
|
||
|
||
#if SSL_SERVER
|
||
if (parser.isSet(optSSLPort)) {
|
||
u16sslPort = parser.value(optSSLPort).toUInt();
|
||
}
|
||
#endif
|
||
|
||
// 没设置 -p 并且参数个数 > 1 并且第一个参数不是 - 开始的
|
||
if (!parser.isSet(optParser) && argc > 1 && !QString(argv[1]).startsWith("-")) {
|
||
// 按照固定顺序级别最优先
|
||
if (argc > 1) {
|
||
szTitle = argv[1];
|
||
}
|
||
if (argc > 2) {
|
||
szUrl = argv[2];
|
||
}
|
||
if (argc > 3) {
|
||
width = QString(argv[3]).toInt();
|
||
}
|
||
if (argc > 4) {
|
||
height = QString(argv[4]).toInt();
|
||
}
|
||
|
||
if (argc > 5) {
|
||
tray = true;
|
||
}
|
||
if (argc > 6) {
|
||
fullScreen = true;
|
||
}
|
||
if (argc > 7) {
|
||
fixSize = true;
|
||
}
|
||
if (argc > 8) {
|
||
hideButtons = true;
|
||
}
|
||
|
||
if (argc > 9) {
|
||
szIcon = QString(argv[9]);
|
||
}
|
||
if (argc > 10) {
|
||
szDesc = QString("%1<br/><br/>%2").arg(QString(argv[10])).arg(szDefaultDesc);
|
||
}
|
||
if (argc > 11) {
|
||
szRootPath = QString(argv[11]);
|
||
}
|
||
if (argc > 12) {
|
||
u16Port = static_cast<quint16>(QString(argv[12]).toUInt());
|
||
}
|
||
#if SSL_SERVER
|
||
if (argc > 13) {
|
||
u16sslPort = QString(argv[13]).toUInt();
|
||
}
|
||
#endif
|
||
}
|
||
|
||
if (fixSize) {
|
||
fullScreen = false; // 固定窗口大小时禁用全屏模式,避免标题栏按钮 BUG
|
||
}
|
||
|
||
// DApplication 单例运行(标题名称_当前登录用户 id)
|
||
if (!a.setSingleInstance(szTitle + "_" + QString::number(getuid()))) {
|
||
qInfo() << "Another instance has already started, now exit...";
|
||
exit(0);
|
||
}
|
||
a.setQuitOnLastWindowClosed(!tray); // 启用托盘时,退出程序后服务不终止
|
||
|
||
#if SSL_SERVER
|
||
if (!szRootPath.isEmpty() && u16Port > 0 && u16sslPort > 0) {
|
||
HttpD httpd(szRootPath, u16Port, u16sslPort);
|
||
httpd.start();
|
||
}
|
||
#else
|
||
if (!szRootPath.isEmpty() && u16Port > 0) {
|
||
static HttpD httpd(szRootPath, u16Port);
|
||
QObject::connect(&a, &Application::sigQuit, &httpd, &HttpD::stop);
|
||
httpd.start();
|
||
}
|
||
#endif
|
||
|
||
MainWindow w(szTitle, szUrl, width, height, tray, fullScreen, fixSize, hideButtons);
|
||
a.setMainWindow(&w);
|
||
QObject::connect(&a, &Application::newInstanceStarted, &w, &MainWindow::slotNewInstanceStarted);
|
||
QObject::connect(&w, &MainWindow::sigClose, &a, &Application::slotMainWindowClose);
|
||
|
||
if (!szIcon.isEmpty()) {
|
||
w.setIcon(szIcon);
|
||
}
|
||
if (!szDesc.isEmpty()) {
|
||
w.setDescription(szDesc);
|
||
}
|
||
|
||
w.show();
|
||
|
||
return a.exec();
|
||
}
|