/** * 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(); }