Support background-run options on Linux.

This commit is contained in:
John Preston 2025-01-14 20:43:14 +04:00
parent de732ba692
commit 530e2a1feb
6 changed files with 117 additions and 36 deletions

View file

@ -604,6 +604,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_update_fail" = "Update check failed :("; "lng_settings_update_fail" = "Update check failed :(";
"lng_settings_workmode_tray" = "Show tray icon"; "lng_settings_workmode_tray" = "Show tray icon";
"lng_settings_workmode_window" = "Show taskbar 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_close_to_taskbar" = "Close to taskbar";
"lng_settings_monochrome_icon" = "Use monochrome icon"; "lng_settings_monochrome_icon" = "Use monochrome icon";
"lng_settings_window_system" = "Window title bar"; "lng_settings_window_system" = "Window title bar";

View file

@ -337,7 +337,7 @@ QByteArray Settings::serialize() const {
<< _photoEditorBrush << _photoEditorBrush
<< qint32(_groupCallNoiseSuppression ? 1 : 0) << qint32(_groupCallNoiseSuppression ? 1 : 0)
<< qint32(SerializePlaybackSpeed(_voicePlaybackSpeed)) << qint32(SerializePlaybackSpeed(_voicePlaybackSpeed))
<< qint32(_closeToTaskbar.current() ? 1 : 0) << qint32(_closeBehavior)
<< _customDeviceModel.current() << _customDeviceModel.current()
<< qint32(_playerRepeatMode.current()) << qint32(_playerRepeatMode.current())
<< qint32(_playerOrderMode.current()) << qint32(_playerOrderMode.current())
@ -493,7 +493,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
QByteArray proxy; QByteArray proxy;
qint32 hiddenGroupCallTooltips = qint32(_hiddenGroupCallTooltips.value()); qint32 hiddenGroupCallTooltips = qint32(_hiddenGroupCallTooltips.value());
QByteArray photoEditorBrush = _photoEditorBrush; QByteArray photoEditorBrush = _photoEditorBrush;
qint32 closeToTaskbar = _closeToTaskbar.current() ? 1 : 0; qint32 closeBehavior = qint32(_closeBehavior);
QString customDeviceModel = _customDeviceModel.current(); QString customDeviceModel = _customDeviceModel.current();
qint32 playerRepeatMode = static_cast<qint32>(_playerRepeatMode.current()); qint32 playerRepeatMode = static_cast<qint32>(_playerRepeatMode.current());
qint32 playerOrderMode = static_cast<qint32>(_playerOrderMode.current()); qint32 playerOrderMode = static_cast<qint32>(_playerOrderMode.current());
@ -689,7 +689,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
stream >> voicePlaybackSpeed; stream >> voicePlaybackSpeed;
} }
if (!stream.atEnd()) { if (!stream.atEnd()) {
stream >> closeToTaskbar; stream >> closeBehavior;
} }
if (!stream.atEnd()) { if (!stream.atEnd()) {
stream >> customDeviceModel; stream >> customDeviceModel;
@ -998,7 +998,12 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
: Tooltip(0)); : Tooltip(0));
}(); }();
_photoEditorBrush = photoEditorBrush; _photoEditorBrush = photoEditorBrush;
_closeToTaskbar = (closeToTaskbar == 1); const auto uncheckedCloseBehavior = static_cast<CloseBehavior>(closeBehavior);
switch (uncheckedCloseBehavior) {
case CloseBehavior::CloseToTaskbar:
case CloseBehavior::RunInBackground:
case CloseBehavior::Quit: _closeBehavior = uncheckedCloseBehavior; break;
}
_customDeviceModel = customDeviceModel; _customDeviceModel = customDeviceModel;
_accountsOrder = accountsOrder; _accountsOrder = accountsOrder;
const auto uncheckedPlayerRepeatMode = static_cast<Media::RepeatMode>(playerRepeatMode); const auto uncheckedPlayerRepeatMode = static_cast<Media::RepeatMode>(playerRepeatMode);

View file

