17 Commits

Author SHA1 Message Date
zty199
f2b69ceb5e fix: typo in config group name
correct: SparkWebAppRunTime -> SparkWebAppRuntime

Log: correct typo when parsing config file
2024-10-20 17:34:24 +08:00
bf6a6893b3 fix: link update 2024-10-20 16:34:45 +08:00
zty199
c18a5b5b36 fix: compilation error on Ubuntu
add QtDBus module in .pro, for older version Dtk5 didn't include this module correctly

Log: add QtDBus module in .pro
2024-10-20 16:29:27 +08:00
64d5e51ef3 !5 reverse merge
Merge pull request !5 from shenmo/master
2024-10-20 08:11:56 +00:00
290c57e1bc actions 2024-10-20 16:03:27 +08:00
zty199
7e5525d4e9 fix: setDescription from cmdline or cfg not working
when aboutDialog is not created yet, ApplicationDescription can't be set

Log: merge changes from develop/qt6 branch
2024-10-20 15:47:35 +08:00
c4e34eb048 fix: Hide buttons can't take effect 2024-10-20 13:22:53 +08:00
3ded131e34 引号没结束
Signed-off-by: shenmo <jifengshenmo@outlook.com>
2024-10-19 15:07:03 +00:00
8a950603d9 1.8
Signed-off-by: shenmo <jifengshenmo@outlook.com>
2024-10-19 15:04:25 +00:00
19233d8c22 feat: Support local html file
Signed-off-by: shenmo <jifengshenmo@outlook.com>
2024-10-19 15:02:56 +00:00
4e4bf8a80f !4 修复多个窗口共用同一个配置文件导致锁定的问题
Merge pull request !4 from gfdgd xi/master
2024-10-19 14:58:45 +00:00
d197bd3a04 修复多个窗口共用同一个配置文件导致锁定的问题(https://gitee.com/spark-store-project/spark-web-app-runtime/issues/IA759Q) 2024-10-19 22:54:46 +08:00
zty199
a95e7e1beb feat: 使用自定义 webkit 滚动条
使用自定义 webkit 滚动条,避免 QWebEngineView 原生滚动条显示(仅在 QWebEnginePage 加载时生效,部分页面动态刷新时滚动条样式不生效)

Log: 使用自定义 webkit 滚动条
2023-10-14 18:23:58 +08:00
zty199
23b40dd231 fix: 修复关于窗口被主窗口遮挡问题
Application::initAboutDialog 执行过早,qApp->activeWindow() 指针为空,关于窗口没有父对象,与主窗口互相抢占焦点

Log: 去除 Application 构造函数中调用 initAboutDialog 操作;handleAboutAction 中,若 aboutDialog() 指针不为空则 return
2022-12-26 14:25:26 +08:00
zty199
edff5b7b31 chore: 添加 libqt5dbus5 依赖
debian/control 添加 libqt5dbus5 编译与运行依赖

Log: debian/control 添加 libqt5dbus5 依赖;更新 debian/changelog 版本至 1.7.0-1
2022-12-19 09:46:24 +08:00
zty199
6b8b31ebf6 fix: 修复 UOS 编译兼容性问题
网页通知获取依赖 QWebEngineNotification 类,在 Qt 5.13 引入

Log: 添加宏定义,判断 Qt 版本 >= 5.13 启用网页通知功能
2022-12-19 09:40:48 +08:00
zty199
faa613d671 feat: ISSUE #I62BVT 添加网页通知功能
WebEngineView 中添加 WebEngineView::present(std::unique_ptr<QWebEngineNotification> &newNotification) 函数,通过 DNotifySender 转发系统通知

Log: 添加网页通知功能,通知图片缓存在 /tmp 下;使用 DLogManager 生成日志;修复强制使用 DTK 平台插件异常问题
2022-12-19 09:31:32 +08:00
20 changed files with 368 additions and 193 deletions

13
.github/workflows/program-builder.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: Building Program
run-name: Building ${{ GITHUB.REPOSITORY }}
on:
workflow_dispatch:
push:
tags:
- "*"
jobs:
call:
uses: GXDE-OS/GXDE/.github/workflows/building-deb.yml@master
secrets: inherit

8
debian/changelog vendored
View File

@@ -1,3 +1,11 @@
spark-webapp-runtime (1.8) stable; urgency=medium
* Fix: Now won't lock cookies.
* Feat: Support local html files
-- shenmo <shenmo@spark-app.store> Mon, 19 Dec 2022 10:00:00 +0800
spark-webapp-runtime (1.6.6-1) stable; urgency=medium spark-webapp-runtime (1.6.6-1) stable; urgency=medium
* Enable Chromium Dark Mode when startup if DTK theme is DarkType (Qt >= 5.15) * Enable Chromium Dark Mode when startup if DTK theme is DarkType (Qt >= 5.15)

24
debian/control vendored
View File

@@ -6,13 +6,10 @@ Build-Depends:
debhelper (>= 9), debhelper (>= 9),
pkg-config, pkg-config,
qtchooser (>= 55-gc9562a1-1~), qtchooser (>= 55-gc9562a1-1~),
libqt5core5a, qtbase5-dev,
libqt5gui5,
libqt5widgets5,
libqt5concurrent5,
libqt5svg5-dev, libqt5svg5-dev,
qtwebengine5-dev, qtwebengine5-dev,
qttools5-private-dev, qttools5-dev-tools,
libdtkcore-dev (>= 5.0), libdtkcore-dev (>= 5.0),
libdtkgui-dev (>= 5.0), libdtkgui-dev (>= 5.0),
libdtkwidget-dev (>= 5.0) libdtkwidget-dev (>= 5.0)
@@ -21,19 +18,10 @@ Homepage: https://gitee.com/deepin-community-store/spark-web-app-runtime
Package: spark-webapp-runtime Package: spark-webapp-runtime
Conflicts: store.spark-app.spark-webapp-runtime
Replaces: store.spark-app.spark-webapp-runtime
Provides: store.spark-app.spark-webapp-runtime
Architecture: any Architecture: any
Depends:${shlibs:Depends}, ${misc:Depends}, Depends:${shlibs:Depends}, ${misc:Depends}
libqt5core5a, Conflicts: store.spark-app.spark-webapp-runtime
libqt5gui5, Provides: store.spark-app.spark-webapp-runtime
libqt5widgets5, Replaces: store.spark-app.spark-webapp-runtime
libqt5concurrent5,
libqt5svg5,
libqt5webenginewidgets5,
libdtkcore5,
libdtkgui5,
libdtkwidget5
Description: Spark WebApp Runtime Description: Spark WebApp Runtime
A simple solution for packaging web apps. A simple solution for packaging web apps.

21
debian/rules vendored
View File

@@ -1,35 +1,36 @@
#!/usr/bin/make -f #!/usr/bin/make -f
export QT_SELECT=5 export QT_SELECT = qt5
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
include /usr/share/dpkg/default.mk include /usr/share/dpkg/default.mk
DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
DH_AUTO_ARGS = --parallel --buildsystem=qmake DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
# Uncomment this to turn on verbose mode. # Uncomment this to turn on verbose mode.
# export DH_VERBOSE=1 #export DH_VERBOSE=1
%: %:
dh $@ --parallel dh $@ --parallel
override_dh_auto_clean: override_dh_auto_clean:
rm -rf $(CURDIR)/build rm -rf $(CURDIR)/build-$(DEB_HOST_MULTIARCH)
override_dh_auto_configure: override_dh_auto_configure:
mkdir -p $(CURDIR)/build mkdir -p $(CURDIR)/build-$(DEB_HOST_MULTIARCH)
dh_auto_configure MAKEFLAGS=-j$(JOBS) -- spark-webapp-runtime.pro \ qmake BUILD_VERSION=$(DEB_VERSION_UPSTREAM) spark-webapp-runtime.pro \
-spec linux-g++ CONFIG+=qtquickcompiler \ -spec linux-g++ CONFIG+=force_debug_info \
-o $(CURDIR)/build/ -o $(CURDIR)/build-$(DEB_HOST_MULTIARCH)/
override_dh_auto_build: override_dh_auto_build:
make -C $(CURDIR)/build -j$(JOBS) make -C $(CURDIR)/build-$(DEB_HOST_MULTIARCH) -j$(JOBS)
override_dh_auto_install: override_dh_auto_install:
make -C $(CURDIR)/build install \ make -C $(CURDIR)/build-$(DEB_HOST_MULTIARCH) install \
INSTALL_ROOT=$(CURDIR)/debian/spark-webapp-runtime INSTALL_ROOT=$(CURDIR)/debian/spark-webapp-runtime

View File

@@ -4,9 +4,17 @@
#include <DPlatformWindowHandle> #include <DPlatformWindowHandle>
#include <DAboutDialog> #include <DAboutDialog>
#include <QStandardPaths>
#include <unistd.h>
const QString websiteLinkTemplate = "<a href='%1' style='text-decoration: none; color: rgba(0,129,255,0.9);'>%2</a>";
Application::Application(int &argc, char **argv) Application::Application(int &argc, char **argv)
: DApplication(argc, argv) : DApplication(argc, argv)
{ {
saveLaunchParams(argc, argv);
loadTranslator(); loadTranslator();
setAttribute(Qt::AA_UseHighDpiPixmaps); setAttribute(Qt::AA_UseHighDpiPixmaps);
@@ -14,68 +22,68 @@ Application::Application(int &argc, char **argv)
setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
} }
setApplicationVersion(QString(CURRENT_VER));
setOrganizationName(ORGANIZATION_NAME); // 添加组织名称,和商店主体的文件夹同在 ~/.local/share/spark-union 文件夹下 setOrganizationName(ORGANIZATION_NAME); // 添加组织名称,和商店主体的文件夹同在 ~/.local/share/spark-union 文件夹下
setApplicationName(APPLICATION_NAME); // 这里不要翻译,否则 ~/.local/share 中文件夹名也会被翻译 setApplicationName(PROJECT_NAME); // 这里不要翻译,否则 ~/.local/share 中文件夹名也会被翻译
setProductName(DEFAULT_TITLE); setApplicationVersion(APP_VERSION);
setApplicationDisplayName(DEFAULT_TITLE); setApplicationDisplayName(DEFAULT_TITLE);
setApplicationLicense(" <a href='https://www.gnu.org/licenses/gpl-3.0.html'>GPLv3</a> "); setWindowIcon(QIcon(":/images/spark-webapp-runtime.svg"));
initAboutDialog(); setProductIcon(QIcon(":/images/spark-webapp-runtime.svg"));
setProductName(websiteLinkTemplate.arg("https://gitee.com/spark-store-project/spark-web-app-runtime", DEFAULT_TITLE));
setApplicationDescription(QObject::tr("Presented By Spark developers # HadesStudio"));
setApplicationLicense(websiteLinkTemplate.arg("https://gitee.com/spark-store-project/spark-web-app-runtime/blob/master/LICENSE", "GPLv3"));
}
void Application::triggerAboutAction()
{
handleAboutAction();
}
QStringList Application::launchParams() const
{
return m_argv;
}
void Application::setMainWindow(MainWindow *window)
{
m_mainWindow = window;
}
MainWindow *Application::mainWindow()
{
return m_mainWindow;
} }
void Application::handleAboutAction() void Application::handleAboutAction()
{ {
if (aboutDialog()) {
DApplication::handleAboutAction();
return;
}
initAboutDialog();
DApplication::handleAboutAction(); DApplication::handleAboutAction();
DAboutDialog *dialog = aboutDialog();
if (dialog) {
// CompanyLogo
dialog->setCompanyLogo(QPixmap(":/images/Logo-Spark.png"));
// WebsiteName
dialog->setWebsiteName("Spark Project");
// WebsiteLink
dialog->setWebsiteLink("https://gitee.com/spark-store-project/");
}
} }
void Application::initAboutDialog() void Application::saveLaunchParams(int &argc, char **argv)
{ {
// Customized DAboutDialog m_argc = argc;
DAboutDialog *dialog = new DAboutDialog(activeWindow());
// WindowIcon
dialog->setWindowIcon(QIcon(":/images/spark-webapp-runtime.svg"));
// ProductIcon
dialog->setProductIcon(QIcon(":/images/spark-webapp-runtime.svg"));
// ProductName
dialog->setProductName(productName());
// Version
dialog->setVersion(translate("DAboutDialog", "Version: %1").arg(applicationVersion()));
// CompanyLogo
dialog->setCompanyLogo(QPixmap(":/images/Logo-Spark.png"));
// Description
QString szDefaultDesc = QString("<a href='https://gitee.com/deepin-community-store/spark-web-app-runtime'><span style='font-size:12pt;font-weight:500;'>%1</span></a><br/>" m_argv.clear();
"<span style='font-size:12pt;'>%2</span>") for (int i = 0; i < m_argc; i++) {
.arg(DEFAULT_TITLE) m_argv.append(argv[i]);
.arg(QObject::tr("Presented By Spark developers # HadesStudio")); }
dialog->setDescription(szDefaultDesc); qDebug() << Q_FUNC_INFO << m_argc << m_argv;
// WebsiteName
dialog->setWebsiteName("Spark Project");
// WebsiteLink
dialog->setWebsiteLink("https://gitee.com/deepin-community-store/");
// License
dialog->setLicense(translate("DAboutDialog", "%1 is released under %2").arg(productName()).arg(applicationLicense()));
setAboutDialog(dialog);
connect(aboutDialog(), &DAboutDialog::destroyed, this, [=] {
setAboutDialog(nullptr);
});
dialog->hide();
} }
void Application::slotMainWindowClose() void Application::slotMainWindowClose()
{ {
if (aboutDialog()) { if (aboutDialog()) {
aboutDialog()->close(); aboutDialog()->close();
aboutDialog()->deleteLater();
} }
} }

