application.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/timer.h"
  9. #include "mtproto/mtproto_auth_key.h"
  10. #include "mtproto/mtproto_proxy_data.h"
  11. #include "window/window_separate_id.h"
  12. class History;
  13. namespace base {
  14. class BatterySaving;
  15. } // namespace base
  16. namespace Platform {
  17. class Integration;
  18. } // namespace Platform
  19. namespace Storage {
  20. class Databases;
  21. } // namespace Storage
  22. namespace Window {
  23. class Controller;
  24. } // namespace Window
  25. namespace Window::Notifications {
  26. class System;
  27. } // namespace Window::Notifications
  28. namespace ChatHelpers {
  29. class EmojiKeywords;
  30. } // namespace ChatHelpers
  31. namespace Main {
  32. class Domain;
  33. class Account;
  34. class Session;
  35. } // namespace Main
  36. namespace Iv {
  37. class Instance;
  38. class DelegateImpl;
  39. } // namespace Iv
  40. namespace Ui {
  41. namespace Animations {
  42. class Manager;
  43. } // namespace Animations
  44. namespace Emoji {
  45. class UniversalImages;
  46. } // namespace Emoji
  47. class BoxContent;
  48. } // namespace Ui
  49. namespace MTP {
  50. class Config;
  51. class Instance;
  52. class AuthKey;
  53. using AuthKeyPtr = std::shared_ptr<AuthKey>;
  54. using AuthKeysList = std::vector<AuthKeyPtr>;
  55. } // namespace MTP
  56. namespace Media {
  57. namespace Audio {
  58. class Instance;
  59. } // namespace Audio
  60. namespace View {
  61. class OverlayWidget;
  62. struct OpenRequest;
  63. } // namespace View
  64. namespace Player {
  65. class FloatController;
  66. class FloatDelegate;
  67. } // namespace Player
  68. class SystemMediaControlsManager;
  69. } // namespace Media
  70. namespace Lang {
  71. class Instance;
  72. class Translator;
  73. class CloudManager;
  74. } // namespace Lang
  75. namespace Data {
  76. struct CloudTheme;
  77. class DownloadManager;
  78. } // namespace Data
  79. namespace Stickers {
  80. class EmojiImageLoader;
  81. } // namespace Stickers
  82. namespace Export {
  83. class Manager;
  84. } // namespace Export
  85. namespace Calls {
  86. class Instance;
  87. } // namespace Calls
  88. namespace Webrtc {
  89. class Environment;
  90. } // namespace Webrtc
  91. namespace Core {
  92. struct LocalUrlHandler;
  93. class Settings;
  94. class Tray;
  95. enum class LaunchState {
  96. Running,
  97. QuitRequested,
  98. QuitProcessed,
  99. };
  100. enum class QuitReason {
  101. Default,
  102. QtQuitEvent,
  103. };
  104. extern const char kOptionSkipUrlSchemeRegister[];
  105. class Application final : public QObject {
  106. public:
  107. struct ProxyChange {
  108. MTP::ProxyData was;
  109. MTP::ProxyData now;
  110. };
  111. Application();
  112. Application(const Application &other) = delete;
  113. Application &operator=(const Application &other) = delete;
  114. ~Application();
  115. void run();
  116. [[nodiscard]] Platform::Integration &platformIntegration() const {
  117. return *_platformIntegration;
  118. }
  119. [[nodiscard]] Ui::Animations::Manager &animationManager() const {
  120. return *_animationsManager;
  121. }
  122. [[nodiscard]] Window::Notifications::System &notifications() const {
  123. Expects(_notifications != nullptr);
  124. return *_notifications;
  125. }
  126. [[nodiscard]] Data::DownloadManager &downloadManager() const {
  127. return *_downloadManager;
  128. }
  129. [[nodiscard]] Tray &tray() const {
  130. return *_tray;
  131. }
  132. [[nodiscard]] base::BatterySaving &batterySaving() const {
  133. return *_batterySaving;
  134. }
  135. // Windows interface.
  136. bool hasActiveWindow(not_null<Main::Session*> session) const;
  137. [[nodiscard]] bool savingPositionFor(
  138. not_null<Window::Controller*> window) const;
  139. [[nodiscard]] Window::Controller *findWindow(
  140. not_null<QWidget*> widget) const;
  141. [[nodiscard]] Window::Controller *activeWindow() const;
  142. [[nodiscard]] Window::Controller *activePrimaryWindow() const;
  143. [[nodiscard]] Window::Controller *separateWindowFor(
  144. Window::SeparateId id) const;
  145. Window::Controller *ensureSeparateWindowFor(
  146. Window::SeparateId id,
  147. MsgId showAtMsgId = 0);
  148. [[nodiscard]] Window::Controller *windowFor( // Doesn't auto-switch.
  149. Window::SeparateId id) const;
  150. [[nodiscard]] Window::Controller *windowForShowingHistory(
  151. not_null<PeerData*> peer) const;
  152. [[nodiscard]] Window::Controller *windowForShowingForum(
  153. not_null<Data::Forum*> forum) const;
  154. [[nodiscard]] bool closeNonLastAsync(
  155. not_null<Window::Controller*> window);
  156. void closeWindow(not_null<Window::Controller*> window);
  157. void windowActivated(not_null<Window::Controller*> window);
  158. bool closeActiveWindow();
  159. bool minimizeActiveWindow();
  160. bool toggleActiveWindowFullScreen();
  161. [[nodiscard]] QWidget *getFileDialogParent();
  162. void notifyFileDialogShown(bool shown);
  163. void checkSystemDarkMode();
  164. [[nodiscard]] bool isActiveForTrayMenu() const;
  165. void closeChatFromWindows(not_null<PeerData*> peer);
  166. void checkWindowId(not_null<Window::Controller*> window);
  167. void activate();
  168. // Media view interface.
  169. bool hideMediaView();
  170. [[nodiscard]] QPoint getPointForCallPanelCenter() const;
  171. [[nodiscard]] bool isSharingScreen() const;
  172. void startSettingsAndBackground();
  173. [[nodiscard]] Settings &settings();
  174. [[nodiscard]] const Settings &settings() const;
  175. void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay);
  176. void saveSettings();
  177. [[nodiscard]] bool canReadDefaultDownloadPath() const;
  178. [[nodiscard]] bool canSaveFileWithoutAskingForPath() const;
  179. // Fallback config and proxy.
  180. [[nodiscard]] MTP::Config &fallbackProductionConfig() const;
  181. void refreshFallbackProductionConfig(const MTP::Config &config);
  182. void constructFallbackProductionConfig(const QByteArray &serialized);
  183. void setCurrentProxy(
  184. const MTP::ProxyData &proxy,
  185. MTP::ProxyData::Settings settings);
  186. [[nodiscard]] rpl::producer<ProxyChange> proxyChanges() const;
  187. void badMtprotoConfigurationError();
  188. // Databases.
  189. [[nodiscard]] Storage::Databases &databases() {
  190. return *_databases;
  191. }
  192. // Domain component.
  193. [[nodiscard]] Main::Domain &domain() const {
  194. return *_domain;
  195. }
  196. [[nodiscard]] Main::Account &activeAccount() const;
  197. [[nodiscard]] bool someSessionExists() const;
  198. [[nodiscard]] Export::Manager &exportManager() const {
  199. return *_exportManager;
  200. }
  201. [[nodiscard]] bool exportPreventsQuit();
  202. // Main::Session component.
  203. Main::Session *maybePrimarySession() const;
  204. [[nodiscard]] int unreadBadge() const;
  205. [[nodiscard]] bool unreadBadgeMuted() const;
  206. [[nodiscard]] rpl::producer<> unreadBadgeChanges() const;
  207. // Media component.
  208. [[nodiscard]] Media::Audio::Instance &audio() {
  209. return *_audio;
  210. }
  211. [[nodiscard]] Webrtc::Environment &mediaDevices() {
  212. return *_mediaDevices;
  213. }
  214. // Langpack and emoji keywords.
  215. [[nodiscard]] Lang::Instance &langpack() {
  216. return *_langpack;
  217. }
  218. [[nodiscard]] Lang::CloudManager *langCloudManager() {
  219. return _langCloudManager.get();
  220. }
  221. [[nodiscard]] bool offerLegacyLangPackSwitch() const;
  222. [[nodiscard]] bool canApplyLangPackWithoutRestart() const;
  223. [[nodiscard]] ChatHelpers::EmojiKeywords &emojiKeywords() {
  224. return *_emojiKeywords;
  225. }
  226. [[nodiscard]] auto emojiImageLoader() const
  227. -> const crl::object_on_queue<Stickers::EmojiImageLoader> & {
  228. return _emojiImageLoader;
  229. }
  230. // Internal links.
  231. void checkStartUrl();
  232. void checkSendPaths();
  233. void checkFileOpen();
  234. bool openLocalUrl(const QString &url, QVariant context);
  235. bool openInternalUrl(const QString &url, QVariant context);
  236. [[nodiscard]] QString changelogLink() const;
  237. // Float player.
  238. void floatPlayerToggleGifsPaused(bool paused);
  239. [[nodiscard]] rpl::producer<FullMsgId> floatPlayerClosed() const;
  240. // Calls.
  241. Calls::Instance &calls() const {
  242. return *_calls;
  243. }
  244. // Iv.
  245. Iv::Instance &iv() const {
  246. return *_iv;
  247. }
  248. void logout(Main::Account *account = nullptr);
  249. void logoutWithChecks(Main::Account *account);
  250. void forceLogOut(
  251. not_null<Main::Account*> account,
  252. const TextWithEntities &explanation);
  253. [[nodiscard]] bool uploadPreventsQuit();
  254. [[nodiscard]] bool downloadPreventsQuit();
  255. void checkLocalTime();
  256. void lockByPasscode();
  257. void maybeLockByPasscode();
  258. void unlockPasscode();
  259. [[nodiscard]] bool passcodeLocked() const;
  260. rpl::producer<bool> passcodeLockChanges() const;
  261. rpl::producer<bool> passcodeLockValue() const;
  262. void checkAutoLock(crl::time lastNonIdleTime = 0);
  263. void checkAutoLockIn(crl::time time);
  264. void localPasscodeChanged();
  265. [[nodiscard]] bool preventsQuit(QuitReason reason);
  266. [[nodiscard]] crl::time lastNonIdleTime() const;
  267. void updateNonIdle();
  268. void registerLeaveSubscription(not_null<QWidget*> widget);
  269. void unregisterLeaveSubscription(not_null<QWidget*> widget);
  270. // Sandbox interface.
  271. void postponeCall(FnMut<void()> &&callable);
  272. void refreshGlobalProxy();
  273. void refreshApplicationIcon();
  274. void quitPreventFinished();
  275. void handleAppDeactivated();
  276. void handleAppActivated();
  277. [[nodiscard]] rpl::producer<bool> appDeactivatedValue() const;
  278. void materializeLocalDrafts();
  279. [[nodiscard]] rpl::producer<> materializeLocalDraftsRequests() const;
  280. void switchDebugMode();
  281. void preventOrInvoke(Fn<void()> &&callback);
  282. // Global runtime variables.
  283. void setScreenIsLocked(bool locked);
  284. bool screenIsLocked() const;
  285. static void RegisterUrlScheme();
  286. protected:
  287. bool eventFilter(QObject *object, QEvent *event) override;
  288. private:
  289. static constexpr auto kDefaultSaveDelay = crl::time(1000);
  290. friend bool IsAppLaunched();
  291. friend Application &App();
  292. void autoRegisterUrlScheme();
  293. void clearEmojiSourceImages();
  294. [[nodiscard]] auto prepareEmojiSourceImages()
  295. -> std::shared_ptr<Ui::Emoji::UniversalImages>;
  296. void startLocalStorage();
  297. void startShortcuts();
  298. void startDomain();
  299. void startEmojiImageLoader();
  300. void startSystemDarkModeViewer();
  301. void startMediaView();
  302. void startTray();
  303. void createTray();
  304. void updateWindowTitles();
  305. void setLastActiveWindow(Window::Controller *window);
  306. void showAccount(not_null<Main::Account*> account);
  307. void enumerateWindows(
  308. Fn<void(not_null<Window::Controller*>)> callback) const;
  309. void processCreatedWindow(not_null<Window::Controller*> window);
  310. void refreshApplicationIcon(Main::Session *session);
  311. friend void QuitAttempt();
  312. void quitDelayed();
  313. [[nodiscard]] bool readyToQuit();
  314. void showOpenGLCrashNotification();
  315. void clearPasscodeLock();
  316. void closeAdditionalWindows();
  317. bool openCustomUrl(
  318. const QString &protocol,
  319. const std::vector<LocalUrlHandler> &handlers,
  320. const QString &url,
  321. const QVariant &context);
  322. static Application *Instance;
  323. struct InstanceSetter {
  324. InstanceSetter(not_null<Application*> instance) {
  325. Expects(Instance == nullptr);
  326. Instance = instance;
  327. }
  328. };
  329. InstanceSetter _setter = { this };
  330. rpl::event_stream<ProxyChange> _proxyChanges;
  331. // Some fields are just moved from the declaration.
  332. struct Private;
  333. const std::unique_ptr<Private> _private;
  334. const std::unique_ptr<Platform::Integration> _platformIntegration;
  335. const std::unique_ptr<base::BatterySaving> _batterySaving;
  336. const std::unique_ptr<Webrtc::Environment> _mediaDevices;
  337. const std::unique_ptr<Storage::Databases> _databases;
  338. const std::unique_ptr<Ui::Animations::Manager> _animationsManager;
  339. crl::object_on_queue<Stickers::EmojiImageLoader> _emojiImageLoader;
  340. base::Timer _clearEmojiImageLoaderTimer;
  341. const std::unique_ptr<Media::Audio::Instance> _audio;
  342. mutable std::unique_ptr<MTP::Config> _fallbackProductionConfig;
  343. // Notifications should be destroyed before _audio, after _domain.
  344. // Mutable because is created in run() after OpenSSL is inited.
  345. std::unique_ptr<Window::Notifications::System> _notifications;
  346. using MediaControlsManager = Media::SystemMediaControlsManager;
  347. std::unique_ptr<MediaControlsManager> _mediaControlsManager;
  348. const std::unique_ptr<Data::DownloadManager> _downloadManager;
  349. const std::unique_ptr<Main::Domain> _domain;
  350. const std::unique_ptr<Export::Manager> _exportManager;
  351. const std::unique_ptr<Calls::Instance> _calls;
  352. const std::unique_ptr<Iv::Instance> _iv;
  353. base::flat_map<
  354. Window::SeparateId,
  355. std::unique_ptr<Window::Controller>> _windows;
  356. base::flat_set<not_null<Window::Controller*>> _closingAsyncWindows;
  357. std::vector<not_null<Window::Controller*>> _windowStack;
  358. Window::Controller *_lastActiveWindow = nullptr;
  359. Window::Controller *_lastActivePrimaryWindow = nullptr;
  360. Window::Controller *_windowInSettings = nullptr;
  361. std::unique_ptr<Media::View::OverlayWidget> _mediaView;
  362. const std::unique_ptr<Lang::Instance> _langpack;
  363. const std::unique_ptr<Lang::CloudManager> _langCloudManager;
  364. const std::unique_ptr<ChatHelpers::EmojiKeywords> _emojiKeywords;
  365. std::unique_ptr<Lang::Translator> _translator;
  366. QPointer<Ui::BoxContent> _badProxyDisableBox;
  367. const std::unique_ptr<Tray> _tray;
  368. std::unique_ptr<Media::Player::FloatController> _floatPlayers;
  369. rpl::lifetime _floatPlayerDelegateLifetime;
  370. bool _floatPlayerGifsPaused = false;
  371. rpl::variable<bool> _passcodeLock;
  372. bool _screenIsLocked = false;
  373. crl::time _shouldLockAt = 0;
  374. base::Timer _autoLockTimer;
  375. QStringList _filesToOpen;
  376. base::Timer _fileOpenTimer;
  377. std::optional<base::Timer> _saveSettingsTimer;
  378. struct LeaveFilter {
  379. std::vector<QPointer<QWidget>> registered;
  380. QPointer<QObject> filter;
  381. };
  382. base::flat_map<not_null<QWidget*>, LeaveFilter> _leaveFilters;
  383. rpl::event_stream<Media::View::OpenRequest> _openInMediaViewRequests;
  384. rpl::event_stream<> _materializeLocalDraftsRequests;
  385. rpl::lifetime _lifetime;
  386. crl::time _lastNonIdleTime = 0;
  387. };
  388. [[nodiscard]] bool IsAppLaunched();
  389. [[nodiscard]] Application &App();
  390. [[nodiscard]] LaunchState CurrentLaunchState();
  391. void SetLaunchState(LaunchState state);
  392. void Quit(QuitReason reason = QuitReason::Default);
  393. [[nodiscard]] bool Quitting();
  394. void Restart();
  395. } // namespace Core