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_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";

View file

@ -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<qint32>(_playerRepeatMode.current());
qint32 playerOrderMode = static_cast<qint32>(_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>(closeBehavior);
switch (uncheckedCloseBehavior) {
case CloseBehavior::CloseToTaskbar:
case CloseBehavior::RunInBackground:
case CloseBehavior::Quit: _closeBehavior = uncheckedCloseBehavior; break;
}
_customDeviceModel = customDeviceModel;
_accountsOrder = accountsOrder;
const auto uncheckedPlayerRepeatMode = static_cast<Media::RepeatMode>(playerRepeatMode);

View file

@ -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<bool> closeToTaskbarValue() const {
return _closeToTaskbar.value();
}
[[nodiscard]] rpl::producer<bool> 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 = WorkMode::WindowAndTray;
base::flags<Calls::Group::StickedTooltip> _hiddenGroupCallTooltips;
rpl::variable<bool> _closeToTaskbar = false;
CloseBehavior _closeBehavior = CloseBehavior::Quit;
rpl::variable<bool> _trayIconMonochrome = true;
rpl::variable<QString> _customDeviceModel;
rpl::variable<Media::RepeatMode> _playerRepeatMode;

View file

@ -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<rpl::variable<bool>>(false);
const auto closeToTaskbarShown = std::make_shared<
rpl::variable<bool>
>(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<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(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container) {
@ -1006,6 +1073,7 @@ void Advanced::setupContent(not_null<Window::SessionController*> controller) {
SetupDataStorage(controller, content);
SetupAutoDownload(controller, content);
SetupWindowTitle(controller, content);
SetupWindowCloseBehavior(controller, content);
SetupSystemIntegration(controller, content);
empty = false;

View file

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

View file

@ -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() {