View File

@@ -1,6 +1,8 @@
#ifndef APPLICATION_H #ifndef APPLICATION_H
#define APPLICATION_H #define APPLICATION_H
#include "mainwindow.h"
#include <DApplication> #include <DApplication>
DWIDGET_USE_NAMESPACE DWIDGET_USE_NAMESPACE
@@ -11,16 +13,30 @@ class Application : public DApplication
public: public:
Application(int &argc, char **argv); Application(int &argc, char **argv);
void triggerAboutAction();
QStringList launchParams() const;
void setMainWindow(MainWindow *window);
MainWindow *mainWindow();
protected:
void handleAboutAction() override; void handleAboutAction() override;
private: private:
void initAboutDialog(); void saveLaunchParams(int &argc, char **argv);
signals: signals:
void sigQuit(); void sigQuit();
public slots: public slots:
void slotMainWindowClose(); void slotMainWindowClose();
private:
MainWindow *m_mainWindow = nullptr;
int m_argc;
QStringList m_argv;
}; };
#endif // APPLICATION_H #endif // APPLICATION_H

View File

@@ -4,7 +4,6 @@
#include <QObject> #include <QObject>
#define DEFAULT_TITLE QObject::tr("SparkWebAppRuntime") #define DEFAULT_TITLE QObject::tr("SparkWebAppRuntime")
#define APPLICATION_NAME QString("SparkWebAppRuntime")
#define ORGANIZATION_NAME QString("spark-union") #define ORGANIZATION_NAME QString("spark-union")
#define DEFAULT_URL QString("qrc:/help/help.html") #define DEFAULT_URL QString("qrc:/help/help.html")
#define DEFAULT_WIDTH (1024) #define DEFAULT_WIDTH (1024)
@@ -18,6 +17,4 @@
#define DEFAULT_PORT 0 #define DEFAULT_PORT 0
#define DEFAULT_GPU 1 #define DEFAULT_GPU 1
#define CURRENT_VER QString("1.6.6")
#endif // GLOBALDEFINE_H #endif // GLOBALDEFINE_H

