From 80466c7aef10b300ec80a3ac6de76ebce5b4ca4a Mon Sep 17 00:00:00 2001 From: Ilia Grigoriev Date: Fri, 11 Jul 2025 19:15:57 +0300 Subject: [PATCH] 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 --- include/global/NekoGui_DataStore.hpp | 1 + include/ui/setting/dialog_basic_settings.h | 1 + include/ui/setting/dialog_basic_settings.ui | 22 +++++++++++++++++++++ res/translations/fa_IR.ts | 8 ++++++++ res/translations/ru_RU.ts | 8 ++++++++ res/translations/zh_CN.ts | 8 ++++++++ src/global/NekoGui.cpp | 1 + src/ui/mainwindow.cpp | 7 ++++++- src/ui/setting/dialog_basic_settings.cpp | 6 ++++++ 9 files changed, 61 insertions(+), 1 deletion(-) diff --git a/include/global/NekoGui_DataStore.hpp b/include/global/NekoGui_DataStore.hpp index 63b8139..64ff79a 100644 --- a/include/global/NekoGui_DataStore.hpp +++ b/include/global/NekoGui_DataStore.hpp @@ -62,6 +62,7 @@ namespace NekoGui { // Misc QString log_level = "info"; QString test_latency_url = "http://cp.cloudflare.com/"; + bool disable_tray = false; int test_concurrent = 10; bool disable_traffic_stats = false; int current_group = 0; // group id diff --git a/include/ui/setting/dialog_basic_settings.h b/include/ui/setting/dialog_basic_settings.h index fbc7208..38b8fc4 100644 --- a/include/ui/setting/dialog_basic_settings.h +++ b/include/ui/setting/dialog_basic_settings.h @@ -27,6 +27,7 @@ private: struct { QString custom_inbound; bool needRestart = false; + bool updateDisableTray = false; } CACHE; private slots: diff --git a/include/ui/setting/dialog_basic_settings.ui b/include/ui/setting/dialog_basic_settings.ui index 7f69653..c6ea295 100644 --- a/include/ui/setting/dialog_basic_settings.ui +++ b/include/ui/setting/dialog_basic_settings.ui @@ -179,6 +179,28 @@ + + + + + + + + 0 + 0 + + + + Disable tray + + + Prevents the app from minimizing to the tray when the window is closed. The app will exit instead + + + + + + diff --git a/res/translations/fa_IR.ts b/res/translations/fa_IR.ts index e2a87b1..ed950fd 100644 --- a/res/translations/fa_IR.ts +++ b/res/translations/fa_IR.ts @@ -141,6 +141,14 @@ For nekobox_core, this rewrites the underlying(localhost) DNS in Tun Mode, norma Latency Test URL آدرس تست تاخیر + + Disable tray + غیرفعال‌سازی سینی + + + Prevents the app from minimizing to the tray when the window is closed. The app will exit instead + از به حداقل بردن برنامه در سینی سیستم هنگام بستن پنجره جلوگیری می‌کند. در عوض برنامه خارج می‌شود + Automatic update آپدیت اتوماتیک diff --git a/res/translations/ru_RU.ts b/res/translations/ru_RU.ts index 9f77ffd..2bd096d 100644 --- a/res/translations/ru_RU.ts +++ b/res/translations/ru_RU.ts @@ -39,6 +39,14 @@ Concurrent Параллельно + + Disable tray + Отключить трей + + + Prevents the app from minimizing to the tray when the window is closed. The app will exit instead + Предотвращает сворачивание приложения в системный трей при закрытии окна. Вместо этого приложение завершит работу + Style Интерфейс diff --git a/res/translations/zh_CN.ts b/res/translations/zh_CN.ts index 7d3c038..8374681 100644 --- a/res/translations/zh_CN.ts +++ b/res/translations/zh_CN.ts @@ -141,6 +141,14 @@ For nekobox_core, this rewrites the underlying(localhost) DNS in Tun Mode, norma Latency Test URL 延迟测试 URL + + Disable tray + 禁用托盘 + + + Prevents the app from minimizing to the tray when the window is closed. The app will exit instead + 当窗口关闭时,阻止应用程序最小化到系统托盘。应用程序将退出 + Automatic update 自动更新 diff --git a/src/global/NekoGui.cpp b/src/global/NekoGui.cpp index 81ef61e..5e4b0ce 100644 --- a/src/global/NekoGui.cpp +++ b/src/global/NekoGui.cpp @@ -241,6 +241,7 @@ namespace NekoGui { DataStore::DataStore() : JsonStore() { _add(new configItem("user_agent2", &user_agent, 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", ¤t_group, itemType::integer)); _add(new configItem("inbound_address", &inbound_address, itemType::string)); _add(new configItem("inbound_socks_port", &inbound_socks_port, itemType::integer)); diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index d27a31d..d738d48 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -335,7 +335,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi trayMenu->addAction(ui->actionRestart_Proxy); trayMenu->addAction(ui->actionRestart_Program); trayMenu->addAction(ui->menu_exit); - tray->show(); + tray->setVisible(!NekoGui::dataStore->disable_tray); tray->setContextMenu(trayMenu); connect(tray, &QSystemTrayIcon::activated, qApp, [=](QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::Trigger) { @@ -524,6 +524,8 @@ void MainWindow::closeEvent(QCloseEvent *event) { if (tray->isVisible()) { hide(); event->ignore(); + } else { + on_menu_exit_triggered(); } } @@ -601,6 +603,9 @@ void MainWindow::dialog_message_impl(const QString &sender, const QString &info) refresh_status(); } if (info.contains("UpdateDataStore")) { + if (info.contains("UpdateDisableTray")) { + tray->setVisible(!NekoGui::dataStore->disable_tray); + } auto suggestRestartProxy = NekoGui::dataStore->Save(); if (info.contains("RouteChanged")) { NekoGui::dataStore->routing->Save(); diff --git a/src/ui/setting/dialog_basic_settings.cpp b/src/ui/setting/dialog_basic_settings.cpp index 92972f2..0ff5e1e 100644 --- a/src/ui/setting/dialog_basic_settings.cpp +++ b/src/ui/setting/dialog_basic_settings.cpp @@ -33,12 +33,16 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent) D_LOAD_INT(inbound_socks_port) D_LOAD_INT(test_concurrent) D_LOAD_STRING(test_latency_url) + D_LOAD_BOOL(disable_tray) ui->speedtest_mode->setCurrentIndex(NekoGui::dataStore->speed_test_mode); ui->simple_down_url->setText(NekoGui::dataStore->simple_dl_url); connect(ui->custom_inbound_edit, &QPushButton::clicked, this, [=] { C_EDIT_JSON_ALLOW_EMPTY(custom_inbound) }); + connect(ui->disable_tray, &QCheckBox::stateChanged, this, [=](const bool &) { + CACHE.updateDisableTray = true; + }); #ifndef Q_OS_WIN ui->proxy_scheme_box->hide(); @@ -170,6 +174,7 @@ void DialogBasicSettings::accept() { D_SAVE_INT(inbound_socks_port) D_SAVE_INT(test_concurrent) D_SAVE_STRING(test_latency_url) + D_SAVE_BOOL(disable_tray) NekoGui::dataStore->proxy_scheme = ui->proxy_scheme->currentText().toLower(); NekoGui::dataStore->speed_test_mode = ui->speedtest_mode->currentIndex(); NekoGui::dataStore->simple_dl_url = ui->simple_down_url->text(); @@ -227,6 +232,7 @@ void DialogBasicSettings::accept() { QStringList str{"UpdateDataStore"}; if (CACHE.needRestart) str << "NeedRestart"; + if (CACHE.updateDisableTray) str << "UpdateDisableTray"; MW_dialog_message(Dialog_DialogBasicSettings, str.join(",")); QDialog::accept(); }