 d539d9b5d2
			
		
	
	
		d539d9b5d2
		
	
	
	
	
		
			
			In libdispatch crl::on_main() implementation we bypass Application::notify() frame. So we handle event loop nesting control manually by wrapping all invokations done through crl::on_main() with the same methods we do from Application::notify().
		
			
				
	
	
		
			133 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| 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<Core::Launcher*> launcher, int &argc, char **argv);
 | |
| 
 | |
| 	int execute();
 | |
| 
 | |
| 	void createMessenger();
 | |
| 	void refreshGlobalProxy();
 | |
| 
 | |
| 	void postponeCall(FnMut<void()> &&callable);
 | |
| 	bool notify(QObject *receiver, QEvent *e) override;
 | |
| 	void registerEnterFromEventLoop();
 | |
| 	auto createEventNestingLevel() {
 | |
| 		incrementEventNestingLevel();
 | |
| 		return gsl::finally([=] { decrementEventNestingLevel(); });
 | |
| 	}
 | |
| 
 | |
| 	void activateWindowDelayed(not_null<QWidget*> 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<QLocalSocket*, QByteArray> LocalClient;
 | |
| 	typedef QList<LocalClient> LocalClients;
 | |
| 
 | |
| 	struct PostponedCall {
 | |
| 		int loopNestingLevel = 0;
 | |
| 		FnMut<void()> 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<int> _previousLoopNestingLevels;
 | |
| 	std::vector<PostponedCall> _postponedCalls;
 | |
| 
 | |
| 	QPointer<QWidget> _windowForDelayedActivation;
 | |
| 	bool _delayedActivationsPaused = false;
 | |
| 
 | |
| 	not_null<Core::Launcher*> _launcher;
 | |
| 	std::unique_ptr<Messenger> _messengerInstance;
 | |
| 
 | |
| 	QString _localServerName, _localSocketReadData;
 | |
| 	QLocalServer _localServer;
 | |
| 	QLocalSocket _localSocket;
 | |
| 	LocalClients _localClients;
 | |
| 	bool _secondInstance = false;
 | |
| 
 | |
| 	void singleInstanceChecked();
 | |
| 
 | |
| private:
 | |
| 	std::unique_ptr<Core::UpdateChecker> _updateChecker;
 | |
| 
 | |
| };
 | |
| 
 | |
| namespace Core {
 | |
| 
 | |
| inline Application &App() {
 | |
| 	Expects(QCoreApplication::instance() != nullptr);
 | |
| 
 | |
| 	return *static_cast<Application*>(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
 |