View File

@@ -19,23 +19,8 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if (!QString(qgetenv("XDG_CURRENT_DESKTOP")).toLower().startsWith("deepin")) {
qputenv("XDG_CURRENT_DESKTOP", "Deepin");
}
// 龙芯机器配置,使得 DApplication 能正确加载 QTWEBENGINE // 龙芯机器配置,使得 DApplication 能正确加载 QTWEBENGINE
qputenv("DTK_FORCE_RASTER_WIDGETS", "FALSE"); 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 缩放支持 // 开启 HiDPI 缩放支持
DApplication::setAttribute(Qt::AA_EnableHighDpiScaling); DApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@@ -44,16 +29,13 @@ int main(int argc, char *argv[])
int fakeArgc = argc + 2; int fakeArgc = argc + 2;
QVector<char *> fakeArgv(fakeArgc); QVector<char *> fakeArgv(fakeArgc);
fakeArgv[0] = argv[0]; fakeArgv[0] = argv[0];
fakeArgv[1] = QString("-platformtheme").toUtf8().data(); fakeArgv[1] = const_cast<char *>("-platformtheme");
fakeArgv[2] = QString("deepin").toUtf8().data(); fakeArgv[2] = const_cast<char *>("deepin");
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
fakeArgv[i + 2] = argv[i]; fakeArgv[i + 2] = argv[i];
} }
Application a(fakeArgc, fakeArgv.data()); Application a(fakeArgc, fakeArgv.data());
// 保存 DTK 主题
DApplicationSettings settings;
// 解析命令行启动参数 // 解析命令行启动参数
QCommandLineParser parser; QCommandLineParser parser;
@@ -180,10 +162,7 @@ int main(int argc, char *argv[])
#if SSL_SERVER #if SSL_SERVER
quint16 u16sslPort = 0; quint16 u16sslPort = 0;
#endif #endif
QString szDefaultDesc = QString("<a href='https://gitee.com/deepin-community-store/spark-web-app-runtime'><span style='font-size:12pt;font-weight:500;'>%1</span></a><br/>" QString szDefaultDesc = QObject::tr("Presented By Spark developers # HadesStudio");
"<span style='font-size:12pt;'>%2</span>")
.arg(DEFAULT_TITLE)
.arg(QObject::tr("Presented By Spark developers # HadesStudio"));
// 解析可能存在的配置文件 // 解析可能存在的配置文件
QString szCfgFile = DEFAULT_CFG; QString szCfgFile = DEFAULT_CFG;
@@ -196,10 +175,10 @@ int main(int argc, char *argv[])
szUrl = settings.value("SparkWebAppRuntime/URL", DEFAULT_TITLE).toString(); szUrl = settings.value("SparkWebAppRuntime/URL", DEFAULT_TITLE).toString();
width = settings.value("SparkWebAppRuntime/Width", DEFAULT_WIDTH).toInt(); width = settings.value("SparkWebAppRuntime/Width", DEFAULT_WIDTH).toInt();
height = settings.value("SparkWebAppRuntime/Height", DEFAULT_HEIGHT).toInt(); height = settings.value("SparkWebAppRuntime/Height", DEFAULT_HEIGHT).toInt();
tray = settings.value("SparkWebAppRunTime/Tray", false).toBool(); tray = settings.value("SparkWebAppRuntime/Tray", false).toBool();
fullScreen = settings.value("SparkWebAppRunTime/FullScreen", false).toBool(); fullScreen = settings.value("SparkWebAppRuntime/FullScreen", false).toBool();
fixSize = settings.value("SparkWebAppRunTime/FixSize", false).toBool(); fixSize = settings.value("SparkWebAppRuntime/FixSize", false).toBool();
hideButtons = settings.value("SparkWebAppRunTime/HideButtons", false).toBool(); hideButtons = settings.value("SparkWebAppRuntime/HideButtons", false).toBool();
szIcon = settings.value("SparkWebAppRuntime/Ico", DEFAULT_ICON).toString(); szIcon = settings.value("SparkWebAppRuntime/Ico", DEFAULT_ICON).toString();
szDesc = QString("%1<br/><br/>%2") szDesc = QString("%1<br/><br/>%2")
.arg(settings.value("SparkWebAppRuntime/Desc", QString()).toString()) .arg(settings.value("SparkWebAppRuntime/Desc", QString()).toString())
@@ -258,11 +237,17 @@ int main(int argc, char *argv[])
if (parser.isSet(useGPU)) { if (parser.isSet(useGPU)) {
toUseGPU = parser.value(useGPU).toUInt(); toUseGPU = parser.value(useGPU).toUInt();
} }
if (toUseGPU == true) {
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--ignore-gpu-blocklist --enable-gpu-rasterization --enable-native-gpu-memory-buffers --enable-accelerated-video-decode"); QStringList chromium_flags = {"--disable-web-security"};
#ifdef __sw_64__ #if defined __sw_64__ || __loongarch__
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--ignore-gpu-blocklist --enable-gpu-rasterization --enable-native-gpu-memory-buffers --enable-accelerated-video-decode --no-sandbox"); chromium_flags << "--no-sandbox";
#endif #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."; qDebug() << "Setting GPU to True.";
} }
// 初始化 QtWebEngine 深色模式环境变量 // 初始化 QtWebEngine 深色模式环境变量
@@ -347,6 +332,7 @@ int main(int argc, char *argv[])
#endif #endif
MainWindow w(szTitle, szUrl, width, height, tray, fullScreen, fixSize, hideButtons); MainWindow w(szTitle, szUrl, width, height, tray, fullScreen, fixSize, hideButtons);
a.setMainWindow(&w);
QObject::connect(&a, &Application::newInstanceStarted, &w, &MainWindow::slotNewInstanceStarted); QObject::connect(&a, &Application::newInstanceStarted, &w, &MainWindow::slotNewInstanceStarted);
QObject::connect(&w, &MainWindow::sigClose, &a, &Application::slotMainWindowClose); QObject::connect(&w, &MainWindow::sigClose, &a, &Application::slotMainWindowClose);

