Skip to content

Commit 17bd206

Browse files
committed
Improve Features
Support tray icon; Fix few bugs about confliction between fullscreen mode and fixsize option.
1 parent 3b54057 commit 17bd206

File tree

8 files changed

+178
-51
lines changed

8 files changed

+178
-51
lines changed

spark-webapp-runtime/help/help.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ <h3>第二种用法: </h3><br />
2828
-u, --url <url> 设置要打开的目标 URL。默认为空。
2929
-w, --width <width> 设置应用的窗口宽度。默认为 1024。
3030
-H, --height <height> 设置应用的窗口高度。默认为 768。
31+
-T, --tray 启用托盘图标。默认不启用。
3132
--full-screen 以全屏模式运行。默认关闭该功能。
3233
--fix-size 固定窗口大小。默认关闭该功能。
3334
--hide-buttons 隐藏控制按钮。默认关闭该功能。
@@ -64,6 +65,7 @@ <h3>The second usage: </h3><br />
6465
-u, --url <url> The target URL. Default is Blank.
6566
-w, --width <width> The Width of Application. Default is 1024.
6667
-H, --height <height> The Height of Application. Default is 768.
68+
-T, --tray Enable Tray Icon. Default is false.
6769
--full-screen Run in Fullscreen Mode. Default is false.
6870
--fix-size Fix Window Size. Default is false.
6971
--hide-buttons Hide Control Buttons. Default is false.

spark-webapp-runtime/main.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ int main(int argc, char *argv[])
2020
DApplication a(argc, argv);
2121

2222
a.loadTranslator();
23-
2423
a.setAttribute(Qt::AA_UseHighDpiPixmaps);
24+
2525
a.setApplicationVersion(QString::number(CURRENT_VER));
2626
a.setOrganizationName("spark-union"); // 添加组织名称,和商店主体的文件夹同在 ~/.local/share/spark-union 文件夹下
2727
a.setApplicationName("SparkWebAppRuntime"); // 这里不要翻译,否则 ~/.local/share 中文件夹名也会被翻译
@@ -86,6 +86,10 @@ int main(int argc, char *argv[])
8686
QString::number(DEFAULT_HEIGHT));
8787
parser.addOption(optHeight);
8888

89+
QCommandLineOption optTray(QStringList() << "T" << "tray",
90+
QObject::tr("Enable Tray Icon. Default is false."));
91+
parser.addOption(optTray);
92+
8993
QCommandLineOption optFullScreen("full-screen",
9094
QObject::tr("Run in Fullscreen Mode. Default is false."));
9195
parser.addOption(optFullScreen);
@@ -143,6 +147,7 @@ int main(int argc, char *argv[])
143147
QString szUrl = DEFAULT_URL;
144148
int width = DEFAULT_WIDTH;
145149
int height = DEFAULT_HEIGHT;
150+
bool tray = false;
146151
bool fullScreen = false;
147152
bool fixSize = false;
148153
bool hideButtons = false;
@@ -168,6 +173,7 @@ int main(int argc, char *argv[])
168173
szUrl = settings.value("SparkWebAppRuntime/URL", DEFAULT_TITLE).toString();
169174
width = settings.value("SparkWebAppRuntime/Width", DEFAULT_WIDTH).toUInt();
170175
height = settings.value("SparkWebAppRuntime/Height", DEFAULT_HEIGHT).toUInt();
176+
tray = settings.value("SparkWebAppRunTime/Tray", false).toBool();
171177
fullScreen = settings.value("SparkWebAppRunTime/FullScreen", false).toBool();
172178
fixSize = settings.value("SparkWebAppRunTime/FixSize", false).toBool();
173179
hideButtons = settings.value("SparkWebAppRunTime/HideButtons", false).toBool();
@@ -202,6 +208,10 @@ int main(int argc, char *argv[])
202208
height = parser.value(optHeight).toInt();
203209
}
204210

211+
if (parser.isSet(optTray))
212+
{
213+
tray = true;
214+
}
205215
if (parser.isSet(optFullScreen))
206216
{
207217
fullScreen = true;
@@ -238,7 +248,7 @@ int main(int argc, char *argv[])
238248
}
239249
#endif
240250

