/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once namespace Core { class Launcher; class UpdateChecker; class Application; class Sandbox final : public QApplication , private QAbstractNativeEventFilter { public: Sandbox(not_null launcher, int &argc, char **argv); Sandbox(const Sandbox &other) = delete; Sandbox &operator=(const Sandbox &other) = delete; int start(); void refreshGlobalProxy(); uint64 installationTag() const; void postponeCall(FnMut &&callable); bool notify(QObject *receiver, QEvent *e) override; void registerEnterFromEventLoop(); auto createEventNestingLevel() { incrementEventNestingLevel(); return gsl::finally([=] { decrementEventNestingLevel(); }); } void activateWindowDelayed(not_null widget); void pauseDelayedWindowActivations(); void resumeDelayedWindowActivations(); rpl::producer<> widgetUpdateRequests() const; ProxyData sandboxProxy() const; static Sandbox &Instance() { Expects(QApplication::instance() != nullptr); return *static_cast(QApplication::instance()); } ~Sandbox(); protected: bool event(QEvent *e) override; private: typedef QPair LocalClient; typedef QList LocalClients; struct PostponedCall { int loopNestingLevel = 0; FnMut callable; }; void closeApplication(); // will be done in aboutToQuit() void checkForQuit(); // will be done in exec() void incrementEventNestingLevel(); void decrementEventNestingLevel(); bool nativeEventFilter( const QByteArray &eventType, void *message, long *result) override; void processPostponedCalls(int level); void singleInstanceChecked(); void launchApplication(); void setupScreenScale(); void execExternal(const QString &cmd); // Single instance application void socketConnected(); void socketError(QLocalSocket::LocalSocketError e); void socketDisconnected(); void socketWritten(qint64 bytes); void socketReading(); void newInstanceConnected(); void readClients(); void removeClients(); const Qt::HANDLE _mainThreadId = nullptr; int _eventNestingLevel = 0; int _loopNestingLevel = 0; std::vector _previousLoopNestingLevels; std::vector _postponedCalls; QPointer _windowForDelayedActivation; bool _delayedActivationsPaused = false; not_null _launcher; std::unique_ptr _application; QString _localServerName, _localSocketReadData; QLocalServer _localServer; QLocalSocket _localSocket; LocalClients _localClients; bool _secondInstance = false; std::unique_ptr _updateChecker; QByteArray _lastCrashDump; ProxyData _sandboxProxy; rpl::event_stream<> _widgetUpdateRequests; }; } // namespace Core