From 530e2a1feb823d7f967b5220ba932ab9cad1158d Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 14 Jan 2025 20:43:14 +0400 Subject: [PATCH] Support background-run options on Linux. --- Telegram/Resources/langs/lang.strings | 3 + Telegram/SourceFiles/core/core_settings.cpp | 13 ++- Telegram/SourceFiles/core/core_settings.h | 21 +++-- .../settings/settings_advanced.cpp | 80 +++++++++++++++++-- .../SourceFiles/settings/settings_advanced.h | 3 + Telegram/SourceFiles/window/main_window.cpp | 33 ++++---- 6 files changed, 117 insertions(+), 36 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 6a25c3e92..1080b4f1f 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -604,6 +604,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_update_fail" = "Update check failed :("; "lng_settings_workmode_tray" = "Show tray icon"; "lng_settings_workmode_window" = "Show taskbar icon"; +"lng_settings_window_close" = "When window closed"; +"lng_settings_run_in_background" = "Run in the background"; +"lng_settings_quit_on_close" = "Quit the application"; "lng_settings_close_to_taskbar" = "Close to taskbar"; "lng_settings_monochrome_icon" = "Use monochrome icon"; "lng_settings_window_system" = "Window title bar"; diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp index 3090ec1a0..60eac9de3 100644 --- a/Telegram/SourceFiles/core/core_settings.cpp +++ b/Telegram/SourceFiles/core/core_settings.cpp @@ -337,7 +337,7 @@ QByteArray Settings::serialize() const { << _photoEditorBrush << qint32(_groupCallNoiseSuppression ? 1 : 0) << qint32(SerializePlaybackSpeed(_voicePlaybackSpeed)) - << qint32(_closeToTaskbar.current() ? 1 : 0) + << qint32(_closeBehavior) << _customDeviceModel.current() << qint32(_playerRepeatMode.current()) << qint32(_playerOrderMode.current()) @@ -493,7 +493,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { QByteArray proxy; qint32 hiddenGroupCallTooltips = qint32(_hiddenGroupCallTooltips.value()); QByteArray photoEditorBrush = _photoEditorBrush; - qint32 closeToTaskbar = _closeToTaskbar.current() ? 1 : 0; + qint32 closeBehavior = qint32(_closeBehavior); QString customDeviceModel = _customDeviceModel.current(); qint32 playerRepeatMode = static_cast(_playerRepeatMode.current()); qint32 playerOrderMode = static_cast(_playerOrderMode.current()); @@ -689,7 +689,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { stream >> voicePlaybackSpeed; } if (!stream.atEnd()) { - stream >> closeToTaskbar; + stream >> closeBehavior; } if (!stream.atEnd()) { stream >> customDeviceModel; @@ -998,7 +998,12 @@ void Settings::addFromSerialized(const QByteArray &serialized) { : Tooltip(0)); }(); _photoEditorBrush = photoEditorBrush; - _closeToTaskbar = (closeToTaskbar == 1); + const auto uncheckedCloseBehavior = static_cast(closeBehavior); + switch (uncheckedCloseBehavior) { + case CloseBehavior::CloseToTaskbar: + case CloseBehavior::RunInBackground: + case CloseBehavior::Quit: _closeBehavior = uncheckedCloseBehavior; break; + } _customDeviceModel = customDeviceModel; _accountsOrder = accountsOrder; const auto uncheckedPlayerRepeatMode = static_cast(playerRepeatMode); diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h index 87fb383f4..91da7945a 100644 --- a/Telegram/SourceFiles/core/core_settings.h +++ b/Telegram/SourceFiles/core/core_settings.h @@ -109,6 +109,11 @@ public: TrayOnly = 1, WindowOnly = 2, }; + enum class CloseBehavior { + Quit = 0, + CloseToTaskbar = 1, + RunInBackground = 2, + }; static constexpr auto kDefaultVolume = 0.9; @@ -745,17 +750,11 @@ public: _hiddenGroupCallTooltips |= value; } - void setCloseToTaskbar(bool value) { - _closeToTaskbar = value; + void setCloseBehavior(CloseBehavior value) { + _closeBehavior = value; } - [[nodiscard]] bool closeToTaskbar() const { - return _closeToTaskbar.current(); - } - [[nodiscard]] rpl::producer closeToTaskbarValue() const { - return _closeToTaskbar.value(); - } - [[nodiscard]] rpl::producer closeToTaskbarChanges() const { - return _closeToTaskbar.changes(); + [[nodiscard]] CloseBehavior closeBehavior() const { + return _closeBehavior; } void setTrayIconMonochrome(bool value) { _trayIconMonochrome = value; @@ -1042,7 +1041,7 @@ private: bool _disableOpenGL = false; rpl::variable _workMode = WorkMode::WindowAndTray; base::flags _hiddenGroupCallTooltips; - rpl::variable _closeToTaskbar = false; + CloseBehavior _closeBehavior = CloseBehavior::Quit; rpl::variable _trayIconMonochrome = true; rpl::variable _customDeviceModel; rpl::variable _playerRepeatMode; diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp index fcd2438cf..1c134f0a5 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced.cpp @@ -578,11 +578,14 @@ void SetupSystemIntegrationContent( #endif // Q_OS_MAC if (!Platform::RunInBackground()) { + using Behavior = Core::Settings::CloseBehavior; const auto closeToTaskbar = addSlidingCheckbox( tr::lng_settings_close_to_taskbar(), - settings->closeToTaskbar()); + settings->closeBehavior() == Behavior::CloseToTaskbar); - const auto closeToTaskbarShown = std::make_shared>(false); + const auto closeToTaskbarShown = std::make_shared< + rpl::variable + >(false); settings->workModeValue( ) | rpl::start_with_next([=](WorkMode workMode) { *closeToTaskbarShown = !Core::App().tray().has(); @@ -590,12 +593,16 @@ void SetupSystemIntegrationContent( closeToTaskbar->toggleOn(closeToTaskbarShown->value()); closeToTaskbar->entity()->checkedChanges( - ) | rpl::filter([=](bool checked) { - return (checked != settings->closeToTaskbar()); - }) | rpl::start_with_next([=](bool checked) { - settings->setCloseToTaskbar(checked); + ) | rpl::map([=](bool checked) { + return checked ? Behavior::CloseToTaskbar : Behavior::Quit; + }) | rpl::filter([=](Behavior value) { + return (settings->closeBehavior() != value); + }) | rpl::start_with_next([=](Behavior value) { + settings->setCloseBehavior(value); Local::writeSettings(); }, closeToTaskbar->lifetime()); + } else if (!Platform::IsMac()) { + } if (Platform::AutostartSupported() && controller) { @@ -958,6 +965,66 @@ void SetupWindowTitle( AddSkip(container); } +void SetupWindowCloseBehavior( + not_null controller, + not_null container) { + if (Platform::IsMac() || !Platform::RunInBackground()) { + return; + } + const auto wrap = container->add( + object_ptr>( + container, + object_ptr(container))); + const auto inner = wrap->entity(); + AddDivider(inner); + AddSkip(inner); + AddSubsectionTitle(inner, tr::lng_settings_window_close()); + + const auto settings = &Core::App().settings(); + using Behavior = Core::Settings::CloseBehavior; + const auto group = std::make_shared>( + settings->closeBehavior()); + const auto add = [&](Behavior value, const QString &label) { + inner->add( + object_ptr>( + inner, + group, + value, + label, + st::settingsSendType), + st::settingsSendTypePadding); + }; + + add( + Behavior::RunInBackground, + tr::lng_settings_run_in_background(tr::now)); + add( + Behavior::CloseToTaskbar, + tr::lng_settings_close_to_taskbar(tr::now)); + add( + Behavior::Quit, + tr::lng_settings_quit_on_close(tr::now)); + + group->value() | rpl::filter([=](Behavior value) { + return (value != settings->closeBehavior()); + }) | rpl::start_with_next([=](Behavior value) { + settings->setCloseBehavior(value); + Local::writeSettings(); + }, inner->lifetime()); + + AddSkip(inner); + + if (!Platform::TrayIconSupported()) { + wrap->toggle(true, anim::type::instant); + } else { + wrap->toggleOn(Core::App().settings().workModeValue( + ) | rpl::map([=](Core::Settings::WorkMode mode) { + return (mode == Core::Settings::WorkMode::WindowOnly); + }) | rpl::distinct_until_changed(), anim::type::normal); + wrap->finishAnimating(); + } +} + void SetupSystemIntegration( not_null controller, not_null container) { @@ -1006,6 +1073,7 @@ void Advanced::setupContent(not_null controller) { SetupDataStorage(controller, content); SetupAutoDownload(controller, content); SetupWindowTitle(controller, content); + SetupWindowCloseBehavior(controller, content); SetupSystemIntegration(controller, content); empty = false; diff --git a/Telegram/SourceFiles/settings/settings_advanced.h b/Telegram/SourceFiles/settings/settings_advanced.h index 1d46797b4..b247d44d9 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.h +++ b/Telegram/SourceFiles/settings/settings_advanced.h @@ -34,6 +34,9 @@ void SetupUpdate(not_null container); void SetupWindowTitleContent( Window::SessionController *controller, not_null container); +void SetupWindowCloseBehaviorContent( + Window::SessionController *controller, + not_null container); void SetupSystemIntegrationContent( Window::SessionController *controller, not_null container); diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 334af505e..c37d41228 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -420,8 +420,8 @@ bool MainWindow::hideNoQuit() { return false; } const auto workMode = Core::App().settings().workMode(); - if (workMode == Core::Settings::WorkMode::TrayOnly - || workMode == Core::Settings::WorkMode::WindowAndTray) { + using Mode = Core::Settings::WorkMode; + if (workMode == Mode::TrayOnly || workMode == Mode::WindowAndTray) { if (minimizeToTray()) { if (const auto controller = sessionController()) { controller->clearSectionStack(); @@ -429,20 +429,23 @@ bool MainWindow::hideNoQuit() { return true; } } - if (Platform::RunInBackground() || Core::App().settings().closeToTaskbar()) { - if (Platform::RunInBackground()) { - closeWithoutDestroy(); - } else { - setWindowState(window()->windowState() | Qt::WindowMinimized); - } - controller().updateIsActiveBlur(); - updateGlobalMenu(); - if (const auto controller = sessionController()) { - controller->clearSectionStack(); - } - return true; + using Behavior = Core::Settings::CloseBehavior; + const auto behavior = Platform::IsMac() + ? Behavior::RunInBackground + : Core::App().settings().closeBehavior(); + if (behavior == Behavior::RunInBackground) { + closeWithoutDestroy(); + } else if (behavior == Behavior::CloseToTaskbar) { + setWindowState(window()->windowState() | Qt::WindowMinimized); + } else { + return false; } - return false; + controller().updateIsActiveBlur(); + updateGlobalMenu(); + if (const auto controller = sessionController()) { + controller->clearSectionStack(); + } + return true; } void MainWindow::clearWidgets() {