@ -109,6 +109,11 @@ public:
TrayOnly = 1, TrayOnly = 1,
WindowOnly = 2, WindowOnly = 2,
}; };
enum class CloseBehavior {
Quit = 0,
CloseToTaskbar = 1,
RunInBackground = 2,
};
static constexpr auto kDefaultVolume = 0.9; static constexpr auto kDefaultVolume = 0.9;
@ -745,17 +750,11 @@ public:
_hiddenGroupCallTooltips |= value; _hiddenGroupCallTooltips |= value;
} }
void setCloseToTaskbar(bool value) { void setCloseBehavior(CloseBehavior value) {
_closeToTaskbar = value; _closeBehavior = value;
} }
[[nodiscard]] bool closeToTaskbar() const { [[nodiscard]] CloseBehavior closeBehavior() const {
return _closeToTaskbar.current(); return _closeBehavior;
}
[[nodiscard]] rpl::producer<bool> closeToTaskbarValue() const {
return _closeToTaskbar.value();
}
[[nodiscard]] rpl::producer<bool> closeToTaskbarChanges() const {
return _closeToTaskbar.changes();
} }
void setTrayIconMonochrome(bool value) { void setTrayIconMonochrome(bool value) {
_trayIconMonochrome = value; _trayIconMonochrome = value;
@ -1042,7 +1041,7 @@ private:
bool _disableOpenGL = false; bool _disableOpenGL = false;
rpl::variable<WorkMode> _workMode = WorkMode::WindowAndTray; rpl::variable<WorkMode> _workMode = WorkMode::WindowAndTray;
base::flags<Calls::Group::StickedTooltip> _hiddenGroupCallTooltips; base::flags<Calls::Group::StickedTooltip> _hiddenGroupCallTooltips;
rpl::variable<bool> _closeToTaskbar = false; CloseBehavior _closeBehavior = CloseBehavior::Quit;
rpl::variable<bool> _trayIconMonochrome = true; rpl::variable<bool> _trayIconMonochrome = true;
rpl::variable<QString> _customDeviceModel; rpl::variable<QString> _customDeviceModel;
rpl::variable<Media::RepeatMode> _playerRepeatMode; rpl::variable<Media::RepeatMode> _playerRepeatMode;

View file

@ -578,11 +578,14 @@ void SetupSystemIntegrationContent(
#endif // Q_OS_MAC #endif // Q_OS_MAC
if (!Platform::RunInBackground()) { if (!Platform::RunInBackground()) {
using Behavior = Core::Settings::CloseBehavior;
const auto closeToTaskbar = addSlidingCheckbox( const auto closeToTaskbar = addSlidingCheckbox(
tr::lng_settings_close_to_taskbar(), tr::lng_settings_close_to_taskbar(),
settings->closeToTaskbar()); settings->closeBehavior() == Behavior::CloseToTaskbar);
const auto closeToTaskbarShown = std::make_shared<rpl::variable<bool>>(false); const auto closeToTaskbarShown = std::make_shared<
rpl::variable<bool>
>(false);
settings->workModeValue( settings->workModeValue(
) | rpl::start_with_next([=](WorkMode workMode) { ) | rpl::start_with_next([=](WorkMode workMode) {
*closeToTaskbarShown = !Core::App().tray().has(); *closeToTaskbarShown = !Core::App().tray().has();
@ -590,12 +593,16 @@ void SetupSystemIntegrationContent(
closeToTaskbar->toggleOn(closeToTaskbarShown->value()); closeToTaskbar->toggleOn(closeToTaskbarShown->value());
closeToTaskbar->entity()->checkedChanges( closeToTaskbar->entity()->checkedChanges(
) | rpl::filter([=](bool checked) { ) | rpl::map([=](bool checked) {
return (checked != settings->closeToTaskbar()); return checked ? Behavior::CloseToTaskbar : Behavior::Quit;
}) | rpl::start_with_next([=](bool checked) { }) | rpl::filter([=](Behavior value) {
settings->setCloseToTaskbar(checked); return (settings->closeBehavior() != value);
}) | rpl::start_with_next([=](Behavior value) {
settings->setCloseBehavior(value);
Local::writeSettings(); Local::writeSettings();
}, closeToTaskbar->lifetime()); }, closeToTaskbar->lifetime());
} else if (!Platform::IsMac()) {
} }
if (Platform::AutostartSupported() && controller) { if (Platform::AutostartSupported() && controller) {
@ -958,6 +965,66 @@ void SetupWindowTitle(
AddSkip(container); AddSkip(container);
} }
void SetupWindowCloseBehavior(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container) {
if (Platform::IsMac() || !Platform::RunInBackground()) {
return;
}
const auto wrap = container->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
container,
object_ptr<Ui::VerticalLayout>(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<Ui::RadioenumGroup<Behavior>>(
settings->closeBehavior());
const auto add = [&](Behavior value, const QString &label) {
inner->add(
object_ptr<Ui::Radioenum<Behavior>>(
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( void SetupSystemIntegration(
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container) { not_null<Ui::VerticalLayout*> container) {
@ -1006,6 +1073,7 @@ void Advanced::setupContent(not_null<Window::SessionController*> controller) {
SetupDataStorage(controller, content); SetupDataStorage(controller, content);
SetupAutoDownload(controller, content); SetupAutoDownload(controller, content);
SetupWindowTitle(controller, content); SetupWindowTitle(controller, content);
SetupWindowCloseBehavior(controller, content);
SetupSystemIntegration(controller, content); SetupSystemIntegration(controller, content);
empty = false; empty = false;

View file

@ -34,6 +34,9 @@ void SetupUpdate(not_null<Ui::VerticalLayout*> container);
void SetupWindowTitleContent( void SetupWindowTitleContent(
Window::SessionController *controller, Window::SessionController *controller,
not_null<Ui::VerticalLayout*> container); not_null<Ui::VerticalLayout*> container);
void SetupWindowCloseBehaviorContent(
Window::SessionController *controller,
not_null<Ui::VerticalLayout*> container);
void SetupSystemIntegrationContent( void SetupSystemIntegrationContent(
Window::SessionController *controller, Window::SessionController *controller,
not_null<Ui::VerticalLayout*> container); not_null<Ui::VerticalLayout*> container);

View file

@ -420,8 +420,8 @@ bool MainWindow::hideNoQuit() {
return false; return false;
} }
const auto workMode = Core::App().settings().workMode(); const auto workMode = Core::App().settings().workMode();
if (workMode == Core::Settings::WorkMode::TrayOnly using Mode = Core::Settings::WorkMode;
|| workMode == Core::Settings::WorkMode::WindowAndTray) { if (workMode == Mode::TrayOnly || workMode == Mode::WindowAndTray) {
if (minimizeToTray()) { if (minimizeToTray()) {
if (const auto controller = sessionController()) { if (const auto controller = sessionController()) {
controller->clearSectionStack(); controller->clearSectionStack();
@ -429,20 +429,23 @@ bool MainWindow::hideNoQuit() {
return true; return true;
} }
} }
if (Platform::RunInBackground() || Core::App().settings().closeToTaskbar()) { using Behavior = Core::Settings::CloseBehavior;
if (Platform::RunInBackground()) { const auto behavior = Platform::IsMac()
closeWithoutDestroy(); ? Behavior::RunInBackground
} else { : Core::App().settings().closeBehavior();
setWindowState(window()->windowState() | Qt::WindowMinimized); if (behavior == Behavior::RunInBackground) {
} closeWithoutDestroy();
controller().updateIsActiveBlur(); } else if (behavior == Behavior::CloseToTaskbar) {
updateGlobalMenu(); setWindowState(window()->windowState() | Qt::WindowMinimized);
if (const auto controller = sessionController()) { } else {
controller->clearSectionStack(); return false;
}
return true;
} }
return false; controller().updateIsActiveBlur();
updateGlobalMenu();
if (const auto controller = sessionController()) {
controller->clearSectionStack();
}
return true;
} }
void MainWindow::clearWidgets() { void MainWindow::clearWidgets() {