tdesktop/Telegram/SourceFiles/core/sandbox.h

139 lines
3.3 KiB
C
Raw Normal View History

/*
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
2019-11-13 14:12:04 +00:00
#include "mtproto/mtproto_proxy_data.h"
2022-01-24 16:33:30 +00:00
#include "base/qt/qt_common_adapters.h"
2019-11-13 14:12:04 +00:00
2019-09-04 07:19:15 +00:00
#include <QtWidgets/QApplication>
#include <QtNetwork/QLocalServer>
#include <QtNetwork/QLocalSocket>
#include <QtCore/QAbstractNativeEventFilter>
class QLockFile;
namespace Core {
class UpdateChecker;
class Application;
class Sandbox final
: public QApplication
, private QAbstractNativeEventFilter {
private:
auto createEventNestingLevel() {
incrementEventNestingLevel();
return gsl::finally([=] { decrementEventNestingLevel(); });
}
public:
Sandbox(int &argc, char **argv);
Sandbox(const Sandbox &other) = delete;
Sandbox &operator=(const Sandbox &other) = delete;
int start();
2018-04-23 10:24:03 +00:00
void refreshGlobalProxy();
void postponeCall(FnMut<void()> &&callable);
bool notify(QObject *receiver, QEvent *e) override;
template <typename Callable>
auto customEnterFromEventLoop(Callable &&callable) {
registerEnterFromEventLoop();
const auto wrap = createEventNestingLevel();
return callable();
}
2019-03-07 13:23:19 +00:00
rpl::producer<> widgetUpdateRequests() const;
2019-11-13 14:12:04 +00:00
MTP::ProxyData sandboxProxy() const;
static Sandbox &Instance() {
2019-09-04 07:19:15 +00:00
Expects(QCoreApplication::instance() != nullptr);
2019-09-04 07:19:15 +00:00
return *static_cast<Sandbox*>(QCoreApplication::instance());
}
2021-11-08 13:33:18 +00:00
static void QuitWhenStarted();
~Sandbox();
protected:
bool event(QEvent *e) override;
private:
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
typedef QList<LocalClient> LocalClients;
struct PostponedCall {
int loopNestingLevel = 0;
FnMut<void()> callable;
};
2019-07-10 15:03:15 +00:00
bool notifyOrInvoke(QObject *receiver, QEvent *e);
void closeApplication(); // will be done in aboutToQuit()
void checkForQuit(); // will be done in exec()
2020-06-29 17:37:35 +00:00
void checkForEmptyLoopNestingLevel();
void registerEnterFromEventLoop();
void incrementEventNestingLevel();
void decrementEventNestingLevel();
bool nativeEventFilter(
const QByteArray &eventType,
void *message,
base::NativeEventResult *result) override;
void processPostponedCalls(int level);
void singleInstanceChecked();
void launchApplication();
2019-02-10 16:29:55 +00:00
void setupScreenScale();
2023-01-09 12:08:34 +00:00
// Return window id for activation.
uint64 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<int> _previousLoopNestingLevels;
std::vector<PostponedCall> _postponedCalls;
std::unique_ptr<Application> _application;
QString _localServerName, _localSocketReadData;
QLocalServer _localServer;
QLocalSocket _localSocket;
LocalClients _localClients;
std::unique_ptr<QLockFile> _lockFile;
2016-04-14 19:24:42 +00:00
bool _secondInstance = false;
2021-11-08 13:33:18 +00:00
bool _started = false;
static bool QuitOnStartRequested;
std::unique_ptr<UpdateChecker> _updateChecker;
QByteArray _lastCrashDump;
2019-11-13 14:12:04 +00:00
MTP::ProxyData _sandboxProxy;
2019-03-07 13:23:19 +00:00
rpl::event_stream<> _widgetUpdateRequests;
std::unique_ptr<QThread> _deadlockDetector;
};
} // namespace Core