diff --git a/Telegram/Resources/icons/info_rights_lock.png b/Telegram/Resources/icons/info_rights_lock.png
new file mode 100644
index 000000000..86edf0241
Binary files /dev/null and b/Telegram/Resources/icons/info_rights_lock.png differ
diff --git a/Telegram/Resources/icons/info_rights_lock@2x.png b/Telegram/Resources/icons/info_rights_lock@2x.png
new file mode 100644
index 000000000..4aac0da7b
Binary files /dev/null and b/Telegram/Resources/icons/info_rights_lock@2x.png differ
diff --git a/Telegram/Resources/icons/info_rights_lock@3x.png b/Telegram/Resources/icons/info_rights_lock@3x.png
new file mode 100644
index 000000000..e3f8fb5d9
Binary files /dev/null and b/Telegram/Resources/icons/info_rights_lock@3x.png differ
diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index beeadffcf..8101513b3 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -1489,7 +1489,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "lng_rights_edit_admin_header" = "What can this admin do?";
 "lng_rights_about_add_admins_yes" = "This admin will be able to add new admins with the same (or more limited) permissions.";
 "lng_rights_about_add_admins_no" = "This admin will not be able to add new admins.";
-"lng_rights_about_admin_cant_edit" = "You cannot edit rights of this admin.";
+
+"lng_rights_about_admin_cant_edit" = "You are not allowed to edit the rights of this admin.";
+"lng_rights_about_restriction_cant_edit" = "You cannot change the restrictions for this user.";
+"lng_rights_restriction_for_all" = "This option is disabled for all members in Group Permissions. You can either enable the permission for everyone or make this user an admin.";
+"lng_rights_permission_for_all" = "This option is enabled for all members in Group Permissions.";
+"lng_rights_permission_unavailable" = "This permission is not available in public groups.";
+"lng_rights_permission_cant_edit" = "You cannot edit this permission.";
 "lng_rights_user_restrictions" = "User restrictions";
 "lng_rights_user_restrictions_header" = "What can this member do?";
 "lng_rights_default_restrictions_header" = "What can members of this group do?";
diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style
index 6fdf27868..439d71c21 100644
--- a/Telegram/SourceFiles/boxes/boxes.style
+++ b/Telegram/SourceFiles/boxes/boxes.style
@@ -692,6 +692,7 @@ rightsCheckbox: Checkbox(defaultBoxCheckbox) {
 rightsToggle: Toggle(defaultToggle) {
 	toggledFg: windowBgActive;
 	untoggledFg: attentionButtonFg;
+	lockIcon: icon {{ "info_rights_lock", windowBgActive }};
 	xsize: 8px;
 	vsize: 5px;
 	vshift: 1px;
diff --git a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
index a0f881361..8bba3824a 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp
@@ -221,12 +221,26 @@ void EditAdminBox::prepare() {
 		| (prepareRights.c_chatAdminRights().vflags.v
 			& (filterByMyRights ? channel->adminRights() : ~Flag(0)));
 
-	const auto disabledFlags = canSave()
-		? (disabledByDefaults
-			| ((!channel || channel->amCreator())
-				? Flags(0)
-				: ~channel->adminRights()))
-		: ~Flags(0);
+	const auto disabledMessages = [&] {
+		auto result = std::map<Flags, QString>();
+		if (!canSave()) {
+			result.emplace(
+				~Flags(0),
+				lang(lng_rights_about_admin_cant_edit));
+		} else {
+			result.emplace(
+				disabledByDefaults,
+				lang(lng_rights_permission_for_all));
+			if (const auto channel = peer()->asChannel()) {
+				if (!channel->amCreator()) {
+					result.emplace(
+						~channel->adminRights(),
+						lang(lng_rights_permission_cant_edit));
+				}
+			}
+		}
+		return result;
+	}();
 
 	const auto anyoneCanAddMembers = chat
 		? chat->anyoneCanAddMembers()
@@ -235,7 +249,7 @@ void EditAdminBox::prepare() {
 		this,
 		lng_rights_edit_admin_header,
 		prepareFlags,
-		disabledFlags,
+		disabledMessages,
 		peer()->isChat() || peer()->isMegagroup(),
 		anyoneCanAddMembers);
 	addControl(std::move(checkboxes), QMargins());
@@ -316,18 +330,29 @@ void EditRestrictedBox::prepare() {
 		| ((channel && channel->isPublic())
 			? (Flag::f_change_info | Flag::f_pin_messages)
 			: Flags(0));
-	const auto disabledFlags = canSave()
-		? (defaultRestrictions
-			| ((channel && channel->isPublic())
-				? (Flag::f_change_info | Flag::f_pin_messages)
-				: Flags(0)))
-		: ~Flags(0);
+	const auto disabledMessages = [&] {
+		auto result = std::map<Flags, QString>();
+		if (!canSave()) {
+			result.emplace(
+				~Flags(0),
+				lang(lng_rights_about_restriction_cant_edit));
+		} else {
+			const auto disabled = defaultRestrictions
+				| ((channel && channel->isPublic())
+					? (Flag::f_change_info | Flag::f_pin_messages)
+					: Flags(0));
+			result.emplace(
+				disabled,
+				lang(lng_rights_restriction_for_all));
+		}
+		return result;
+	}();
 
 	auto [checkboxes, getRestrictions, changes] = CreateEditRestrictions(
 		this,
 		lng_rights_user_restrictions_header,
 		prepareFlags,
-		disabledFlags);
+		disabledMessages);
 	addControl(std::move(checkboxes), QMargins());
 
 	_until = prepareRights.c_chatBannedRights().vuntil_date.v;
@@ -424,7 +449,7 @@ void EditRestrictedBox::createUntilVariants() {
 		if (!canSave() && _untilGroup->value() != value) {
 			return;
 		}
-		_untilVariants.push_back(base::unique_qptr<Ui::Radiobutton>(
+		_untilVariants.emplace_back(
 			addControl(
 				object_ptr<Ui::Radiobutton>(
 					this,
@@ -432,7 +457,7 @@ void EditRestrictedBox::createUntilVariants() {
 					value,
 					text,
 					st::defaultBoxCheckbox),
-				st::rightsToggleMargin)));
+				st::rightsToggleMargin));
 		if (!canSave()) {
 			_untilVariants.back()->setDisabled(true);
 		}
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp
index c3c87ebf9..adfcd3b21 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp
@@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "ui/wrap/vertical_layout.h"
 #include "ui/widgets/labels.h"
 #include "ui/widgets/checkbox.h"
+#include "ui/toast/toast.h"
 #include "info/profile/info_profile_button.h"
 #include "info/profile/info_profile_icon.h"
 #include "info/profile/info_profile_values.h"
@@ -280,24 +281,26 @@ void EditPeerPermissionsBox::prepare() {
 		}
 		Unexpected("User in EditPeerPermissionsBox.");
 	}();
-	const auto disabledFlags = [&] {
-		if (const auto chat = _peer->asChat()) {
-			return Flags(0)
-				| disabledByAdminRights;
-		} else if (const auto channel = _peer->asChannel()) {
-			return (channel->isPublic()
-				? (Flag::f_change_info | Flag::f_pin_messages)
-				: Flags(0))
-				| disabledByAdminRights;
+	const auto disabledMessages = [&] {
+		auto result = std::map<Flags, QString>();
+			result.emplace(
+				disabledByAdminRights,
+				lang(lng_rights_permission_cant_edit));
+		if (const auto channel = _peer->asChannel()) {
+			if (channel->isPublic()) {
+				result.emplace(
+					Flag::f_change_info | Flag::f_pin_messages,
+					lang(lng_rights_permission_unavailable));
+			}
 		}
-		Unexpected("User in EditPeerPermissionsBox.");
+		return result;
 	}();
 
 	auto [checkboxes, getRestrictions, changes] = CreateEditRestrictions(
 		this,
 		lng_rights_default_restrictions_header,
 		restrictions,
-		disabledFlags);
+		disabledMessages);
 
 	inner->add(std::move(checkboxes));
 
@@ -353,12 +356,15 @@ void EditPeerPermissionsBox::addBannedButtons(
 	}
 }
 
-template <typename Flags, typename FlagLabelPairs>
+template <
+	typename Flags,
+	typename DisabledMessagePairs,
+	typename FlagLabelPairs>
 EditFlagsControl<Flags> CreateEditFlags(
 		QWidget *parent,
 		LangKey header,
 		Flags checked,
-		Flags disabled,
+		const DisabledMessagePairs &disabledMessagePairs,
 		const FlagLabelPairs &flagLabelPairs) {
 	auto widget = object_ptr<Ui::VerticalLayout>(parent);
 	const auto container = widget.data();
@@ -394,24 +400,38 @@ EditFlagsControl<Flags> CreateEditFlags(
 		st::rightsHeaderMargin);
 
 	auto addCheckbox = [&](Flags flags, const QString &text) {
+		const auto lockedIt = ranges::find_if(
+			disabledMessagePairs,
+			[&](const auto &pair) { return (pair.first & flags) != 0; });
+		const auto locked = (lockedIt != end(disabledMessagePairs))
+			? std::make_optional(lockedIt->second)
+			: std::nullopt;
+		const auto toggled = ((checked & flags) != 0);
+		auto toggle = std::make_unique<Ui::ToggleView>(
+			st::rightsToggle,
+			toggled);
+		toggle->setLocked(locked.has_value());
 		const auto control = container->add(
 			object_ptr<Ui::Checkbox>(
 				container,
 				text,
-				(checked & flags) != 0,
 				st::rightsCheckbox,
-				st::rightsToggle),
+				std::move(toggle)),
 			st::rightsToggleMargin);
 		control->checkedChanges(
 		) | rpl::start_with_next([=](bool checked) {
-			InvokeQueued(control, [=] {
-				applyDependencies(control);
-				changes->fire({});
-			});
+			if (locked.has_value()) {
+				if (checked != toggled) {
+					Ui::Toast::Show(*locked);
+					control->setChecked(toggled);
+				}
+			} else {
+				InvokeQueued(control, [=] {
+					applyDependencies(control);
+					changes->fire({});
+				});
+			}
 		}, control->lifetime());
-		if ((disabled & flags) != 0) {
-			control->setDisabled(true);
-		}
 		checkboxes->emplace(flags, control);
 	};
 	for (const auto &[flags, label] : flagLabelPairs) {
@@ -434,12 +454,12 @@ EditFlagsControl<MTPDchatBannedRights::Flags> CreateEditRestrictions(
 		QWidget *parent,
 		LangKey header,
 		MTPDchatBannedRights::Flags restrictions,
-		MTPDchatBannedRights::Flags disabled) {
+		std::map<MTPDchatBannedRights::Flags, QString> disabledMessages) {
 	auto result = CreateEditFlags(
 		parent,
 		header,
 		NegateRestrictions(restrictions),
-		disabled,
+		disabledMessages,
 		RestrictionLabels());
 	result.value = [original = std::move(result.value)]{
 		return NegateRestrictions(original());
@@ -455,13 +475,13 @@ EditFlagsControl<MTPDchatAdminRights::Flags> CreateEditAdminRights(
 		QWidget *parent,
 		LangKey header,
 		MTPDchatAdminRights::Flags rights,
-		MTPDchatAdminRights::Flags disabled,
+		std::map<MTPDchatAdminRights::Flags, QString> disabledMessages,
 		bool isGroup,
 		bool anyoneCanAddMembers) {
 	return CreateEditFlags(
 		parent,
 		header,
 		rights,
-		disabled,
+		disabledMessages,
 		AdminRightLabels(isGroup, anyoneCanAddMembers));
 }
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h
index f771bb38a..cd6998f83 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h
@@ -46,13 +46,13 @@ EditFlagsControl<MTPDchatBannedRights::Flags> CreateEditRestrictions(
 	QWidget *parent,
 	LangKey header,
 	MTPDchatBannedRights::Flags restrictions,
-	MTPDchatBannedRights::Flags disabled);
+	std::map<MTPDchatBannedRights::Flags, QString> disabledMessages);
 
 EditFlagsControl<MTPDchatAdminRights::Flags> CreateEditAdminRights(
 	QWidget *parent,
 	LangKey header,
 	MTPDchatAdminRights::Flags rights,
-	MTPDchatAdminRights::Flags disabled,
+	std::map<MTPDchatAdminRights::Flags, QString> disabledMessages,
 	bool isGroup,
 	bool anyoneCanAddMembers);
 
diff --git a/Telegram/SourceFiles/ui/twidget.cpp b/Telegram/SourceFiles/ui/twidget.cpp
index 0184bdf5c..be9ecce12 100644
--- a/Telegram/SourceFiles/ui/twidget.cpp
+++ b/Telegram/SourceFiles/ui/twidget.cpp
@@ -22,7 +22,7 @@ bool ValidateFont(const QString &familyName, int flags = 0) {
 	checkFont.setStyleStrategy(QFont::PreferQuality);
 	auto realFamily = QFontInfo(checkFont).family();
 	if (realFamily.trimmed().compare(familyName, Qt::CaseInsensitive)) {
-		LOG(("Font Error: could not resolve '%1' font, got '%2' after feeding '%3'.").arg(familyName).arg(realFamily));
+		LOG(("Font Error: could not resolve '%1' font, got '%2'.").arg(familyName).arg(realFamily));
 		return false;
 	}
 
diff --git a/Telegram/SourceFiles/ui/widgets/checkbox.cpp b/Telegram/SourceFiles/ui/widgets/checkbox.cpp
index da8d5dfc7..188de1791 100644
--- a/Telegram/SourceFiles/ui/widgets/checkbox.cpp
+++ b/Telegram/SourceFiles/ui/widgets/checkbox.cpp
@@ -115,20 +115,28 @@ void ToggleView::paint(Painter &p, int left, int top, int outerWidth, TimeMs ms)
 	p.drawEllipse(fgRect);
 
 	if (_st->xsize > 0) {
-		paintXV(p, toggleLeft, top, outerWidth, toggled, fgBrush);
+		p.setPen(Qt::NoPen);
+		p.setBrush(fgBrush);
+		if (_locked) {
+			const auto color = anim::color(_st->untoggledFg, _st->toggledFg, toggled);
+			_st->lockIcon.paint(p, toggleLeft, top, outerWidth, color);
+		} else {
+			paintXV(p, toggleLeft, top, outerWidth, toggled, fgBrush);
+		}
 	}
 }
 
 void ToggleView::paintXV(Painter &p, int left, int top, int outerWidth, float64 toggled, const QBrush &brush) {
-	Assert(_st->vsize > 0);
-	Assert(_st->stroke > 0);
+	Expects(_st->vsize > 0);
+	Expects(_st->stroke > 0);
+
 	static const auto sqrt2 = sqrt(2.);
-	auto stroke = (0. + _st->stroke) / sqrt2;
+	const auto stroke = (0. + _st->stroke) / sqrt2;
 	if (toggled < 1) {
 		// Just X or X->V.
-		auto xSize = 0. + _st->xsize;
-		auto xLeft = left + (_st->diameter - xSize) / 2.;
-		auto xTop = top + (_st->diameter - xSize) / 2.;
+		const auto xSize = 0. + _st->xsize;
+		const auto xLeft = left + (_st->diameter - xSize) / 2.;
+		const auto xTop = top + (_st->diameter - xSize) / 2.;
 		QPointF pathX[] = {
 			{ xLeft, xTop + stroke },
 			{ xLeft + stroke, xTop },
@@ -148,10 +156,10 @@ void ToggleView::paintXV(Painter &p, int left, int top, int outerWidth, float64
 		}
 		if (toggled > 0) {
 			// X->V.
-			auto vSize = 0. + _st->vsize;
-			auto fSize = (xSize + vSize - 2. * stroke);
-			auto vLeft = left + (_st->diameter - fSize) / 2.;
-			auto vTop = 0. + xTop + _st->vshift;
+			const auto vSize = 0. + _st->vsize;
+			const auto fSize = (xSize + vSize - 2. * stroke);
+			const auto vLeft = left + (_st->diameter - fSize) / 2.;
+			const auto vTop = 0. + xTop + _st->vshift;
 			QPointF pathV[] = {
 				{ vLeft, vTop + xSize - vSize + stroke },
 				{ vLeft + stroke, vTop + xSize - vSize },
@@ -176,12 +184,12 @@ void ToggleView::paintXV(Painter &p, int left, int top, int outerWidth, float64
 		}
 	} else {
 		// Just V.
-		auto xSize = 0. + _st->xsize;
-		auto xTop = top + (_st->diameter - xSize) / 2.;
-		auto vSize = 0. + _st->vsize;
-		auto fSize = (xSize + vSize - 2. * stroke);
-		auto vLeft = left + (_st->diameter - (_st->xsize + _st->vsize - 2. * stroke)) / 2.;
-		auto vTop = 0. + xTop + _st->vshift;
+		const auto xSize = 0. + _st->xsize;
+		const auto xTop = top + (_st->diameter - xSize) / 2.;
+		const auto vSize = 0. + _st->vsize;
+		const auto fSize = (xSize + vSize - 2. * stroke);
+		const auto vLeft = left + (_st->diameter - (_st->xsize + _st->vsize - 2. * stroke)) / 2.;
+		const auto vTop = 0. + xTop + _st->vshift;
 		QPointF pathV[] = {
 			{ vLeft, vTop + xSize - vSize + stroke },
 			{ vLeft + stroke, vTop + xSize - vSize },
@@ -214,6 +222,13 @@ bool ToggleView::checkRippleStartPosition(QPoint position) const {
 	return QRect(QPoint(0, 0), rippleSize()).contains(position);
 }
 
+void ToggleView::setLocked(bool locked) {
+	if (_locked != locked) {
+		_locked = locked;
+		update();
+	}
+}
+
 CheckView::CheckView(const style::Check &st, bool checked, Fn<void()> updateCallback) : AbstractCheckView(st.duration, checked, std::move(updateCallback))
 , _st(&st) {
 }
diff --git a/Telegram/SourceFiles/ui/widgets/checkbox.h b/Telegram/SourceFiles/ui/widgets/checkbox.h
index 0f2bf00c9..f428ff201 100644
--- a/Telegram/SourceFiles/ui/widgets/checkbox.h
+++ b/Telegram/SourceFiles/ui/widgets/checkbox.h
@@ -126,12 +126,14 @@ public:
 	void paint(Painter &p, int left, int top, int outerWidth, TimeMs ms) override;
 	QImage prepareRippleMask() const override;
 	bool checkRippleStartPosition(QPoint position) const override;
+	void setLocked(bool locked);
 
 private:
 	void paintXV(Painter &p, int left, int top, int outerWidth, float64 toggled, const QBrush &brush);
 	QSize rippleSize() const;
 
 	not_null<const style::Toggle*> _st;
+	bool _locked = false;
 
 };
 
diff --git a/Telegram/SourceFiles/ui/widgets/widgets.style b/Telegram/SourceFiles/ui/widgets/widgets.style
index b9511979a..793ecae8a 100644
--- a/Telegram/SourceFiles/ui/widgets/widgets.style
+++ b/Telegram/SourceFiles/ui/widgets/widgets.style
@@ -115,6 +115,7 @@ Toggle {
 	vsize: pixels;
 	vshift: pixels;
 	stroke: pixels;
+	lockIcon: icon;
 	rippleAreaPadding: pixels;
 }