diff --git a/Telegram/SourceFiles/codegen/emoji/data.cpp b/Telegram/SourceFiles/codegen/emoji/data.cpp
index e0aed486c..ad7a807bf 100644
--- a/Telegram/SourceFiles/codegen/emoji/data.cpp
+++ b/Telegram/SourceFiles/codegen/emoji/data.cpp
@@ -17,6 +17,7 @@ using uint64 = quint64;
 
 using std::vector;
 using std::map;
+using std::set;
 using std::find;
 using std::make_pair;
 using std::move;
@@ -81,6 +82,12 @@ Replace Replaces[] = {
 	{ { 0xD83DDE08U }, "}:)" },
 };
 
+InputCategory PostfixRequired = {
+ { 0x2122U, 0xFE0FU, },
+ { 0xA9U, 0xFE0FU, },
+ { 0xAEU, 0xFE0FU, },
+};
+
 using ColorId = uint32;
 ColorId Colors[] = {
 	0xD83CDFFBU,
@@ -1904,35 +1911,46 @@ Id BareIdFromInput(const InputId &id) {
 	return result;
 }
 
-using VariatedIds = map<Id, bool>;
-VariatedIds fillVariatedIds() {
-	auto result = VariatedIds();
-	for (auto &row : ColoredEmoji) {
+set<Id> fillVariatedIds() {
+	auto result = set<Id>();
+	for (const auto &row : ColoredEmoji) {
 		auto variatedId = Id();
 		if (row.size() < 2) {
 			logDataError() << "colored string should have at least two characters.";
-			return VariatedIds();
+			return {};
 		}
 		for (auto i = size_t(0), size = row.size(); i != size; ++i) {
 			auto code = row[i];
 			if (i == 1) {
 				if (code != ColorMask) {
 					logDataError() << "color code should appear at index 1.";
-					return VariatedIds();
+					return {};
 				}
 			} else if (code == ColorMask) {
 				logDataError() << "color code should appear only at index 1.";
-				return VariatedIds();
+				return {};
 			} else if (code != kPostfix) {
 				append(variatedId, code);
 			}
 		}
-		result.insert(make_pair(variatedId, true));
+		result.emplace(variatedId);
 	}
 	return result;
 }
 
-void appendCategory(Data &result, const InputCategory &category, const VariatedIds &variatedIds) {
+set<Id> fillPostfixRequiredIds() {
+	auto result = set<Id>();
+	for (const auto &row : PostfixRequired) {
+		result.emplace(BareIdFromInput(row));
+	}
+	return result;
+}
+
+void appendCategory(
+		Data &result,
+		const InputCategory &category,
+		const set<Id> &variatedIds,
+		const set<Id> &postfixRequiredIds) {
 	result.categories.push_back(vector<int>());
 	for (auto &id : category) {
 		auto emoji = Emoji();
@@ -1956,6 +1974,7 @@ void appendCategory(Data &result, const InputCategory &category, const VariatedI
 			result = Data();
 			return;
 		}
+
 		auto it = result.map.find(bareId);
 		if (it == result.map.cend()) {
 			const auto index = result.list.size();
@@ -1964,6 +1983,9 @@ void appendCategory(Data &result, const InputCategory &category, const VariatedI
 			if (const auto a = Aliases.find(bareId); a != end(Aliases)) {
 				result.map.emplace(a->second, index);
 			}
+			if (postfixRequiredIds.find(bareId) != end(postfixRequiredIds)) {
+				result.postfixRequired.emplace(index);
+			}
 		} else if (result.list[it->second].postfixed != emoji.postfixed) {
 			logDataError() << "same emoji found with different postfixed property.";
 			result = Data();
@@ -1973,7 +1995,7 @@ void appendCategory(Data &result, const InputCategory &category, const VariatedI
 			result = Data();
 			return;
 		}
-		if (variatedIds.find(bareId) != variatedIds.cend()) {
+		if (variatedIds.find(bareId) != end(variatedIds)) {
 			result.list[it->second].variated = true;
 
 			auto baseId = Id();
@@ -2003,6 +2025,9 @@ void appendCategory(Data &result, const InputCategory &category, const VariatedI
 					if (const auto a = Aliases.find(bareColoredId); a != end(Aliases)) {
 						result.map.emplace(a->second, index);
 					}
+					if (postfixRequiredIds.find(bareColoredId) != end(postfixRequiredIds)) {
+						result.postfixRequired.emplace(index);
+					}
 				} else if (result.list[it->second].postfixed != colored.postfixed) {
 					logDataError() << "same emoji found with different postfixed property.";
 					result = Data();
@@ -2253,8 +2278,9 @@ common::LogStream logDataError() {
 Data PrepareData() {
 	Data result;
 
-	auto variatedIds = fillVariatedIds();
-	if (variatedIds.empty()) {
+	const auto variatedIds = fillVariatedIds();
+	const auto postfixRequiredIds = fillPostfixRequiredIds();
+	if (variatedIds.empty() || postfixRequiredIds.empty()) {
 		return Data();
 	}
 
@@ -2277,7 +2303,7 @@ Data PrepareData() {
 		&Category7,
 	};
 	for (const auto category : categories) {
-		appendCategory(result, *category, variatedIds);
+		appendCategory(result, *category, variatedIds, postfixRequiredIds);
 		if (result.list.empty()) {
 			return Data();
 		}
diff --git a/Telegram/SourceFiles/codegen/emoji/data.h b/Telegram/SourceFiles/codegen/emoji/data.h
index a0c91a926..eb8551f5e 100644
--- a/Telegram/SourceFiles/codegen/emoji/data.h
+++ b/Telegram/SourceFiles/codegen/emoji/data.h
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "codegen/common/logging.h"
 #include <vector>
 #include <map>
+#include <set>
 #include <memory>
 #include <functional>
 #include <QtCore/QString>
@@ -30,6 +31,7 @@ struct Emoji {
 struct Data {
 	std::vector<Emoji> list;
 	std::map<Id, int, std::greater<Id>> map;
+	std::set<int> postfixRequired;
 	std::vector<std::vector<int>> categories;
 	std::map<QString, int, std::greater<QString>> replaces;
 };
diff --git a/Telegram/SourceFiles/codegen/emoji/generator.cpp b/Telegram/SourceFiles/codegen/emoji/generator.cpp
index 660813ef7..1453c41e8 100644
--- a/Telegram/SourceFiles/codegen/emoji/generator.cpp
+++ b/Telegram/SourceFiles/codegen/emoji/generator.cpp
@@ -640,7 +640,7 @@ int FindIndex(const QChar *start, const QChar *end, int *outLength) {\n\
 	auto ch = start;\n\
 \n";
 
-	if (!writeFindFromDictionary(data_.map, true)) {
+	if (!writeFindFromDictionary(data_.map, true, data_.postfixRequired)) {
 		return false;
 	}
 
@@ -651,7 +651,10 @@ int FindIndex(const QChar *start, const QChar *end, int *outLength) {\n\
 	return true;
 }
 
-bool Generator::writeFindFromDictionary(const std::map<QString, int, std::greater<QString>> &dictionary, bool skipPostfixes) {
+bool Generator::writeFindFromDictionary(
+		const std::map<QString, int, std::greater<QString>> &dictionary,
+		bool skipPostfixes,
+		const std::set<int> &postfixRequired) {
 	auto tabs = [](int size) {
 		return QString(size, '\t');
 	};
@@ -672,7 +675,7 @@ bool Generator::writeFindFromDictionary(const std::map<QString, int, std::greate
 	auto checkTypes = QVector<UsedCheckType>();
 	auto chars = QString();
 	auto tabsUsed = 1;
-	auto lengthsCounted = std::map<QString, bool>();
+	auto lengthsCounted = std::set<QString>();
 
 	auto writeSkipPostfix = [this, &tabs, skipPostfixes](int tabsCount) {
 		if (skipPostfixes) {
@@ -728,8 +731,8 @@ bool Generator::writeFindFromDictionary(const std::map<QString, int, std::greate
 			auto checking = chars.size();
 			auto partialKey = key.mid(0, checking);
 			if (dictionary.find(partialKey) != dictionary.cend()) {
-				if (lengthsCounted.find(partialKey) == lengthsCounted.cend()) {
-					lengthsCounted.insert(std::make_pair(partialKey, true));
+				if (lengthsCounted.find(partialKey) == end(lengthsCounted)) {
+					lengthsCounted.emplace(partialKey);
 					source_->stream() << tabs(tabsUsed) << "if (outLength) *outLength = (ch - start);\n";
 				}
 			}
@@ -752,8 +755,14 @@ bool Generator::writeFindFromDictionary(const std::map<QString, int, std::greate
 			writeSkipPostfix(++tabsUsed);
 			chars.push_back(keyChar);
 		}
-		if (lengthsCounted.find(key) == lengthsCounted.cend()) {
-			lengthsCounted.insert(std::make_pair(key, true));
+
+		if (postfixRequired.find(item.second) != end(postfixRequired)) {
+			source_->stream() << tabs(tabsUsed) << "if ((ch - 1)->unicode() != kPostfix) {\n";
+			source_->stream() << tabs(tabsUsed + 1) << "return 0;\n";
+			source_->stream() << tabs(tabsUsed) << "}\n";
+		}
+		if (lengthsCounted.find(key) == end(lengthsCounted)) {
+			lengthsCounted.emplace(key);
 			source_->stream() << tabs(tabsUsed) << "if (outLength) *outLength = (ch - start);\n";
 		}
 
diff --git a/Telegram/SourceFiles/codegen/emoji/generator.h b/Telegram/SourceFiles/codegen/emoji/generator.h
index 779fe88c0..b8c8541a7 100644
--- a/Telegram/SourceFiles/codegen/emoji/generator.h
+++ b/Telegram/SourceFiles/codegen/emoji/generator.h
@@ -48,7 +48,10 @@ private:
 	bool writeGetSections();
 	bool writeFindReplace();
 	bool writeFind();
-	bool writeFindFromDictionary(const std::map<QString, int, std::greater<QString>> &dictionary, bool skipPostfixes = false);
+	bool writeFindFromDictionary(
+		const std::map<QString, int, std::greater<QString>> &dictionary,
+		bool skipPostfixes = false,
+		const std::set<int> &postfixRequired = {});
 	bool writeGetReplacements();
 	void startBinary();
 	bool writeStringBinary(common::CppFile *source, const QString &string);