From d1be4c6d96cedc5372112467a2a513777acfaee4 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Tue, 25 Dec 2018 14:11:10 +0400
Subject: [PATCH] Fix crash with event loop nesting.

---
 Telegram/SourceFiles/application.cpp           | 18 +++++++++++++++---
 .../platform/linux/specific_linux.cpp          |  4 ----
 .../SourceFiles/platform/mac/specific_mac.mm   |  4 ----
 .../SourceFiles/platform/platform_specific.h   |  2 --
 .../SourceFiles/platform/win/specific_win.cpp  | 15 ---------------
 5 files changed, 15 insertions(+), 28 deletions(-)

diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp
index eccdb2f6f..9a10ab15a 100644
--- a/Telegram/SourceFiles/application.cpp
+++ b/Telegram/SourceFiles/application.cpp
@@ -390,7 +390,20 @@ void Application::refreshGlobalProxy() {
 
 void Application::postponeCall(FnMut<void()> &&callable) {
 	Expects(callable != nullptr);
-	Expects(_eventNestingLevel > _loopNestingLevel);
+	Expects(_eventNestingLevel >= _loopNestingLevel);
+
+	// _loopNestingLevel == _eventNestingLevel means that we had a
+	// native event in a nesting loop that didn't get a notify() call
+	// after. That means we already have exited the nesting loop and
+	// there must not be any postponed calls with that nesting level.
+	if (_loopNestingLevel == _eventNestingLevel) {
+		Assert(_postponedCalls.empty()
+			|| _postponedCalls.back().loopNestingLevel < _loopNestingLevel);
+		Assert(!_previousLoopNestingLevels.empty());
+
+		_loopNestingLevel = _previousLoopNestingLevels.back();
+		_previousLoopNestingLevels.pop_back();
+	}
 
 	_postponedCalls.push_back({
 		_loopNestingLevel,
@@ -430,8 +443,7 @@ bool Application::nativeEventFilter(
 		const QByteArray &eventType,
 		void *message,
 		long *result) {
-	if (_eventNestingLevel > _loopNestingLevel
-		&& Platform::NativeEventNestsLoop(message)) {
+	if (_eventNestingLevel > _loopNestingLevel) {
 		_previousLoopNestingLevels.push_back(_loopNestingLevel);
 		_loopNestingLevel = _eventNestingLevel;
 	}
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
index 401cbefd5..11b730df1 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
@@ -488,10 +488,6 @@ void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCal
 void OpenSystemSettingsForPermission(PermissionType type) {
 }
 
-bool NativeEventNestsLoop(void *message) {
-	return true;
-}
-
 namespace ThirdParty {
 
 void start() {
diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.mm b/Telegram/SourceFiles/platform/mac/specific_mac.mm
index b57064e4f..c0726628b 100644
--- a/Telegram/SourceFiles/platform/mac/specific_mac.mm
+++ b/Telegram/SourceFiles/platform/mac/specific_mac.mm
@@ -332,10 +332,6 @@ void OpenSystemSettingsForPermission(PermissionType type) {
 #endif // OS_MAC_OLD
 }
 
-bool NativeEventNestsLoop(void *message) {
-	return true;
-}
-
 } // namespace Platform
 
 void psNewVersion() {
diff --git a/Telegram/SourceFiles/platform/platform_specific.h b/Telegram/SourceFiles/platform/platform_specific.h
index a9c8acc2b..dfb625a50 100644
--- a/Telegram/SourceFiles/platform/platform_specific.h
+++ b/Telegram/SourceFiles/platform/platform_specific.h
@@ -35,8 +35,6 @@ PermissionStatus GetPermissionStatus(PermissionType type);
 void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback);
 void OpenSystemSettingsForPermission(PermissionType type);
 
-bool NativeEventNestsLoop(void *message);
-
 QString SystemLanguage();
 QString SystemCountry();
 
diff --git a/Telegram/SourceFiles/platform/win/specific_win.cpp b/Telegram/SourceFiles/platform/win/specific_win.cpp
index 31cbd7c4a..683097d6a 100644
--- a/Telegram/SourceFiles/platform/win/specific_win.cpp
+++ b/Telegram/SourceFiles/platform/win/specific_win.cpp
@@ -657,21 +657,6 @@ void OpenSystemSettingsForPermission(PermissionType type) {
 	}
 }
 
-bool NativeEventNestsLoop(void *message) {
-	const auto code = static_cast<const MSG*>(message)->message;
-	if (code > WM_NULL && code <= WM_GETMINMAXINFO) {
-		return true;
-	} else if (code >= WM_NCCREATE && code <= WM_NCXBUTTONDBLCLK) {
-		return true;
-	} else if (code == WM_WINDOWPOSCHANGING
-		|| code == WM_WINDOWPOSCHANGED
-		|| code == WM_STYLECHANGING
-		|| code == WM_STYLECHANGED) {
-		return true;
-	}
-	return false;
-}
-
 } // namespace Platform
 
 void psNewVersion() {