241-
// 没设置 -p 并且参数个数>1 并且第一个参数不是-开始的
251+
// 没设置 -p 并且参数个数 > 1 并且第一个参数不是 - 开始的
242252
if (!parser.isSet(optParser) && argc > 1 && !QString(argv[1]).startsWith("-"))
243253
{
244254
// 按照固定顺序级别最优先
@@ -261,35 +271,39 @@ int main(int argc, char *argv[])
261271

262272
if (argc > 5)
263273
{
264-
fullScreen = true;
274+
tray = true;
265275
}
266276
if (argc > 6)
267277
{
268-
fixSize = true;
278+
fullScreen = true;
269279
}
270280
if (argc > 7)
281+
{
282+
fixSize = true;
283+
}
284+
if (argc > 8)
271285
{
272286
hideButtons = true;
273287
}
274288

275-
if (argc > 8)
289+
if (argc > 9)
276290
{
277291
szIcon = QString(argv[7]);
278292
}
279-
if (argc > 9)
293+
if (argc > 10)
280294
{
281295
szDesc = QString("%1<br/><br/>%2").arg(QString(argv[8])).arg(szDefaultDesc);
282296
}
283-
if (argc > 10)
297+
if (argc > 11)
284298
{
285299
szRootPath = QString(argv[9]);
286300
}
287-
if (argc > 11)
301+
if (argc > 12)
288302
{
289303
u16Port = QString(argv[10]).toUInt();
290304
}
291305
#if SSL_SERVER
292-
if (argc > 12)
306+
if (argc > 13)
293307
{
294308
u16sslPort = QString(argv[11]).toUInt();
295309
}
@@ -298,10 +312,12 @@ int main(int argc, char *argv[])
298312

299313
if(fixSize)
300314
{
301-
fullScreen = false; // 固定窗口大小时禁用全屏模式,避免标题栏按钮 BUG
315+
fullScreen = false; // 固定窗口大小时禁用全屏模式,避免标题栏按钮 BUG
302316
}
303317

304-
MainWindow w(szTitle, szUrl, width, height, fullScreen, fixSize, hideButtons, dialog);
318+
a.setQuitOnLastWindowClosed(!tray); // 启用托盘时,退出程序后服务不终止
319+
320+
MainWindow w(szTitle, szUrl, width, height, tray, fullScreen, fixSize, hideButtons, dialog);
305321

306322
#if SSL_SERVER
307323
if (!szRootPath.isEmpty() && u16Port > 0 && u16sslPort > 0)

spark-webapp-runtime/mainwindow.cpp

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ MainWindow::MainWindow(QString szTitle,
1919
QString szUrl,
2020
int nWidth,
2121
int nHeight,
22+
bool tray,
2223
bool nFullScreen,
2324
bool nFixSize,
2425
bool nHideButtons,
@@ -27,19 +28,27 @@ MainWindow::MainWindow(QString szTitle,
2728
: DMainWindow(parent)
2829
, m_widget(new Widget(szUrl))
2930
, m_dialog(dialog)
31+
, m_tray(new QSystemTrayIcon)
3032
, btnBack(new DToolButton(titlebar()))
3133
, btnForward(new DToolButton(titlebar()))
3234
, btnRefresh(new DToolButton(titlebar()))
3335
, m_menu(new QMenu)
3436
, m_fullScreen(new QAction(tr("Full Screen")))
3537
, m_fixSize(new QAction(tr("Fix Size")))
3638
, m_hideButtons(new QAction(tr("Hide Buttons")))
39+
, t_menu(new QMenu)
40+
, t_show(new QAction(tr("Show MainWindow")))
41+
, t_about(new QAction(tr("About")))
42+
, t_exit(new QAction(tr("Exit")))
3743
, bar(new DProgressBar)
3844
, message(new DFloatingMessage(DFloatingMessage::ResidentType))
3945
, process(new QProcess)
46+
, mtray(tray)
47+
, mFixSize(nFixSize)
4048
, m_width(nWidth)
4149
, m_height(nHeight)
4250
{
51+
/* 初始化 MainWindow */
4352
setCentralWidget(m_widget);
4453
centralWidget()->layout()->setContentsMargins(0, 0, 0, 0);
4554

@@ -72,17 +81,36 @@ MainWindow::MainWindow(QString szTitle,
7281
m_hideButtons->setCheckable(true);
7382
m_hideButtons->setChecked(nHideButtons);
7483
m_hideButtons->setDisabled(nHideButtons);
75-
m_menu->addAction(m_fullScreen);
76-
m_menu->addAction(m_fixSize);
77-
m_menu->addAction(m_hideButtons);
84+
/* 命令行设置参数后 GUI 中隐藏对应选项 */
85+
if(!nFixSize)
86+
{
87+
m_menu->addAction(m_fullScreen);
88+
m_menu->addAction(m_fixSize);
89+
}
90+
if(!nHideButtons)
91+
{
92+
m_menu->addAction(m_hideButtons);
93+
}
7894
titlebar()->setMenu(m_menu);
7995

8096
titlebar()->setAutoHideOnFullscreen(true);
8197

82-
fullScreen();
8398
fixSize();
8499
hideButtons();
85100

101+
/* 初始化 TrayIcon */
102+
t_menu->addAction(t_show);
103+
t_menu->addAction(t_about);
104+
t_menu->addAction(t_exit);
105+
m_tray->setContextMenu(t_menu);
106+
m_tray->setToolTip(szTitle);
107+
m_tray->setIcon(QIcon(":/images/spark-webapp-runtime.svg"));
108+
109+
if(tray)
110+
{
111+
m_tray->show(); // 启用托盘时显示
112+
}
113+
86114
connect(btnBack, &DToolButton::clicked, this, [&]()
87115
{
88116
m_widget->goBack();
@@ -109,6 +137,22 @@ MainWindow::MainWindow(QString szTitle,
109137
hideButtons();
110138
});
111139

140+
connect(t_show, &QAction::triggered, this, [=]()
141+
{
142+
this->activateWindow();
143+
fixSize();
144+
});
145+
connect(t_about, &QAction::triggered, this, [=]()
146+
{
147+
m_dialog->activateWindow();
148+
m_dialog->show();
149+
});
150+
connect(t_exit, &QAction::triggered, this, [=]()
151+
{
152+
exit(0);
153+
});
154+
connect(m_tray, &QSystemTrayIcon::activated, this, &MainWindow::trayIconActivated);
155+
112156
connect(m_widget->getPage()->profile(), &QWebEngineProfile::downloadRequested, this, &MainWindow::on_downloadStart);
113157
}
114158

@@ -117,6 +161,7 @@ MainWindow::~MainWindow()
117161
emit sigQuit();
118162
delete m_widget;
119163
delete m_dialog;
164+
delete m_tray;
120165
}
121166

122167
void MainWindow::setIcon(QString szIconPath)
@@ -126,6 +171,7 @@ void MainWindow::setIcon(QString szIconPath)
126171
{
127172
titlebar()->setIcon(QIcon(szIconPath));
128173
setWindowIcon(QIcon(szIconPath));
174+
m_tray->setIcon(QIcon(szIconPath));
129175
qDebug() << szIconPath << "is Set!";
130176
}
131177
else
@@ -138,11 +184,19 @@ void MainWindow::fullScreen()
138184
{
139185
if(m_fullScreen->isChecked())
140186
{
187+
m_fixSize->setChecked(false);
188+
m_fixSize->setDisabled(true);
189+
m_menu->update();
141190
showFullScreen();
142191
DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-information").pixmap(64, 64), QString(tr("%1Fullscreen Mode")).arg(" "));
143192
}
144193
else
145194
{
195+
if(!mFixSize)
196+
{
197+
m_fixSize->setDisabled(false); // 命令行参数没有固定窗口大小时,窗口模式下允许手动选择固定窗口大小
198+
}
199+
m_menu->update();
146200
showNormal();
147201
DMessageManager::instance()->sendMessage(this, QIcon::fromTheme("dialog-information").pixmap(64, 64), QString(tr("%1Windowed Mode")).arg(" "));
148202
}
@@ -152,13 +206,20 @@ void MainWindow::fixSize()
152206
{
153207
if(m_fixSize->isChecked())
154208
{
155-
setFixedSize(this->width(), this->height());
209+
m_fullScreen->setChecked(false);
210+
m_fullScreen->setDisabled(true);
211+
m_menu->update();
212+
setFixedSize(this->size());
213+
/* 存在 BUG: 启用托盘图标后,若手动选择固定窗口大小,并且关闭窗口,再次打开时会丢失最大化按钮,且无法恢复。 */
156214
}
157215
else
158216
{
217+
m_fullScreen->setDisabled(false);
218+
m_menu->update();
159219
setMinimumSize(m_width, m_height);
160220
setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
161221
}
222+
fullScreen();
162223
}
163224

164225
void MainWindow::hideButtons()
@@ -182,24 +243,23 @@ QString MainWindow::saveAs(QString fileName)
182243
QString saveFile = QFileDialog::getSaveFileName(this, tr("Save As"), QDir::homePath() + "/Downloads/" + fileName);
183244
if(!saveFile.isEmpty())
184245
{
185-
// 判断上层目录是否可写入
186-
if(QFileInfo(QFileInfo(saveFile).absolutePath()).permissions().testFlag(QFile::WriteUser))
246+
if(QFileInfo(QFileInfo(saveFile).absolutePath()).permissions().testFlag(QFile::WriteUser)) // 判断上层目录是否可写入
187247
{
188248
return saveFile;
189249
}
190250
else
191251
{
192-
saveAs(fileName);
252+
return saveAs(fileName);
193253
}
194254
}
195255
return nullptr;
196256
}
197257

198258
void MainWindow::keyPressEvent(QKeyEvent *event)
199259
{
200-
if(m_fixSize->isEnabled())
260+
if(!m_fixSize->isChecked()) // 固定窗口大小时禁止全屏
201261
{
202-
if(event->key() == Qt::Key_F11)
262+
if(event->key() == Qt::Key_F11) // 绑定键盘快捷键 F11
203263
{
204264
m_fullScreen->trigger();
205265
m_menu->update();
@@ -210,23 +270,41 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
210270

211271
void MainWindow::closeEvent(QCloseEvent *event)
212272
{
213-
m_dialog->close();
273+
if(!mtray)
274+
{
275+
m_dialog->close(); // 不启用托盘时,关闭主窗口则关闭关于窗口
276+
}
214277
event->accept();
215278
}
216279

280+
void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
281+
{
282+
switch(reason)
283+
{
284+
/* 响应托盘点击事件 */
285+
case QSystemTrayIcon::Trigger:
286+
this->activateWindow();
287+
fixSize();
288+
break;
289+
default:
290+
break;
291+
}
292+
}
293+
217294
void MainWindow::on_downloadStart(QWebEngineDownloadItem *item)
218295

219296
{
220297
QString fileName = QFileInfo(item->path()).fileName();
221-
if(saveAs(fileName).isEmpty())
298+
QString filePath = saveAs(fileName);
299+
if(filePath.isEmpty())
222300
{
223301
return;
224302
}
225-
item->setPath(saveAs(fileName));
226-
QString filePath = QFileInfo(item->path()).absoluteFilePath();
303+
item->setPath(filePath);
304+
filePath = QFileInfo(item->path()).absoluteFilePath();
227305

228306
connect(item, &QWebEngineDownloadItem::downloadProgress, this, &MainWindow::on_downloadProgress);
229-
connect(item, &QWebEngineDownloadItem::finished, this, [=]
307+
connect(item, &QWebEngineDownloadItem::finished, this, [=]()
230308
{
231309
on_downloadFinish(filePath);
232310
});
@@ -263,7 +341,7 @@ void MainWindow::on_downloadFinish(QString filePath)
263341
message->setWidget(button);
264342
DMessageManager::instance()->sendMessage(this, message);
265343

266-
connect(button, &DPushButton::clicked, this, [=]
344+
connect(button, &DPushButton::clicked, this, [=]()
267345
{
268346
process->start("dde-file-manager --show-item " + filePath);
269347
message->hide();

0 commit comments

Comments
 (0)