From 8e8719870af357bdda065a3ae3f9ea096c886d35 Mon Sep 17 00:00:00 2001
From: ZavaruKitsu <alexeyzavar@gmail.com>
Date: Wed, 30 Aug 2023 20:07:23 +0000
Subject: [PATCH] feat: streamer mode

Co-authored-by: MaxPlays35 <35427519+maxplays35@users.noreply.github.com>
---
 Telegram/CMakeLists.txt                       |   7 +-
 Telegram/Resources/icons/ayu/streamer.png     | Bin 0 -> 583 bytes
 Telegram/Resources/icons/ayu/streamer@2x.png  | Bin 0 -> 1067 bytes
 Telegram/Resources/icons/ayu/streamer@3x.png  | Bin 0 -> 1542 bytes
 Telegram/Resources/langs/lang.strings         |  17 ++-
 Telegram/SourceFiles/ayu/ayu_settings.cpp     |  10 +-
 .../SourceFiles/ayu/database/ayu_database.cpp |   2 +-
 .../features/streamer_mode/streamer_mode.h    |  19 ++++
 .../streamer_mode/streamer_mode_linux.cpp     |  43 ++++++++
 .../streamer_mode/streamer_mode_windows.cpp   |  53 ++++++++++
 .../ayu/messages/ayu_messages_controller.cpp  |   2 +-
 .../ayu/sync/ayu_sync_controller.cpp          |   2 +-
 Telegram/SourceFiles/ayu/ui/ayu_icons.style   |   1 +
 .../ayu/ui/settings/settings_ayu.cpp          |  98 ++++++++++++++++--
 .../ayu/ui/settings/settings_ayu.h            |  13 +++
 .../ayu/{sync => }/utils/telegram_helpers.cpp |   2 +-
 .../ayu/{sync => }/utils/telegram_helpers.h   |   0
 Telegram/SourceFiles/data/data_user.cpp       |   2 +-
 .../media/view/media_view_overlay_widget.cpp  |  11 ++
 .../SourceFiles/media/view/media_view_pip.cpp |  11 ++
 Telegram/SourceFiles/tray.cpp                 |  30 +++++-
 .../window/notifications_manager_default.cpp  |  14 +++
 .../SourceFiles/window/window_main_menu.cpp   |  20 ++++
 .../SourceFiles/window/window_main_menu.h     |   3 +-
 24 files changed, 331 insertions(+), 29 deletions(-)
 create mode 100644 Telegram/Resources/icons/ayu/streamer.png
 create mode 100644 Telegram/Resources/icons/ayu/streamer@2x.png
 create mode 100644 Telegram/Resources/icons/ayu/streamer@3x.png
 create mode 100644 Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode.h
 create mode 100644 Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode_linux.cpp
 create mode 100644 Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode_windows.cpp
 rename Telegram/SourceFiles/ayu/{sync => }/utils/telegram_helpers.cpp (97%)
 rename Telegram/SourceFiles/ayu/{sync => }/utils/telegram_helpers.h (100%)

diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index 5dcf1be3e..f1b4752ce 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -102,6 +102,8 @@ PRIVATE
     ayu/ayu_lang.cpp
     ayu/ayu_lang.h
     ayu/ayu_constants.h
+    ayu/utils/telegram_helpers.cpp
+    ayu/utils/telegram_helpers.h
     ayu/ui/ayu_lottie.cpp
     ayu/ui/ayu_lottie.h
     ayu/ui/utils/ayu_profile_values.cpp
@@ -126,8 +128,6 @@ PRIVATE
     ayu/sync/utils/ayu_pipe_wrapper.cpp
     ayu/sync/utils/ayu_pipe_wrapper.h
     ayu/sync/utils/process_utils.hpp
-    ayu/sync/utils/telegram_helpers.cpp
-    ayu/sync/utils/telegram_helpers.h
     ayu/messages/ayu_messages_controller.cpp
     ayu/messages/ayu_messages_controller.h
     ayu/libs/pipe.hpp
@@ -137,6 +137,9 @@ PRIVATE
     ayu/libs/sqlite/sqlite3.c
     ayu/libs/sqlite/sqlite3.h
     ayu/libs/sqlite/sqlite_orm.h
+    ayu/features/streamer_mode/streamer_mode_windows.cpp
+    ayu/features/streamer_mode/streamer_mode_linux.cpp
+    ayu/features/streamer_mode/streamer_mode.h
     ayu/database/entities.h
     ayu/database/ayu_database.cpp
     ayu/database/ayu_database.h