View File

@@ -1,8 +1,7 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "application.h" #include "application.h"
#include "webengineview.h"
#include "webenginepage.h"
#include <DLog>
#include <DWidgetUtil> #include <DWidgetUtil>
#include <DTitlebar> #include <DTitlebar>
#include <DMessageManager> #include <DMessageManager>
@@ -15,6 +14,10 @@
#include <QDir> #include <QDir>
#include <QStandardPaths> #include <QStandardPaths>
#include <unistd.h>
DCORE_USE_NAMESPACE
MainWindow::MainWindow(QString szTitle, MainWindow::MainWindow(QString szTitle,
QString szUrl, QString szUrl,
int nWidth, int nWidth,
@@ -33,7 +36,7 @@ MainWindow::MainWindow(QString szTitle,
, m_isFullScreen(nFullScreen) , m_isFullScreen(nFullScreen)
, m_isFixedSize(nFixSize) , m_isFixedSize(nFixSize)
, m_isHideButton(nHideButtons) , m_isHideButton(nHideButtons)
, m_widget(new Widget(m_url, this)) , m_widget(new Widget(m_url, this, m_title))
, m_tray(new QSystemTrayIcon(this)) , m_tray(new QSystemTrayIcon(this))
, btnBack(new DToolButton(titlebar())) , btnBack(new DToolButton(titlebar()))
, btnForward(new DToolButton(titlebar())) , btnForward(new DToolButton(titlebar()))
@@ -45,8 +48,8 @@ MainWindow::MainWindow(QString szTitle,
, m_clearCache(new QAction(QObject::tr("Clear Cache"), this)) , m_clearCache(new QAction(QObject::tr("Clear Cache"), this))
, t_menu(new QMenu(this)) , t_menu(new QMenu(this))
, t_show(new QAction(QObject::tr("Show MainWindow"), this)) , t_show(new QAction(QObject::tr("Show MainWindow"), this))
, t_about(new QAction(qApp->translate("TitleBarMenu", "About"), this)) , t_about(new QAction(qApp->translate("TitleBarMenu", QString("About").toUtf8().data()), this))
, t_exit(new QAction(qApp->translate("TitleBarMenu", "Exit"), this)) , t_exit(new QAction(qApp->translate("TitleBarMenu", QString("Exit").toUtf8().data()), this))
, downloadMessage(new DFloatingMessage(DFloatingMessage::ResidentType, this)) , downloadMessage(new DFloatingMessage(DFloatingMessage::ResidentType, this))
, downloadProgressWidget(new QWidget(downloadMessage)) , downloadProgressWidget(new QWidget(downloadMessage))
, progressBarLayout(new QHBoxLayout(downloadProgressWidget)) , progressBarLayout(new QHBoxLayout(downloadProgressWidget))
@@ -56,6 +59,9 @@ MainWindow::MainWindow(QString szTitle,
, btnCancel(new DPushButton(QObject::tr("Cancel"), downloadProgressWidget)) , btnCancel(new DPushButton(QObject::tr("Cancel"), downloadProgressWidget))
, isCanceled(false) , isCanceled(false)
{ {
initTmpDir();
initLog();
initUI(); initUI();
initTrayIcon(); initTrayIcon();
initConnections(); initConnections();
@@ -67,7 +73,7 @@ MainWindow::~MainWindow()
void MainWindow::setIcon(QString szIconPath) void MainWindow::setIcon(QString szIconPath)
{ {
if (!QFileInfo(szIconPath).exists()) { if (!QFile::exists(szIconPath)) {
return; return;
} }
@@ -75,19 +81,25 @@ void MainWindow::setIcon(QString szIconPath)
setWindowIcon(QIcon(szIconPath)); setWindowIcon(QIcon(szIconPath));
m_tray->setIcon(QIcon(szIconPath)); m_tray->setIcon(QIcon(szIconPath));
DAboutDialog *aboutDialog = qobject_cast<Application *>(qApp)->aboutDialog(); qApp->setWindowIcon(QIcon::fromTheme(szIconPath));
if (aboutDialog) { qApp->setProductIcon(QIcon::fromTheme(szIconPath));
aboutDialog->setWindowIcon(QIcon::fromTheme(szIconPath));
aboutDialog->setProductIcon(QIcon::fromTheme(szIconPath));
}
} }
void MainWindow::setDescription(const QString &desc) void MainWindow::setDescription(const QString &desc)
{ {
DAboutDialog *aboutDialog = qobject_cast<Application *>(qApp)->aboutDialog(); qApp->setApplicationDescription(desc);
if (aboutDialog) { }
aboutDialog->setDescription(desc);
} QString MainWindow::title() const
{
return m_title;
}
QString MainWindow::tmpDir() const
{
QString orgName = qobject_cast<DApplication *>(qApp)->organizationName();
QString appName = qobject_cast<DApplication *>(qApp)->applicationName();
return QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + orgName + "/" + appName + "/" + m_title + "/" + QString::number(getuid());
} }
void MainWindow::keyPressEvent(QKeyEvent *event) void MainWindow::keyPressEvent(QKeyEvent *event)
@@ -127,6 +139,29 @@ void MainWindow::closeEvent(QCloseEvent *event)
DMainWindow::closeEvent(event); DMainWindow::closeEvent(event);
} }
void MainWindow::initLog()
{
if (!QDir(tmpDir()).exists()) {
return;
}
DLogManager::setlogFilePath(tmpDir() + "/" + "log");
DLogManager::registerFileAppender();
DLogManager::registerConsoleAppender();
}
void MainWindow::initTmpDir()
{
QDir dir(tmpDir());
dir.removeRecursively();
dir.mkpath(dir.path());
if (!dir.exists()) {
qCritical() << Q_FUNC_INFO << dir.path() << "not exists";
return;
}
qDebug() << Q_FUNC_INFO << dir.path() << "created";
}
void MainWindow::initUI() void MainWindow::initUI()
{ {
// 初始化 MainWindow // 初始化 MainWindow
@@ -144,6 +179,7 @@ void MainWindow::initUI()
fixSize(); fixSize();
fullScreen(); fullScreen();
hideButtons(); // 修复指定hidebuttons之后没有生效
} }
void MainWindow::initTitleBar() void MainWindow::initTitleBar()
@@ -258,7 +294,7 @@ void MainWindow::initConnections()
fixSize(); fixSize();
}); });
connect(t_about, &QAction::triggered, this, [=]() { connect(t_about, &QAction::triggered, this, [=]() {
qobject_cast<Application *>(qApp)->handleAboutAction(); qobject_cast<Application *>(qApp)->triggerAboutAction();
}); });
connect(t_exit, &QAction::triggered, this, [=]() { connect(t_exit, &QAction::triggered, this, [=]() {
exit(0); exit(0);
@@ -339,7 +375,7 @@ QString MainWindow::saveAs(QString fileName)
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/" + fileName); QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/" + fileName);
if (!saveFile.isEmpty()) { if (!saveFile.isEmpty()) {
// 判断上层目录是否可写入 // 判断上层目录是否可写入
if (QFileInfo(QFileInfo(saveFile).absolutePath()).isWritable()) { if (QFileInfo(QFileInfo(saveFile).absoluteDir().canonicalPath()).isWritable()) {
return saveFile; return saveFile;
} else { } else {
return saveAs(fileName); return saveAs(fileName);
@@ -373,14 +409,13 @@ void MainWindow::on_downloadStart(QWebEngineDownloadItem *item)
{ {
// 尝试加锁互斥量,禁止同时下载多个文件 // 尝试加锁互斥量,禁止同时下载多个文件
if (mutex.tryLock()) { if (mutex.tryLock()) {
QString fileName = QFileInfo(item->path()).fileName(); QString fileName = item->downloadFileName();
QString filePath = saveAs(fileName); QString filePath = saveAs(fileName);
if (filePath.isEmpty()) { if (filePath.isEmpty()) {
mutex.unlock(); mutex.unlock();
return; return;
} }
item->setPath(filePath); item->setDownloadDirectory(QFileInfo(filePath).absoluteDir().canonicalPath());
filePath = QFileInfo(item->path()).absoluteFilePath();
connect(item, &QWebEngineDownloadItem::downloadProgress, this, &MainWindow::on_downloadProgress); connect(item, &QWebEngineDownloadItem::downloadProgress, this, &MainWindow::on_downloadProgress);
connect(item, &QWebEngineDownloadItem::finished, this, [=]() { connect(item, &QWebEngineDownloadItem::finished, this, [=]() {

View File

@@ -36,12 +36,18 @@ public:
void setIcon(QString szIconPath); void setIcon(QString szIconPath);
void setDescription(const QString &desc); void setDescription(const QString &desc);
QString title() const;
QString tmpDir() const;
protected: protected:
void keyPressEvent(QKeyEvent *event); void keyPressEvent(QKeyEvent *event);
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
private: private:
void initLog();
void initTmpDir();
void initUI(); void initUI();
void initTitleBar(); void initTitleBar();
void initDownloadProgressBar(); void initDownloadProgressBar();

View File

@@ -0,0 +1,26 @@
::-webkit-scrollbar {
width: 12px;
height: 12px;
background-color: transparent
}
::-webkit-scrollbar-thumb {
border: 2px solid transparent;
border-radius: 99px;
background-clip: padding-box;
background-color: rgba(80, 80, 80, 0.3);
-webkit-transition: background 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
transition: background 0.2s cubic-bezier(0.34, 0.69, 0.1, 1)
}
::-webkit-scrollbar-button {
display: none
}
::-webkit-scrollbar-corner {
display: none
}
::-webkit-scrollbar-thumb:hover {
background-color: rgba(80, 80, 80, 0.6)!important
}

View File

@@ -1,5 +1,6 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>css/webkit-scrollbar.css</file>
<file>images/spark-webapp-runtime.svg</file> <file>images/spark-webapp-runtime.svg</file>
<file>images/Logo-Spark.png</file> <file>images/Logo-Spark.png</file>
<file>images/go-previous-24.svg</file> <file>images/go-previous-24.svg</file>

View File

@@ -1,4 +1,4 @@
QT += core gui webenginewidgets svg concurrent QT += core gui webenginewidgets concurrent dbus
greaterThan(QT_MAJOR_VERSION, 5): QT += widgets greaterThan(QT_MAJOR_VERSION, 5): QT += widgets
@@ -6,6 +6,13 @@ TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += PROJECT_NAME=\\\"'$${TARGET}'\\\"
# Get build version from qmake
VERSION = $$BUILD_VERSION
isEmpty(VERSION): VERSION = 1.0
DEFINES += APP_VERSION=\\\"'$${VERSION}'\\\"
CONFIG += c++11 link_pkgconfig CONFIG += c++11 link_pkgconfig
PKGCONFIG += dtkcore dtkgui dtkwidget PKGCONFIG += dtkcore dtkgui dtkwidget
@@ -31,10 +38,10 @@ SOURCES += \
webengineurlrequestinterceptor.cpp webengineurlrequestinterceptor.cpp
RESOURCES += \ RESOURCES += \
resources/resources.qrc resources/resources.qrc
TRANSLATIONS += \ TRANSLATIONS += \
translations/spark-webapp-runtime_zh_CN.ts translations/$${TARGET}_zh_CN.ts
# Default rules for deployment. # Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin qnx: target.path = /tmp/$${TARGET}/bin

View File

@@ -1,109 +1,96 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS> <!DOCTYPE TS>
<TS version="2.1" language="zh_CN"> <TS version="2.1" language="zh_CN">
<context>
<name>DAboutDialog</name>
<message>
<location filename="../application.cpp" line="49"/>
<source>Version: %1</source>
<translation>%1</translation>
</message>
<message>
<location filename="../application.cpp" line="65"/>
<source>%1 is released under %2</source>
<translation>%1%2</translation>
</message>
</context>
<context> <context>
<name>QObject</name> <name>QObject</name>
<message> <message>
<location filename="../application.cpp" line="57"/> <location filename="../application.cpp" line="33"/>
<location filename="../main.cpp" line="186"/> <location filename="../main.cpp" line="165"/>
<source>Presented By Spark developers # HadesStudio</source> <source>Presented By Spark developers # HadesStudio</source>
<translation> @ </translation> <translation> @ </translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="60"/> <location filename="../main.cpp" line="42"/>
<source>Description: %1</source> <source>Description: %1</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="66"/> <location filename="../main.cpp" line="48"/>
<source>Enable CommandLineParser. Default is false.</source> <source>Enable CommandLineParser. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="71"/> <location filename="../main.cpp" line="53"/>
<source>The Title of Application. Default is %1.</source> <source>The Title of Application. Default is %1.</source>
<translation> %1</translation> <translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="78"/> <location filename="../main.cpp" line="60"/>
<source>The target URL. Default is Blank.</source> <source>The target URL. Default is Blank.</source>
<translation> URL</translation> <translation> URL</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="85"/> <location filename="../main.cpp" line="67"/>
<source>The Width of Application. Default is %1.</source> <source>The Width of Application. Default is %1.</source>
<translation> %1</translation> <translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="92"/> <location filename="../main.cpp" line="74"/>
<source>The Height of Application. Default is %1.</source> <source>The Height of Application. Default is %1.</source>
<translation> %1</translation> <translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="99"/> <location filename="../main.cpp" line="81"/>
<source>Enable Tray Icon. Default is false.</source> <source>Enable Tray Icon. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="103"/> <location filename="../main.cpp" line="85"/>
<source>Run in Fullscreen Mode. Default is false.</source> <source>Run in Fullscreen Mode. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="107"/> <location filename="../main.cpp" line="89"/>
<source>Fix Window Size. Default is false.</source> <source>Fix Window Size. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="111"/> <location filename="../main.cpp" line="93"/>
<source>Hide Control Buttons. Default is false.</source> <source>Hide Control Buttons. Default is false.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="116"/> <location filename="../main.cpp" line="98"/>
<source>The ICON of Application.</source> <source>The ICON of Application.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="123"/> <location filename="../main.cpp" line="105"/>
<source>The Description of Application.</source> <source>The Description of Application.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="130"/> <location filename="../main.cpp" line="112"/>
<source>The Configuration file of Application.</source> <source>The Configuration file of Application.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="137"/> <location filename="../main.cpp" line="119"/>
<source>The root path of the program web service.</source> <source>The root path of the program web service.</source>
<translation> WebServer </translation> <translation> WebServer </translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="144"/> <location filename="../main.cpp" line="126"/>
<source>The port number of the program web service.</source> <source>The port number of the program web service.</source>
<translation> WebServer </translation> <translation> WebServer </translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="151"/> <location filename="../main.cpp" line="133"/>
<source>To use GPU instead of CPU to decoding. Default True.</source> <source>To use GPU instead of CPU to decoding. Default True.</source>
<translation>GPU渲染</translation> <translation>GPU渲染</translation>
</message> </message>
<message> <message>
<location filename="../main.cpp" line="159"/> <location filename="../main.cpp" line="141"/>
<source>The ssl port number of the program web service.</source> <source>The ssl port number of the program web service.</source>
<translation> WebServer SSL </translation> <translation> WebServer SSL </translation>
</message> </message>
@@ -113,97 +100,89 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="42"/> <location filename="../mainwindow.cpp" line="45"/>
<source>Full Screen</source> <source>Full Screen</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="43"/> <location filename="../mainwindow.cpp" line="46"/>
<source>Fix Size</source> <source>Fix Size</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="44"/> <location filename="../mainwindow.cpp" line="47"/>
<source>Hide Buttons</source> <source>Hide Buttons</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="45"/> <location filename="../mainwindow.cpp" line="48"/>
<source>Clear Cache</source> <source>Clear Cache</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="47"/> <location filename="../mainwindow.cpp" line="50"/>
<source>Show MainWindow</source> <source>Show MainWindow</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="54"/> <location filename="../mainwindow.cpp" line="57"/>
<source>Pause</source> <source>Pause</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="55"/> <location filename="../mainwindow.cpp" line="58"/>
<source>Resume</source> <source>Resume</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="56"/> <location filename="../mainwindow.cpp" line="59"/>
<source>Cancel</source> <source>Cancel</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="338"/> <location filename="../mainwindow.cpp" line="374"/>
<source>Save As</source> <source>Save As</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="402"/> <location filename="../mainwindow.cpp" line="437"/>
<source>%1Start downloading %2</source> <source>%1Start downloading %2</source>
<translation>%1 %2</translation> <translation>%1 %2</translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="413"/> <location filename="../mainwindow.cpp" line="448"/>
<source>%1Wait for previous download to complete!</source> <source>%1Wait for previous download to complete!</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="435"/> <location filename="../mainwindow.cpp" line="470"/>
<source>Open</source> <source>Open</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="439"/> <location filename="../mainwindow.cpp" line="474"/>
<source>download finished.</source> <source>download finished.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="439"/> <location filename="../mainwindow.cpp" line="474"/>
<source>Show in file manager?</source> <source>Show in file manager?</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="477"/> <location filename="../mainwindow.cpp" line="512"/>
<source>%1Download canceled!</source> <source>%1Download canceled!</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="482"/> <location filename="../mainwindow.cpp" line="517"/>
<source>%1Load error occurred!</source> <source>%1Load error occurred!</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
</context>
<context>
<name>TitleBarMenu</name>
<message> <message>
<location filename="../mainwindow.cpp" line="48"/> <location filename="../webengineview.cpp" line="82"/>
<source>About</source> <source>View</source>
<translation></translation> <translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="49"/>
<source>Exit</source>
<translation>退</translation>
</message> </message>
</context> </context>
</TS> </TS>

View File

@@ -1,10 +1,22 @@
#include "webenginepage.h" #include "webenginepage.h"
#include <QFile>
#include <QWebEngineScript>
#include <QWebEngineScriptCollection>
#include <QDesktopServices> #include <QDesktopServices>
WebEnginePage::WebEnginePage(QObject *parent) WebEnginePage::WebEnginePage(QObject *parent)
: QWebEnginePage(parent) : QWebEnginePage(parent)
{ {
initScrollBarStyle();
connect(this, &QWebEnginePage::featurePermissionRequested, [&](const QUrl &origin, QWebEnginePage::Feature feature) {
if (feature != QWebEnginePage::Notifications) {
return;
}
setFeaturePermission(origin, feature, QWebEnginePage::PermissionGrantedByUser);
});
} }
WebEnginePage::~WebEnginePage() WebEnginePage::~WebEnginePage()
@@ -30,6 +42,30 @@ QWebEnginePage *WebEnginePage::createWindow(QWebEnginePage::WebWindowType type)
return page; return page;
} }
void WebEnginePage::initScrollBarStyle()
{
//自定义浏览器滚动条样式
QFile file(":/css/webkit-scrollbar.css");
if (file.open(QFile::ReadOnly)) {
QString scrollbarStyleJS = QString("(function() {"
" css = document.createElement('style');"
" css.type = 'text/css';"
" css.id = '%1';"
" document.head.appendChild(css);"
" css.innerText = '%2';"
"})()\n")
.arg("scrollbarStyle")
.arg(QString::fromUtf8(file.readAll()).simplified());
file.close();
QWebEngineScript script;
script.setWorldId(QWebEngineScript::MainWorld);
script.setSourceCode(scrollbarStyleJS);
scripts().insert(script);
runJavaScript(scrollbarStyleJS, QWebEngineScript::ApplicationWorld);
}
}
void WebEnginePage::slotUrlChanged(const QUrl &url) void WebEnginePage::slotUrlChanged(const QUrl &url)
{ {
if (m_currentUrl == url) { if (m_currentUrl == url) {

View File

@@ -16,6 +16,9 @@ public:
protected: protected:
QWebEnginePage *createWindow(WebWindowType type) override; QWebEnginePage *createWindow(WebWindowType type) override;
private:
void initScrollBarStyle();
private slots: private slots:
void slotUrlChanged(const QUrl &url); void slotUrlChanged(const QUrl &url);

View File

@@ -1,13 +1,17 @@
#include "webengineview.h" #include "webengineview.h"
//#include "webengineurlrequestinterceptor.h" //#include "webengineurlrequestinterceptor.h"
#include "application.h"
#include <DGuiApplicationHelper> #include <DGuiApplicationHelper>
#include <DNotifySender>
#include <QWebEngineSettings> #include <QWebEngineSettings>
#include <QWebEngineProfile> #include <QWebEngineProfile>
#include <QLocale> #include <QLocale>
#include <QFileInfo>
DGUI_USE_NAMESPACE DGUI_USE_NAMESPACE
DCORE_USE_NAMESPACE
WebEngineView::WebEngineView(QWidget *parent) WebEngineView::WebEngineView(QWidget *parent)
: QWebEngineView(parent) : QWebEngineView(parent)
@@ -17,6 +21,11 @@ WebEngineView::WebEngineView(QWidget *parent)
// page()->setUrlRequestInterceptor(interceptor); // page()->setUrlRequestInterceptor(interceptor);
// page()->settings()->setAttribute(QWebEngineSettings::WebAttribute::LocalContentCanAccessRemoteUrls, true); // page()->settings()->setAttribute(QWebEngineSettings::WebAttribute::LocalContentCanAccessRemoteUrls, true);
page()->profile()->setHttpAcceptLanguage(QLocale::system().name()); page()->profile()->setHttpAcceptLanguage(QLocale::system().name());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
page()->profile()->setNotificationPresenter([&](std::unique_ptr<QWebEngineNotification> notification) {
WebEngineView::present(notification);
});
#endif
}); });
} }
@@ -25,7 +34,7 @@ void WebEngineView::handleChromiumFlags()
DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::instance()->themeType(); DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::instance()->themeType();
QString env = qgetenv("QTWEBENGINE_CHROMIUM_FLAGS"); QString env = qgetenv("QTWEBENGINE_CHROMIUM_FLAGS");
QStringList flags = env.split(" ", QString::SkipEmptyParts); QStringList flags = env.split(" ", Qt::SkipEmptyParts);
/** /**
* --blink-settings=preferredColorScheme=0 强制 prefers-color-scheme=dark (>= 5.14) * --blink-settings=preferredColorScheme=0 强制 prefers-color-scheme=dark (>= 5.14)
@@ -51,3 +60,40 @@ void WebEngineView::handleChromiumFlags()
qDebug() << Q_FUNC_INFO << "QTWEBENGINE_CHROMIUM_FLAGS=" + qgetenv("QTWEBENGINE_CHROMIUM_FLAGS"); qDebug() << Q_FUNC_INFO << "QTWEBENGINE_CHROMIUM_FLAGS=" + qgetenv("QTWEBENGINE_CHROMIUM_FLAGS");
} }
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
void WebEngineView::present(std::unique_ptr<QWebEngineNotification> &newNotification)
{
qDebug() << Q_FUNC_INFO << "New notification received:" << newNotification->title() << newNotification->message();
QImage image = newNotification->icon();
QString tmpDir = qobject_cast<Application *>(qApp)->mainWindow()->tmpDir();
QString appIcon = tmpDir + "/" + "icon.png";
if (QFileInfo::exists(appIcon)) {
QFile::remove(appIcon);
}
image.save(appIcon, "PNG");
QString summary = newNotification->title();
QString appName = qobject_cast<Application *>(qApp)->mainWindow()->title();
QString appBody = newNotification->message();
quint32 replaceId = 0;
int timeOut = 3000;
QStringList actions = QStringList() << "view" << QObject::tr("View");
QString launchCmd = qobject_cast<Application *>(qApp)->launchParams().join(",");
qDebug() << launchCmd;
QVariantMap hints;
hints.insert("x-deepin-action-view", launchCmd);
DUtil::DNotifySender(summary)
.appName(appName)
.appIcon(appIcon)
.appBody(appBody)
.replaceId(replaceId)
.timeOut(timeOut)
.actions(actions)
.hints(hints)
.call();
}
#endif

View File

@@ -2,6 +2,9 @@
#define WEBENGINEVIEW_H #define WEBENGINEVIEW_H
#include <QWebEngineView> #include <QWebEngineView>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
#include <QWebEngineNotification>
#endif
// class WebEngineUrlRequestInterceptor; // class WebEngineUrlRequestInterceptor;
class WebEngineView : public QWebEngineView class WebEngineView : public QWebEngineView
@@ -12,6 +15,9 @@ public:
explicit WebEngineView(QWidget *parent = nullptr); explicit WebEngineView(QWidget *parent = nullptr);
static void handleChromiumFlags(); static void handleChromiumFlags();
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
static void present(std::unique_ptr<QWebEngineNotification> &newNotification);
#endif
private: private:
// WebEngineUrlRequestInterceptor *interceptor = nullptr; // WebEngineUrlRequestInterceptor *interceptor = nullptr;

View File

@@ -2,16 +2,19 @@
#include "webengineview.h" #include "webengineview.h"
#include "webenginepage.h" #include "webenginepage.h"
#include <QDir>
#include <QWebEngineProfile>
#include <DApplication> #include <DApplication>
DWIDGET_USE_NAMESPACE DWIDGET_USE_NAMESPACE
Widget::Widget(QString szUrl, QWidget *parent) Widget::Widget(QString szUrl, QWidget *parent, QString szTitle)
: QWidget(parent) : QWidget(parent)
, m_webEngineView(new WebEngineView(this)) , m_webEngineView(new WebEngineView(this))
, m_spinner(new DSpinner(this)) , m_spinner(new DSpinner(this))
, mainLayout(new QStackedLayout(this)) , mainLayout(new QStackedLayout(this))
, m_szUrl(szUrl) , m_szUrl(szUrl)
, m_szTitle(szTitle)
{ {
initUI(); initUI();
initConnections(); initConnections();
@@ -54,6 +57,15 @@ void Widget::initUI()
page->setUrl(QUrl()); page->setUrl(QUrl());
if (!m_szUrl.isEmpty()) { if (!m_szUrl.isEmpty()) {
page->setUrl(QUrl(m_szUrl)); page->setUrl(QUrl(m_szUrl));
// 设置新的 cookie 路径以防止冲突https://gitee.com/spark-store-project/spark-web-app-runtime/issues/IA759Q
QString cookiePath = QDir::homePath() +
"/.config/spark-webapp-runtime/" +
QUrl::toPercentEncoding(m_szTitle); // 使用 url 转移以便正确将标题做为文件名
QWebEngineProfile *profile = page->profile();
if (!QDir(cookiePath).exists()) {
QDir().mkpath(cookiePath);
}
profile->setPersistentStoragePath(cookiePath);
} }
QWidget *spinnerWidget = new QWidget(this); QWidget *spinnerWidget = new QWidget(this);

View File

@@ -17,7 +17,7 @@ class Widget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit Widget(QString szUrl = nullptr, QWidget *parent = nullptr); explicit Widget(QString szUrl = nullptr, QWidget *parent = nullptr, QString szTitle = nullptr);
~Widget(); ~Widget();
QWebEnginePage *getPage(); QWebEnginePage *getPage();
@@ -46,6 +46,7 @@ private:
QStackedLayout *mainLayout = nullptr; QStackedLayout *mainLayout = nullptr;
QString m_szUrl; QString m_szUrl;
QString m_szTitle;
}; };
#endif // WIDGET_H #endif // WIDGET_H