Support system text replacements on macOS.

This commit is contained in:
John Preston
2026-03-12 18:25:45 +04:00
parent ff54ea88e2
commit af4c7bc754
12 changed files with 64 additions and 15 deletions
+1
View File
@@ -660,6 +660,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_section_chat_settings" = "Chat Settings";
"lng_settings_replace_emojis" = "Replace emoji automatically";
"lng_settings_system_text_replace" = "System text replacements";
"lng_settings_suggest_emoji" = "Suggest emoji replacements";
"lng_settings_suggest_animated_emoji" = "Suggest animated emoji";
"lng_settings_suggest_by_emoji" = "Suggest popular stickers by emoji";
@@ -577,7 +577,8 @@ void GroupInfoBox::prepare() {
_title->setMaxLength(Ui::EditPeer::kMaxGroupChannelTitle);
_title->setInstantReplaces(Ui::InstantReplaces::Default());
_title->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_title,
@@ -593,7 +594,8 @@ void GroupInfoBox::prepare() {
_description->setMaxLength(Ui::EditPeer::kMaxChannelDescription);
_description->setInstantReplaces(Ui::InstantReplaces::Default());
_description->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
_description->setSubmitSettings(
Core::App().settings().sendSubmitWay());
@@ -177,7 +177,8 @@ void InitField(
not_null<Main::Session*> session) {
field->setInstantReplaces(Ui::InstantReplaces::Default());
field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
auto options = Ui::Emoji::SuggestionsController::Options();
options.suggestExactFirstWord = false;
Ui::Emoji::SuggestionsController::Init(
@@ -954,7 +955,8 @@ not_null<Ui::InputField*> CreatePollBox::setupSolution(
solution->setMaxLength(kSolutionLimit + kErrorLimit);
solution->setInstantReplaces(Ui::InstantReplaces::Default());
solution->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
solution->setMarkdownReplacesEnabled(rpl::single(
Ui::MarkdownEnabledState{ Ui::MarkdownEnabled{ {
Ui::InputField::kTagBold,
@@ -185,7 +185,8 @@ void InitField(
not_null<Main::Session*> session) {
field->setInstantReplaces(Ui::InstantReplaces::Default());
field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
auto options = Ui::Emoji::SuggestionsController::Options();
options.suggestExactFirstWord = false;
Ui::Emoji::SuggestionsController::Init(
@@ -662,7 +662,8 @@ object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
result->entity()->setMaxLength(Ui::EditPeer::kMaxGroupChannelTitle);
result->entity()->setInstantReplaces(Ui::InstantReplaces::Default());
result->entity()->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
Ui::Emoji::SuggestionsController::Init(
_wrap->window(),
result->entity(),
@@ -770,7 +771,8 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
result->entity()->setMaxLength(Ui::EditPeer::kMaxChannelDescription);
result->entity()->setInstantReplaces(Ui::InstantReplaces::Default());
result->entity()->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
result->entity()->setSubmitSettings(
Core::App().settings().sendSubmitWay());
Ui::Emoji::SuggestionsController::Init(
@@ -156,7 +156,8 @@ void EditLinkBox(
st::markdownLinkFieldPadding);
text->setInstantReplaces(Ui::InstantReplaces::Default());
text->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
Ui::Emoji::SuggestionsController::Init(
box->getDelegate()->outerContainer(),
text,
@@ -514,7 +515,8 @@ void InitMessageFieldHandlers(MessageFieldHandlersArgs &&args) {
});
field->setInstantReplaces(Ui::InstantReplaces::Default());
field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
field->setMarkdownReplacesEnabled(rpl::single(Ui::MarkdownEnabledState{
Ui::MarkdownEnabled{ std::move(args.allowMarkdownTags) }
}));
@@ -604,7 +606,8 @@ Fn<void(not_null<Ui::InputField*>)> FactcheckFieldIniter(
});
field->setInstantReplaces(Ui::InstantReplaces::Default());
field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
field->setMarkdownReplacesEnabled(rpl::single(
Ui::MarkdownEnabledState{
Ui::MarkdownEnabled{
+9 -2
View File
@@ -259,7 +259,7 @@ QByteArray Settings::serialize() const {
+ sizeof(ushort)
+ sizeof(qint32) // _notificationsDisplayChecksum
+ Serialize::bytearraySize(callPanelPosition)
+ sizeof(qint32) * 3; // _cornerReply + _systemAccentColorEnabled + _usePlatformTranslation
+ sizeof(qint32) * 4;
auto result = QByteArray();
result.reserve(size);
@@ -427,7 +427,8 @@ QByteArray Settings::serialize() const {
<< callPanelPosition
<< qint32(_cornerReply.current() ? 1 : 0)
<< qint32(_systemAccentColorEnabled ? 1 : 0)
<< qint32(_usePlatformTranslation ? 1 : 0);
<< qint32(_usePlatformTranslation ? 1 : 0)
<< qint32(_systemTextReplace.current() ? 1 : 0);
}
Ensures(result.size() == size);
@@ -565,6 +566,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
? 1
: 0;
qint32 usePlatformTranslation = _usePlatformTranslation ? 1 : 0;
qint32 systemTextReplace = _systemTextReplace.current() ? 1 : 0;
stream >> themesAccentColors;
if (!stream.atEnd()) {
@@ -914,6 +916,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
if (!stream.atEnd()) {
stream >> usePlatformTranslation;
}
if (!stream.atEnd()) {
stream >> systemTextReplace;
}
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: "
"Bad data for Core::Settings::constructFromSerialized()"));
@@ -989,6 +994,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
_loopAnimatedStickers = (loopAnimatedStickers == 1);
_largeEmoji = (largeEmoji == 1);
_replaceEmoji = (replaceEmoji == 1);
_systemTextReplace = (systemTextReplace == 1);
_suggestEmoji = (suggestEmoji == 1);
_suggestStickersByEmoji = (suggestStickersByEmoji == 1);
_spellcheckerEnabled = (spellcheckerEnabled == 1);
@@ -1508,6 +1514,7 @@ void Settings::resetOnLastLogout() {
_loopAnimatedStickers = true;
_largeEmoji = true;
_replaceEmoji = true;
_systemTextReplace = true;
_suggestEmoji = true;
_suggestStickersByEmoji = true;
_suggestAnimatedEmoji = true;
+13
View File
@@ -469,6 +469,18 @@ public:
[[nodiscard]] rpl::producer<bool> replaceEmojiChanges() const {
return _replaceEmoji.changes();
}
void setSystemTextReplace(bool value) {
_systemTextReplace = value;
}
[[nodiscard]] bool systemTextReplace() const {
return _systemTextReplace.current();
}
[[nodiscard]] rpl::producer<bool> systemTextReplaceValue() const {
return _systemTextReplace.value();
}
[[nodiscard]] rpl::producer<bool> systemTextReplaceChanges() const {
return _systemTextReplace.changes();
}
[[nodiscard]] bool suggestEmoji() const {
return _suggestEmoji;
}
@@ -1049,6 +1061,7 @@ private:
bool _loopAnimatedStickers = true;
rpl::variable<bool> _largeEmoji = true;
rpl::variable<bool> _replaceEmoji = true;
rpl::variable<bool> _systemTextReplace = true;
bool _suggestEmoji = true;
bool _suggestStickersByEmoji = true;
bool _suggestAnimatedEmoji = true;
@@ -535,6 +535,22 @@ void BuildSystemIntegrationSection(SectionBuilder &builder) {
}, warnBeforeQuit->lifetime());
}
const auto systemReplace = builder.addCheckbox({
.id = u"advanced/system_text_replace"_q,
.title = tr::lng_settings_system_text_replace(),
.checked = settings->systemTextReplace(),
.keywords = { u"text"_q, u"replace"_q, u"system"_q },
});
if (systemReplace) {
systemReplace->checkedChanges(
) | rpl::filter([=](bool checked) {
return (checked != settings->systemTextReplace());
}) | rpl::on_next([=](bool checked) {
settings->setSystemTextReplace(checked);
Core::App().saveSettingsDelayed();
}, systemReplace->lifetime());
}
#ifndef OS_MAC_STORE
const auto roundIconEnabled = [=] {
const auto digest = base::Platform::CurrentCustomAppIconDigest();
@@ -693,7 +693,8 @@ void SetupBio(
bio->changes() | rpl::on_next(updated, bio->lifetime());
bio->setInstantReplaces(Ui::InstantReplaces::Default());
bio->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
Ui::Emoji::SuggestionsController::Init(
container->window(),
bio,
@@ -94,7 +94,8 @@ EditInfoBox::EditInfoBox(
Core::App().settings().sendSubmitWay());
_field->setInstantReplaces(Ui::InstantReplaces::Default());
_field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue(),
Core::App().settings().systemTextReplaceValue());
_field->setMarkdownReplacesEnabled(true);
_field->setEditLinkCallback(
DefaultEditLinkCallback(controller->uiShow(), _field));