/** * Spark WebApp Runtime * 星火网页应用运行环境 */ #include "application.h" #include "mainwindow.h" #include "webengineview.h" #include "httpd.h" #include #include #include #include #include #include #include int main(int argc, char *argv[]) { if (!QString(qgetenv("XDG_CURRENT_DESKTOP")).toLower().startsWith("deepin")) { qputenv("XDG_CURRENT_DESKTOP", "Deepin"); } // 龙芯机器配置,使得 DApplication 能正确加载 QTWEBENGINE qputenv("DTK_FORCE_RASTER_WIDGETS", "FALSE"); // qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-features=UseModernMediaControls"); // qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-web-security"); #ifdef __sw_64__ qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--no-sandbox"); #endif if (!Dtk::Core::DSysInfo::isDDE()) { #ifndef DSTORE_NO_DXCBs DApplication::loadDXcbPlugin(); #endif } // 开启 HiDPI 缩放支持 DApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // 强制使用 DTK 平台插件 int fakeArgc = argc + 2; QVector fakeArgv(fakeArgc); fakeArgv[0] = argv[0]; fakeArgv[1] = const_cast("-platformtheme"); fakeArgv[2] = const_cast("deepin"); for (int i = 1; i < argc; i++) { fakeArgv[i + 2] = argv[i]; } Application a(fakeArgc, fakeArgv.data()); // 保存 DTK 主题 DApplicationSettings settings; // 解析命令行启动参数 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 = QString("%1
" "%2") .arg(DEFAULT_TITLE) .arg(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

%2") .arg(settings.value("SparkWebAppRuntime/Desc", QString()).toString()) .arg(szDefaultDesc); szRootPath = settings.value("SparkWebAppRuntime/RootPath", QString()).toString(); u16Port = static_cast(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

%2").arg(parser.value(optDesc)).arg(szDefaultDesc); } if (parser.isSet(optRootPath)) { szRootPath = parser.value(optRootPath); } if (parser.isSet(optPort)) { u16Port = static_cast(parser.value(optPort).toUInt()); } if (parser.isSet(useGPU)) { toUseGPU = parser.value(useGPU).toUInt(); } qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-web-security); if (toUseGPU == true) { qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--ignore-gpu-blocklist --enable-gpu-rasterization --enable-native-gpu-memory-buffers --enable-accelerated-video-decode --disable-web-security); #ifdef __sw_64__ qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--ignore-gpu-blocklist --enable-gpu-rasterization --enable-native-gpu-memory-buffers --enable-accelerated-video-decode --disable-web-security --no-sandbox"); #endif 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

%2").arg(QString(argv[10])).arg(szDefaultDesc); } if (argc > 11) { szRootPath = QString(argv[11]); } if (argc > 12) { u16Port = static_cast(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(); }