diff --git a/Telegram/Resources/icons/ayu/streamer.png b/Telegram/Resources/icons/ayu/streamer.png
new file mode 100644
index 0000000000000000000000000000000000000000..208555a21f4a4ca6585ad7977180b907145af366
GIT binary patch
literal 583
zcmV-N0=WH&P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00009a7bBm000XU
z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH0o+MMK~#7FwUv!=
z!Y~YlMXv)e0vo^vumNlU8^8vz0Wbk0zy`nszy!bquz{;jSEX(eC+YQ~JKf2#tY`f^
zrz0XkT9glISw5RMjYcEs_xsZAc5VHBzvXtj$?0^eJzJT<VzH3d>m~dB-ar6Av3I+j
z-0ydpPNz~QA+Nn&FC34@aJgK<a5xNQKIm*V3kqV&nS@_4I0x42buw^Xm&;`p$nOt0
za-eB&S1v@>l>nY{yw;j0gK}f-LAIu(+P5?S!TkV^aoXBg%M2Y12KEhbd^{*VIuzvq
zZ2Il};CMW?^=h@UgE~2;?C~uQ>X~BmtpG5e&x4Mm*^|j6t0%Y3HxN4xgs*2#3}U%&
z#slX2@pzaGsjk<n*_wqB%J&fL!{H!0!nVd&L9;z4B+~j*kpVz|zs2+U6fKR}=kr;#
zWZ52q4V%dV!Phfpk65u3CV+;;HFhF-li72w&@cA9$=Ese|BO@|)W_5h(rh1758$l#
zrsjE603ax2k%(v&Z;XM*M2mS;3LxJj_m_9b6<(Cwz6juHJCT~`X0vJj*u@};ltVli
zl$5MfrR+FLnP?A0n`$;==w$OTMKn{{ZnvorQVHM!W102%mkA&osgp(k|B=?8iZ380
VQYQn0P+I^1002ovPDHLkV1gV_{}BKH

literal 0
HcmV?d00001

diff --git a/Telegram/Resources/icons/ayu/streamer@2x.png b/Telegram/Resources/icons/ayu/streamer@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..0250620d5f8327d3dcbe7586bd6e8d3e9b714898
GIT binary patch
literal 1067
zcmV+`1l0S9P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00009a7bBm000&x
z000&x0ZCFM@Bjb+0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH1Hef{K~#7F?ONe&
z@-Pr}KYjn(PS9>pHh>La1K0pI049J95F4-oFaa<DFaa<@niuIs7w4SVBmp7yNmeVT
zKHs}L-}#ch8Dk>z!uV%i9Df9!jsK=0e0+Q)12~;drYY1y0E)I+Ez|9GO{dc_-{0S<
z^2GIeHT(TO8QbmFtX3;i7ovMdtY|cuOrp!>5{2S;JVuMfB9T!=hr0;G){W-#c}5|S
zSg+U7a5#)&Pefl|U+IXw6Sdpz<Qe|PMnxiF3*rz-tS2oA#Xu^=0E59GCkL_{B`_L|
zG8Tv8cUmnSHW7qmBLpCrKp4~zyXk-|8CroP!jzxQX0<7956C9q?OF&RE+3)1M#A$<
z6uXx32^Tl5JO{%GdwV1Y_d}#N3esXeB=fk2CIfr1ws?5mZGEEO@8_QLTm-~wZZNB9
zhgN31l7vxieV6h;Q7Xm8MP8ChYKCC=j>qG00$glcUwTFpjDrXA@_K>aUDZ||T2yTL
z494O50z>2{d%a#N)LtkLSdnL3(86W6+eKQUz}_@OK}Ir8tJnfzAy-`5g$|zMJ*ceO
z%2aJDN`n;~=KLfV+40SDVG}D0D-JvhRg_@_FL@K7+i-)_T<s#Jg_X-VSfeRw%V0P|
zCvO6TeW(bV7zu0X)*c8aO(7YcF7IjwIoA`Tn<C;()Opz=%GU94IG8eQHk))^d`8lF
zbZms2mw11F&&^eC>SgOF3H$v0?RGO&ks}~2At9~)`T3cd=Nk0GWkB!DedJ!!!{_rk
z{aq54^Mp!(g1MPg7KqP4W}Xdt9N(r4aVE;FA%1>-lAmb$B}l+!ST%&GsI-dQG|mi}
z`Q>t%{DcSM9B*8}Gs>J!r<rGzX%lb}lgOQHS0O7ZI5Nj06(S=cvmlEg^T>|Nt`#!V
z*qQIHLPkZkI|v18g+-EZK`V5wo&$Rmc+=rcK;A*@q9yaSW))b|b(yp42Zp?Y*w+)*
zjFJMWKcF?W#bwuEX$ahhT+gMPBG1@W+lzpVOHD}<tnzAw1T^Joea$mo1Tc7*5dx2H
zDLt)UOaQ{4-PC)$e<~LC=+`RpovU`}g9%{B!`37TseDNv97X^`=J=*xEe0s>PrxR@
zYFkx#cvsepJF;5XhT7|O5D9&~4n=J_o-tpI0A0>DQi2~iK$7<$4zz~+z+r#U!MUoC
zlFhvfQzFumz5oe?WYx3uMiy1U4}9n$Ftm?+xTd3}#I+plr|XU%g4zgZU~h}ou?}T5
lG)mwR`1@CbXXE7w`~v=WFQ@f@AT|I1002ovPDHLkV1iud+8Y1>

literal 0
HcmV?d00001

diff --git a/Telegram/Resources/icons/ayu/streamer@3x.png b/Telegram/Resources/icons/ayu/streamer@3x.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae0a507e49c18c63eba1b45dae91a8e560c3cd60
GIT binary patch
literal 1542
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

literal 0
HcmV?d00001

diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index de72609e7..8f3ca7a71 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -4082,10 +4082,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "ayu_AyuSyncStatusTitle" = "Sync status";
 "ayu_AyuSyncStatusOk" = "connected";
 "ayu_AyuSyncStatusErrorDisconnected" = "disconnected";
-"ayu_AyuSyncStatusErrorNotRegistered" = "not registered";
 "ayu_AyuSyncStatusErrorNoToken" = "no token";
 "ayu_AyuSyncStatusErrorInvalidToken" = "invalid token";
-"ayu_AyuSyncStatusErrorNoMVP" = "no MVP";
 "ayu_AyuSyncServerURL" = "Server URL";
 "ayu_AyuSyncServerToken" = "Access token";
 "ayu_AyuSyncEnable" = "Enable synchronization";
@@ -4100,6 +4098,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "ayu_AyuSyncRegisterStatusCode" = "Register status code";
 "ayu_AyuSyncOpenPreferences" = "Open preferences";
 "ayu_AyuSyncDownloadAgent" = "Download agent";
+"ayu_IconDefault" = "Default";
+"ayu_IconAlternative" = "AyuGram Alt";
+"ayu_IconNothing" = "Nothing";
 "ayu_WALMode" = "Enable WAL mode";
 "ayu_ClearAyuDatabase" = "Clear Ayu Database";
 "ayu_ClearAyuDatabaseNotification" = "AyuGram database cleared";
@@ -4110,17 +4111,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "ayu_StickerConfirmation" = "Confirmation when sending stickers";
 "ayu_GIFConfirmation" = "Confirmation when sending GIFs";
 "ayu_VoiceConfirmation" = "Confirmation when sending voice messages";
-"ayu_EnableGhostMode" = "Enable Ghost";
-"ayu_DisableGhostMode" = "Disable Ghost";
 "ayu_KillApp" = "Kill App";
 "ayu_LReadMessages" = "Read on Local";
 "ayu_SReadMessages" = "Read on Server";
 "ayu_GhostModeToggle" = "Ghost Mode";
+"ayu_EnableGhostMode" = "Enable Ghost";
+"ayu_DisableGhostMode" = "Disable Ghost";
+"ayu_EnableGhostModeTray" = "Enable Ghost Mode";
+"ayu_DisableGhostModeTray" = "Disable Ghost Mode";
 "ayu_GhostModeEnabled" = "Ghost mode turned on";
 "ayu_GhostModeDisabled" = "Ghost mode turned off";
+"ayu_StreamerModeToggle" = "Streamer Mode";
+"ayu_EnableStreamerModeTray" = "Enable Streamer Mode";
+"ayu_DisableStreamerModeTray" = "Disable Streamer Mode";
 "ayu_EditsHistoryTitle" = "Edits history";
 "ayu_EditsHistoryMenuText" = "History";
-"ayu_ReadUntilMenuText" = "Read until";
+"ayu_ReadUntilMenuText" = "Read Message";
 "ayu_DeleteKeepLocally" = "Keep locally";
 "ayu_BoxActionReset" = "Reset";
 "ayu_ReadConfirmationBoxQuestion" = "Do you want to read all messages?";
@@ -4139,3 +4145,4 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "ayu_ContextCopyCallbackData" = "Copy Callback Data";
 "ayu_LocalPremiumNotice" = "You're using **local** Telegram Premium.\nIt **won't** give you any benefits, except translator.\n**Enjoy the star near your nickname!**";
 "ayu_SettingsWatermark" = "AyuGram developed and maintained by Radolyn Labs.";
+"ayu_UtilityRestartRequired" = "App will close in 5 seconds.";
diff --git a/Telegram/SourceFiles/ayu/ayu_settings.cpp b/Telegram/SourceFiles/ayu/ayu_settings.cpp
index 511ca5795..6ca889a11 100644
--- a/Telegram/SourceFiles/ayu/ayu_settings.cpp
+++ b/Telegram/SourceFiles/ayu/ayu_settings.cpp
@@ -224,6 +224,11 @@ namespace AyuSettings
 		localPremium = val;
 	}
 
+	void AyuGramSettings::set_copyUsernameAsLink(bool val)
+	{
+		copyUsernameAsLink = val;
+	}
+
 	void AyuGramSettings::set_deletedMark(QString val)
 	{
 		deletedMark = std::move(val);
@@ -277,11 +282,6 @@ namespace AyuSettings
 		voiceConfirmation = val;
 	}
 
-	void AyuGramSettings::set_copyUsernameAsLink(bool val)
-	{
-		copyUsernameAsLink = val;
-	}
-
 	bool get_ghostModeEnabled()
 	{
 		return ghostModeEnabled.current();
diff --git a/Telegram/SourceFiles/ayu/database/ayu_database.cpp b/Telegram/SourceFiles/ayu/database/ayu_database.cpp
index 0a1f2d1c6..9b603f026 100644
--- a/Telegram/SourceFiles/ayu/database/ayu_database.cpp
+++ b/Telegram/SourceFiles/ayu/database/ayu_database.cpp
@@ -9,7 +9,7 @@
 
 #include "entities.h"
 #include "ayu/libs/sqlite/sqlite_orm.h"
-#include "ayu/sync/utils/telegram_helpers.h"
+#include "ayu/utils/telegram_helpers.h"
 
 using namespace sqlite_orm;
 auto storage = make_storage(
diff --git a/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode.h b/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode.h
new file mode 100644
index 000000000..d5b747dfd
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode.h
@@ -0,0 +1,19 @@
+// This is the source code of AyuGram for Desktop.
+//
+// We do not and cannot prevent the use of our code,
+// but be respectful and credit the original author.
+//
+// Copyright @Radolyn, 2023
+
+#pragma once
+
+#include "ui/rp_widget.h"
+
+namespace AyuFeatures::StreamerMode
+{
+	bool isEnabled();
+	void enable();
+	void disable();
+	void hideWidgetWindow(QWidget* widget);
+	void showWidgetWindow(QWidget* widget);
+}
diff --git a/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode_linux.cpp b/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode_linux.cpp
new file mode 100644
index 000000000..98bf0c696
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode_linux.cpp
@@ -0,0 +1,43 @@
+// This is the source code of AyuGram for Desktop.
+//
+// We do not and cannot prevent the use of our code,
+// but be respectful and credit the original author.
+//
+// Copyright @Radolyn, 2023
+
+#ifndef WIN32
+
+#include "streamer_mode.h"
+
+#include "core/application.h"
+#include "window/window_controller.h"
+
+namespace AyuFeatures::StreamerMode
+{
+	bool isEnabledVal;
+
+	bool isEnabled()
+	{
+		return isEnabledVal;
+	}
+
+	void enable()
+	{
+		isEnabledVal = true;
+	}
+
+	void disable()
+	{
+		isEnabledVal = false;
+	}
+
+	void hideWidgetWindow(QWidget* widget) {
+
+	}
+
+	void showWidgetWindow(QWidget* widget) {
+
+	}
+}
+
+#endif
diff --git a/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode_windows.cpp b/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode_windows.cpp
new file mode 100644
index 000000000..a61f3f8ac
--- /dev/null
+++ b/Telegram/SourceFiles/ayu/features/streamer_mode/streamer_mode_windows.cpp
@@ -0,0 +1,53 @@
+// This is the source code of AyuGram for Desktop.
+//
+// We do not and cannot prevent the use of our code,
+// but be respectful and credit the original author.
+//
+// Copyright @Radolyn, 2023
+
+#ifdef WIN32
+
+#include "streamer_mode.h"
+
+#include "core/application.h"
+#include "window/window_controller.h"
+
+namespace AyuFeatures::StreamerMode
+{
+	bool isEnabledVal;
+
+	bool isEnabled()
+	{
+		return isEnabledVal;
+	}
+
+	void enable()
+	{
+		auto handle = Core::App().activeWindow()->widget()->psHwnd();
+		SetWindowDisplayAffinity(handle, WDA_EXCLUDEFROMCAPTURE);
+
+		isEnabledVal = true;
+	}
+
+	void disable()
+	{
+		auto handle = Core::App().activeWindow()->widget()->psHwnd();
+		SetWindowDisplayAffinity(handle, WDA_NONE);
+
+		isEnabledVal = false;
+	}
+
+	void hideWidgetWindow(QWidget* widget)
+	{
+		auto handle = reinterpret_cast<HWND>(widget->window()->winId());
+		SetWindowDisplayAffinity(handle, WDA_EXCLUDEFROMCAPTURE);
+	}
+
+	void showWidgetWindow(QWidget* widget)
+	{
+		auto handle = reinterpret_cast<HWND>(widget->window()->winId());
+		SetWindowDisplayAffinity(handle, WDA_NONE);
+	}
+}
+
+#endif
diff --git a/Telegram/SourceFiles/ayu/messages/ayu_messages_controller.cpp b/Telegram/SourceFiles/ayu/messages/ayu_messages_controller.cpp
index 4ba415245..d7c890404 100644
--- a/Telegram/SourceFiles/ayu/messages/ayu_messages_controller.cpp
+++ b/Telegram/SourceFiles/ayu/messages/ayu_messages_controller.cpp
@@ -9,7 +9,7 @@
 
 #include "ayu/ayu_constants.h"
 #include "ayu/database/ayu_database.h"
-#include "ayu/sync/utils/telegram_helpers.h"
+#include "ayu/utils/telegram_helpers.h"
 
 #include "base/unixtime.h"
 
diff --git a/Telegram/SourceFiles/ayu/sync/ayu_sync_controller.cpp b/Telegram/SourceFiles/ayu/sync/ayu_sync_controller.cpp
index 082c2f8f9..f61298d09 100644
--- a/Telegram/SourceFiles/ayu/sync/ayu_sync_controller.cpp
+++ b/Telegram/SourceFiles/ayu/sync/ayu_sync_controller.cpp
@@ -9,7 +9,7 @@
 #include "ayu/libs/process.hpp"
 #include "ayu/sync/models.h"
 #include "ayu/sync/utils/process_utils.hpp"
-#include "ayu/sync/utils/telegram_helpers.h"
+#include "ayu/utils/telegram_helpers.h"
 #include "data/data_session.h"
 #include "history/history.h"
 
diff --git a/Telegram/SourceFiles/ayu/ui/ayu_icons.style b/Telegram/SourceFiles/ayu/ui/ayu_icons.style
index 4e5029ed1..a5cfa5595 100644
--- a/Telegram/SourceFiles/ayu/ui/ayu_icons.style
+++ b/Telegram/SourceFiles/ayu/ui/ayu_icons.style
@@ -5,3 +5,4 @@ ayuGhostIcon: icon {{ "ayu/ghost", menuIconColor }};
 ayuMenuIcon: icon {{ "ayu/ayu_menu", menuIconColor }};
 ayuLReadMenuIcon: icon {{ "ayu/lread", menuIconColor }};
 ayuSReadMenuIcon: icon {{ "ayu/sread", menuIconColor }};
+ayuStreamerModeMenuIcon: icon {{ "ayu/streamer", menuIconColor }};
diff --git a/Telegram/SourceFiles/ayu/ui/settings/settings_ayu.cpp b/Telegram/SourceFiles/ayu/ui/settings/settings_ayu.cpp
index 0f06e22b3..6f5f912cc 100644
--- a/Telegram/SourceFiles/ayu/ui/settings/settings_ayu.cpp
+++ b/Telegram/SourceFiles/ayu/ui/settings/settings_ayu.cpp
@@ -15,11 +15,15 @@
 #include "lang_auto.h"
 #include "mainwindow.h"
 #include "api/api_blocked_peers.h"
+
+#include "ayu/features/streamer_mode/streamer_mode.h"
+
 #include "boxes/connection_box.h"
 #include "core/application.h"
 #include "data/data_session.h"
 #include "lang/lang_instance.h"
 #include "main/main_session.h"
+#include "media/system_media_controls_manager.h"
 #include "platform/platform_specific.h"
 #include "settings/settings_common.h"
 #include "storage/localstorage.h"
@@ -31,6 +35,7 @@
 #include "styles/style_widgets.h"
 
 #include "ui/painter.h"
+#include "ui/boxes/confirm_box.h"
 #include "ui/boxes/single_choice_box.h"
 #include "ui/text/text_utilities.h"
 #include "ui/toast/toast.h"
@@ -45,6 +50,17 @@ constexpr auto GhostModeOptionsCount = 5;
 
 class PainterHighQualityEnabler;
 
+const char kStreamerMode[] =
+	"streamer-mode";
+
+base::options::toggle StreamerMode({
+	.id = kStreamerMode,
+	.name = "Show streamer mode toggles",
+	.description = "Streamer mode completely hides AyuGram windows and notifications from capture apps.",
+	.scope = base::options::windows,
+	.restartRequired = true
+});
+
 not_null<Ui::RpWidget*> AddInnerToggle(
 	not_null<Ui::VerticalLayout*> container,
 	const style::SettingsButton& st,
@@ -112,7 +128,7 @@ not_null<Ui::RpWidget*> AddInnerToggle(
 		) | start_with_next([=](const QRect& r)
 		{
 			const auto w = st::rightsButtonToggleWidth;
-			constexpr auto kLineWidth = static_cast<int>(1);
+			constexpr auto kLineWidth = 1;
 			toggleButton->setGeometry(
 				r.x() + r.width() - w,
 				r.y(),
@@ -267,6 +283,69 @@ namespace Settings
 		setupContent(controller);
 	}
 
+	void Ayu::AddPlatformOption(
+		not_null<Window::SessionController*> window,
+		not_null<Ui::VerticalLayout*> container,
+		base::options::option<bool>& option,
+		rpl::producer<> resetClicks)
+	{
+		auto& lifetime = container->lifetime();
+		const auto name = option.name().isEmpty() ? option.id() : option.name();
+		const auto toggles = lifetime.make_state<rpl::event_stream<bool>>();
+		std::move(
+			resetClicks
+		) | rpl::map_to(
+			option.defaultValue()
+		) | start_to_stream(*toggles, lifetime);
+
+		const auto button = AddButton(
+			container,
+			rpl::single(name),
+			(option.relevant()
+				 ? st::settingsButtonNoIcon
+				 : st::settingsOptionDisabled)
+		)->toggleOn(toggles->events_starting_with(option.value()));
+
+		const auto restarter = (option.relevant() && option.restartRequired())
+			                       ? button->lifetime().make_state<base::Timer>()
+			                       : nullptr;
+		if (restarter)
+		{
+			restarter->setCallback([=]
+			{
+				window->show(Ui::MakeConfirmBox({
+					.text = tr::lng_settings_need_restart(),
+					.confirmed = [] { Core::Restart(); },
+					.confirmText = tr::lng_settings_restart_now(),
+					.cancelText = tr::lng_settings_restart_later(),
+				}));
+			});
+		}
+		button->toggledChanges(
+		) | start_with_next([=, &option](bool toggled)
+		{
+			if (!option.relevant() && toggled != option.defaultValue())
+			{
+				toggles->fire_copy(option.defaultValue());
+				window->showToast(
+					tr::lng_settings_experimental_irrelevant(tr::now));
+				return;
+			}
+			option.set(toggled);
+			if (restarter)
+			{
+				restarter->callOnce(st::settingsButtonNoIcon.toggle.duration);
+			}
+		}, container->lifetime());
+
+		const auto& description = option.description();
+		if (!description.isEmpty())
+		{
+			AddSkip(container);
+			AddDividerText(container, rpl::single(description));
+		}
+	}
+
 	void Ayu::SetupGhostEssentials(not_null<Ui::VerticalLayout*> container)
 	{
 		auto settings = &AyuSettings::getInstance();
@@ -333,11 +412,6 @@ namespace Settings
 			std::function<void(bool)> callback;
 		};
 
-		struct LabeledEntryGroup
-		{
-			std::vector<NestedEntry> nested;
-		};
-
 		std::vector checkboxes{
 			NestedEntry{
 				tr::ayu_DontReadMessages(tr::now), !settings->sendReadMessages, [=](bool enabled)
@@ -791,6 +865,13 @@ namespace Settings
 		}, container->lifetime());
 	}
 
+	void Ayu::SetupExperimental(not_null<Ui::VerticalLayout*> container,
+	                            not_null<Window::SessionController*> controller)
+	{
+		AddSubsectionTitle(container, tr::lng_settings_experimental());
+		AddPlatformOption(controller, container, StreamerMode, rpl::producer<>());
+	}
+
 	void Ayu::SetupAyuGramSettings(not_null<Ui::VerticalLayout*> container,
 	                               not_null<Window::SessionController*> controller)
 	{
@@ -818,7 +899,7 @@ namespace Settings
 		AddDividerText(container, tr::ayu_SettingsCustomizationHint());
 
 		// todo: compilation flag
-		if (false)
+		if constexpr (false)
 		{
 			AddSkip(container);
 			SetupAyuSync(container);
@@ -831,6 +912,9 @@ namespace Settings
 		SetupSendConfirmations(container);
 		AddSkip(container);
 
+		AddDivider(container);
+		SetupExperimental(container, controller);
+
 		AddDividerText(container, tr::ayu_SettingsWatermark());
 	}
 
diff --git a/Telegram/SourceFiles/ayu/ui/settings/settings_ayu.h b/Telegram/SourceFiles/ayu/ui/settings/settings_ayu.h
index c4fa86ea5..5fc0fb787 100644
--- a/Telegram/SourceFiles/ayu/ui/settings/settings_ayu.h
+++ b/Telegram/SourceFiles/ayu/ui/settings/settings_ayu.h
@@ -7,6 +7,7 @@
 
 #pragma once
 
+#include "base/options.h"
 #include "settings/settings_common.h"
 
 class BoxContent;
@@ -18,6 +19,9 @@ namespace Window
 	class SessionController;
 } // namespace Window
 
+extern const char kStreamerMode[];
+extern base::options::toggle StreamerMode;
+
 namespace Settings
 {
 	class Ayu : public Section<Ayu>
@@ -28,6 +32,12 @@ namespace Settings
 		[[nodiscard]] rpl::producer<QString> title() override;
 
 	private:
+		void AddPlatformOption(
+			not_null<Window::SessionController*> window,
+			not_null<Ui::VerticalLayout*> container,
+			base::options::option<bool>& option,
+			rpl::producer<> resetClicks);
+
 		void SetupGhostEssentials(not_null<Ui::VerticalLayout*> container);
 
 		void SetupSpyEssentials(not_null<Ui::VerticalLayout*> container);
@@ -45,6 +55,9 @@ namespace Settings
 
 		void SetupSendConfirmations(not_null<Ui::VerticalLayout*> container);
 
+		void SetupExperimental(not_null<Ui::VerticalLayout*> container,
+		                       not_null<Window::SessionController*> controller);
+
 		void SetupAyuGramSettings(not_null<Ui::VerticalLayout*> container, not_null<Window::SessionController*> null);
 
 		void setupContent(not_null<Window::SessionController*> controller);
diff --git a/Telegram/SourceFiles/ayu/sync/utils/telegram_helpers.cpp b/Telegram/SourceFiles/ayu/utils/telegram_helpers.cpp
similarity index 97%
rename from Telegram/SourceFiles/ayu/sync/utils/telegram_helpers.cpp
rename to Telegram/SourceFiles/ayu/utils/telegram_helpers.cpp
index ea1220c7f..515f36f8a 100644
--- a/Telegram/SourceFiles/ayu/sync/utils/telegram_helpers.cpp
+++ b/Telegram/SourceFiles/ayu/utils/telegram_helpers.cpp
@@ -22,7 +22,7 @@
 
 Main::Session* getSession(ID userId)
 {
-	for (auto& [index, account] : Core::App().domain().accounts())
+	for (const auto& [index, account] : Core::App().domain().accounts())
 	{
 		if (const auto session = account->maybeSession())
 		{
diff --git a/Telegram/SourceFiles/ayu/sync/utils/telegram_helpers.h b/Telegram/SourceFiles/ayu/utils/telegram_helpers.h
similarity index 100%
rename from Telegram/SourceFiles/ayu/sync/utils/telegram_helpers.h
rename to Telegram/SourceFiles/ayu/utils/telegram_helpers.h
diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp
index 6b0751616..59f7e5c87 100644
--- a/Telegram/SourceFiles/data/data_user.cpp
+++ b/Telegram/SourceFiles/data/data_user.cpp
@@ -28,7 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 // AyuGram includes
 #include "ayu/ayu_settings.h"
-#include "ayu/sync/utils/telegram_helpers.h"
+#include "ayu/utils/telegram_helpers.h"
 
 
 namespace {
diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
index 957679aba..fbf5e385a 100644
--- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
+++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
@@ -110,6 +110,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 #include <kurlmimedata.h>
 
+// AyuGram includes
+#include "ayu/features/streamer_mode/streamer_mode.h"
+
+
 namespace Media {
 namespace View {
 namespace {
@@ -3250,6 +3254,13 @@ void OverlayWidget::activate() {
 	setFocus();
 	QApplication::setActiveWindow(_window);
 	setFocus();
+
+	if (AyuFeatures::StreamerMode::isEnabled())
+	{
+		AyuFeatures::StreamerMode::hideWidgetWindow(_window);
+	} else {
+		AyuFeatures::StreamerMode::showWidgetWindow(_window);
+	}
 }
 
 void OverlayWidget::show(OpenRequest request) {
diff --git a/Telegram/SourceFiles/media/view/media_view_pip.cpp b/Telegram/SourceFiles/media/view/media_view_pip.cpp
index dbee087b0..c8e7d7241 100644
--- a/Telegram/SourceFiles/media/view/media_view_pip.cpp
+++ b/Telegram/SourceFiles/media/view/media_view_pip.cpp
@@ -42,6 +42,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include <QtGui/QScreen>
 #include <QtWidgets/QApplication>
 
+// AyuGram includes
+#include "ayu/features/streamer_mode/streamer_mode.h"
+
+
 namespace Media {
 namespace View {
 namespace {
@@ -957,6 +961,13 @@ void Pip::setupPanel() {
 	_panel.setPosition(Deserialize(_delegate->pipLoadGeometry()));
 	_panel.widget()->show();
 
+	if (AyuFeatures::StreamerMode::isEnabled())
+	{
+		AyuFeatures::StreamerMode::hideWidgetWindow(_panel.widget());
+	} else {
+		AyuFeatures::StreamerMode::showWidgetWindow(_panel.widget());
+	}
+
 	_panel.saveGeometryRequests(
 	) | rpl::start_with_next([=] {
 		saveGeometry();
diff --git a/Telegram/SourceFiles/tray.cpp b/Telegram/SourceFiles/tray.cpp
index 681cc8898..5f82f4b46 100644
--- a/Telegram/SourceFiles/tray.cpp
+++ b/Telegram/SourceFiles/tray.cpp
@@ -13,7 +13,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "platform/platform_specific.h"
 
 #include <QtWidgets/QApplication>
-#include <ayu/ayu_settings.h>
+
+// AyuGram includes
+#include "ayu/ayu_settings.h"
+#include "ayu/ui/settings/settings_ayu.h"
+#include "ayu/features/streamer_mode/streamer_mode.h"
+
 
 namespace Core {
 
@@ -96,10 +101,9 @@ void Tray::rebuildMenu() {
 		bool ghostModeEnabled = AyuSettings::get_ghostModeEnabled();
 
 		return ghostModeEnabled
-			       ? tr::ayu_DisableGhostMode(tr::now)
-			       : tr::ayu_EnableGhostMode(tr::now);
+			       ? tr::ayu_DisableGhostModeTray(tr::now)
+			       : tr::ayu_EnableGhostModeTray(tr::now);
 	});
-
 	_tray.addAction(std::move(turnGhostModeText), [=]
 	{
 		auto settings = &AyuSettings::getInstance();
@@ -110,6 +114,24 @@ void Tray::rebuildMenu() {
 		AyuSettings::save();
 	});
 
+	if (StreamerMode.value()) {
+		auto turnStreamerModeText = _textUpdates.events(
+		) | rpl::map([=] {
+			bool streamerModeEnabled = AyuFeatures::StreamerMode::isEnabled();
+
+			return streamerModeEnabled
+			       ? tr::ayu_DisableStreamerModeTray(tr::now)
+			       : tr::ayu_EnableStreamerModeTray(tr::now);
+		});
+		_tray.addAction(std::move(turnStreamerModeText), [=] {
+			if (AyuFeatures::StreamerMode::isEnabled()) {
+				AyuFeatures::StreamerMode::disable();
+			} else {
+				AyuFeatures::StreamerMode::enable();
+			}
+		});
+	}
+
 	auto quitText = _textUpdates.events(
 	) | rpl::map([=]
 	{
diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp
index f5c52ddf7..ea758acde 100644
--- a/Telegram/SourceFiles/window/notifications_manager_default.cpp
+++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp
@@ -43,6 +43,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include <QtGui/QGuiApplication>
 #include <QtGui/QScreen>
 
+// AyuGram includes
+#include "ayu/features/streamer_mode/streamer_mode.h"
+
+
 namespace Window {
 namespace Notifications {
 namespace Default {
@@ -699,6 +703,11 @@ Notification::Notification(
 	}, lifetime());
 
 	show();
+
+	if (AyuFeatures::StreamerMode::isEnabled())
+	{
+		AyuFeatures::StreamerMode::hideWidgetWindow(this);
+	}
 }
 
 void Notification::updateReplyGeometry() {
@@ -1239,6 +1248,11 @@ HideAllButton::HideAllButton(
 	}, lifetime());
 
 	show();
+
+	if (AyuFeatures::StreamerMode::isEnabled())
+	{
+		AyuFeatures::StreamerMode::hideWidgetWindow(this);
+	}
 }
 
 void HideAllButton::startHiding() {
diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp
index 1e7676e7f..2b3e3fce9 100644
--- a/Telegram/SourceFiles/window/window_main_menu.cpp
+++ b/Telegram/SourceFiles/window/window_main_menu.cpp
@@ -82,10 +82,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include <QtGui/QGuiApplication>
 #include <QtGui/QClipboard>
 
+// AyuGram includes
 #include "ayu/ayu_settings.h"
+#include "ayu/ui/settings/settings_ayu.h"
+#include "ayu/features/streamer_mode/streamer_mode.h"
 #include "ayu/ui/boxes/confirmation_box.h"
 #include "styles/style_ayu_icons.h"
 
+
 namespace Window {
 namespace {
 
@@ -908,6 +912,22 @@ void MainMenu::setupMenu() {
 		}, _ghostModeToggle->lifetime());
 	}
 
+	if (StreamerMode.value()) {
+		_streamerModeToggle = addAction(
+			    tr::ayu_StreamerModeToggle(),
+			    { &st::ayuStreamerModeMenuIcon }
+	    )->toggleOn(rpl::single(AyuFeatures::StreamerMode::isEnabled()));
+
+		_streamerModeToggle->toggledChanges(
+		) | rpl::start_with_next([=](bool enabled) {
+			if (enabled) {
+				AyuFeatures::StreamerMode::enable();
+			} else {
+				AyuFeatures::StreamerMode::disable();
+			}
+		}, _streamerModeToggle->lifetime());
+	}
+
 	Core::App().settings().systemDarkModeValue(
 	) | rpl::start_with_next([=](std::optional<bool> darkMode) {
 		const auto darkModeEnabled
diff --git a/Telegram/SourceFiles/window/window_main_menu.h b/Telegram/SourceFiles/window/window_main_menu.h
index 25e0c7d9e..3d6b105d6 100644
--- a/Telegram/SourceFiles/window/window_main_menu.h
+++ b/Telegram/SourceFiles/window/window_main_menu.h
@@ -95,7 +95,8 @@ private:
 	not_null<Ui::FlatLabel*> _telegram;
 	not_null<Ui::FlatLabel*> _version;
 	QPointer<Ui::SettingsButton> _nightThemeToggle;
-    QPointer<Ui::SettingsButton> _ghostModeToggle;
+	QPointer<Ui::SettingsButton> _ghostModeToggle;
+	QPointer<Ui::SettingsButton> _streamerModeToggle;
 	rpl::event_stream<bool> _nightThemeSwitches;
 	base::Timer _nightThemeSwitch;
 	base::unique_qptr<Ui::PopupMenu> _contextMenu;