/* 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; } // namespace Core bool InternalPassportLink(const QString &url); bool StartUrlRequiresActivate(const QString &url); class Application : public QApplication, private QAbstractNativeEventFilter { Q_OBJECT public: Application(not_null launcher, int &argc, char **argv); int execute(); void createMessenger(); void refreshGlobalProxy(); 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(); ~Application(); signals: void adjustSingleTimers(); // Single instance application public slots: void socketConnected(); void socketError(QLocalSocket::LocalSocketError e); void socketDisconnected(); void socketWritten(qint64 bytes); void socketReading(); void newInstanceConnected(); void readClients(); void removeClients(); void startApplication(); // will be done in exec() void closeApplication(); // will be done in aboutToQuit() protected: bool event(QEvent *e) override; private: typedef QPair LocalClient; typedef QList LocalClients; struct PostponedCall { int loopNestingLevel = 0; FnMut callable; }; void incrementEventNestingLevel(); void decrementEventNestingLevel(); bool nativeEventFilter( const QByteArray &eventType, void *message, long *result) override; void processPostponedCalls(int level); 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 _messengerInstance; QString _localServerName, _localSocketReadData; QLocalServer _localServer; QLocalSocket _localSocket; LocalClients _localClients; bool _secondInstance = false; void singleInstanceChecked(); private: std::unique_ptr _updateChecker; }; namespace Core { inline Application &App() { Expects(QCoreApplication::instance() != nullptr); return *static_cast(QCoreApplication::instance()); } } // namespace Core namespace Sandbox { QRect availableGeometry(); QRect screenGeometry(const QPoint &p); void setActiveWindow(QWidget *window); bool isSavingSession(); void execExternal(const QString &cmd); void adjustSingleTimers(); void refreshGlobalProxy(); void connect(const char *signal, QObject *object, const char *method); void launch(); } // namespace Sandbox