Implement "Disable tray" option (#482)

* feat: implement "Disable tray" option

Add a "Disable Tray" checkbox, with its state saved and loaded to
the data store. The state of the tray icon is managed by this
checkbox at runtime. Depending on the visibility of the tray icon,
the application will either minimize to the tray or close completely
upon the close event.

* feat: add tooltip and translations for "Disable tray" option

* fix: apply "Disable tray" only after pressing OK
This commit is contained in:
Ilia Grigoriev 2025-07-11 19:15:57 +03:00 committed by GitHub
parent 7d0f33eb4d
commit 80466c7aef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 61 additions and 1 deletions

View File

@ -62,6 +62,7 @@ namespace NekoGui {
// Misc // Misc
QString log_level = "info"; QString log_level = "info";
QString test_latency_url = "http://cp.cloudflare.com/"; QString test_latency_url = "http://cp.cloudflare.com/";
bool disable_tray = false;
int test_concurrent = 10; int test_concurrent = 10;
bool disable_traffic_stats = false; bool disable_traffic_stats = false;
int current_group = 0; // group id int current_group = 0; // group id

View File

@ -27,6 +27,7 @@ private:
struct { struct {
QString custom_inbound; QString custom_inbound;
bool needRestart = false; bool needRestart = false;
bool updateDisableTray = false;
} CACHE; } CACHE;
private slots: private slots:

View File

@ -179,6 +179,28 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="horizontalGroupBox_1_5">
<layout class="QHBoxLayout" name="horizontalLayout_1_5">
<item>
<widget class="QCheckBox" name="disable_tray">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Disable tray</string>
</property>
<property name="toolTip">
<string>Prevents the app from minimizing to the tray when the window is closed. The app will exit instead</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QFrame" name="frame"> <widget class="QFrame" name="frame">
<property name="frameShape"> <property name="frameShape">

View File

@ -141,6 +141,14 @@ For nekobox_core, this rewrites the underlying(localhost) DNS in Tun Mode, norma
<source>Latency Test URL</source> <source>Latency Test URL</source>
<translation type="unfinished">آدرس تست تاخیر</translation> <translation type="unfinished">آدرس تست تاخیر</translation>
</message> </message>
<message>
<source>Disable tray</source>
<translation>غیرفعالسازی سینی</translation>
</message>
<message>
<source>Prevents the app from minimizing to the tray when the window is closed. The app will exit instead</source>
<translation>از به حداقل بردن برنامه در سینی سیستم هنگام بستن پنجره جلوگیری میکند. در عوض برنامه خارج میشود</translation>
</message>
<message> <message>
<source>Automatic update</source> <source>Automatic update</source>
<translation type="unfinished">آپدیت اتوماتیک</translation> <translation type="unfinished">آپدیت اتوماتیک</translation>

View File

@ -39,6 +39,14 @@
<source>Concurrent</source> <source>Concurrent</source>
<translation>Параллельно</translation> <translation>Параллельно</translation>
</message> </message>
<message>
<source>Disable tray</source>
<translation>Отключить трей</translation>
</message>
<message>
<source>Prevents the app from minimizing to the tray when the window is closed. The app will exit instead</source>
<translation>Предотвращает сворачивание приложения в системный трей при закрытии окна. Вместо этого приложение завершит работу</translation>
</message>
<message> <message>
<source>Style</source> <source>Style</source>
<translation>Интерфейс</translation> <translation>Интерфейс</translation>

View File

@ -141,6 +141,14 @@ For nekobox_core, this rewrites the underlying(localhost) DNS in Tun Mode, norma
<source>Latency Test URL</source> <source>Latency Test URL</source>
<translation> URL</translation> <translation> URL</translation>
</message> </message>
<message>
<source>Disable tray</source>
<translation></translation>
</message>
<message>
<source>Prevents the app from minimizing to the tray when the window is closed. The app will exit instead</source>
<translation>退</translation>
</message>
<message> <message>
<source>Automatic update</source> <source>Automatic update</source>
<translation></translation> <translation></translation>

View File

@ -241,6 +241,7 @@ namespace NekoGui {
DataStore::DataStore() : JsonStore() { DataStore::DataStore() : JsonStore() {
_add(new configItem("user_agent2", &user_agent, itemType::string)); _add(new configItem("user_agent2", &user_agent, itemType::string));
_add(new configItem("test_url", &test_latency_url, itemType::string)); _add(new configItem("test_url", &test_latency_url, itemType::string));
_add(new configItem("disable_tray", &disable_tray, itemType::boolean));
_add(new configItem("current_group", &current_group, itemType::integer)); _add(new configItem("current_group", &current_group, itemType::integer));
_add(new configItem("inbound_address", &inbound_address, itemType::string)); _add(new configItem("inbound_address", &inbound_address, itemType::string));
_add(new configItem("inbound_socks_port", &inbound_socks_port, itemType::integer)); _add(new configItem("inbound_socks_port", &inbound_socks_port, itemType::integer));

View File

@ -335,7 +335,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
trayMenu->addAction(ui->actionRestart_Proxy); trayMenu->addAction(ui->actionRestart_Proxy);
trayMenu->addAction(ui->actionRestart_Program); trayMenu->addAction(ui->actionRestart_Program);
trayMenu->addAction(ui->menu_exit); trayMenu->addAction(ui->menu_exit);
tray->show(); tray->setVisible(!NekoGui::dataStore->disable_tray);
tray->setContextMenu(trayMenu); tray->setContextMenu(trayMenu);
connect(tray, &QSystemTrayIcon::activated, qApp, [=](QSystemTrayIcon::ActivationReason reason) { connect(tray, &QSystemTrayIcon::activated, qApp, [=](QSystemTrayIcon::ActivationReason reason) {
if (reason == QSystemTrayIcon::Trigger) { if (reason == QSystemTrayIcon::Trigger) {
@ -524,6 +524,8 @@ void MainWindow::closeEvent(QCloseEvent *event) {
if (tray->isVisible()) { if (tray->isVisible()) {
hide(); hide();
event->ignore(); event->ignore();
} else {
on_menu_exit_triggered();
} }
} }
@ -601,6 +603,9 @@ void MainWindow::dialog_message_impl(const QString &sender, const QString &info)
refresh_status(); refresh_status();
} }
if (info.contains("UpdateDataStore")) { if (info.contains("UpdateDataStore")) {
if (info.contains("UpdateDisableTray")) {
tray->setVisible(!NekoGui::dataStore->disable_tray);
}
auto suggestRestartProxy = NekoGui::dataStore->Save(); auto suggestRestartProxy = NekoGui::dataStore->Save();
if (info.contains("RouteChanged")) { if (info.contains("RouteChanged")) {
NekoGui::dataStore->routing->Save(); NekoGui::dataStore->routing->Save();

View File

@ -33,12 +33,16 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
D_LOAD_INT(inbound_socks_port) D_LOAD_INT(inbound_socks_port)
D_LOAD_INT(test_concurrent) D_LOAD_INT(test_concurrent)
D_LOAD_STRING(test_latency_url) D_LOAD_STRING(test_latency_url)
D_LOAD_BOOL(disable_tray)
ui->speedtest_mode->setCurrentIndex(NekoGui::dataStore->speed_test_mode); ui->speedtest_mode->setCurrentIndex(NekoGui::dataStore->speed_test_mode);
ui->simple_down_url->setText(NekoGui::dataStore->simple_dl_url); ui->simple_down_url->setText(NekoGui::dataStore->simple_dl_url);
connect(ui->custom_inbound_edit, &QPushButton::clicked, this, [=] { connect(ui->custom_inbound_edit, &QPushButton::clicked, this, [=] {
C_EDIT_JSON_ALLOW_EMPTY(custom_inbound) C_EDIT_JSON_ALLOW_EMPTY(custom_inbound)
}); });
connect(ui->disable_tray, &QCheckBox::stateChanged, this, [=](const bool &) {
CACHE.updateDisableTray = true;
});
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
ui->proxy_scheme_box->hide(); ui->proxy_scheme_box->hide();
@ -170,6 +174,7 @@ void DialogBasicSettings::accept() {
D_SAVE_INT(inbound_socks_port) D_SAVE_INT(inbound_socks_port)
D_SAVE_INT(test_concurrent) D_SAVE_INT(test_concurrent)
D_SAVE_STRING(test_latency_url) D_SAVE_STRING(test_latency_url)
D_SAVE_BOOL(disable_tray)
NekoGui::dataStore->proxy_scheme = ui->proxy_scheme->currentText().toLower(); NekoGui::dataStore->proxy_scheme = ui->proxy_scheme->currentText().toLower();
NekoGui::dataStore->speed_test_mode = ui->speedtest_mode->currentIndex(); NekoGui::dataStore->speed_test_mode = ui->speedtest_mode->currentIndex();
NekoGui::dataStore->simple_dl_url = ui->simple_down_url->text(); NekoGui::dataStore->simple_dl_url = ui->simple_down_url->text();
@ -227,6 +232,7 @@ void DialogBasicSettings::accept() {
QStringList str{"UpdateDataStore"}; QStringList str{"UpdateDataStore"};
if (CACHE.needRestart) str << "NeedRestart"; if (CACHE.needRestart) str << "NeedRestart";
if (CACHE.updateDisableTray) str << "UpdateDisableTray";
MW_dialog_message(Dialog_DialogBasicSettings, str.join(",")); MW_dialog_message(Dialog_DialogBasicSettings, str.join(","));
QDialog::accept(); QDialog::accept();
} }