Subject: Address macOS hangs in Tcl_WaitForEvent.

From: culler <culler>
Date: Sat, 6 Jun 2020 21:23:50 +0000

---
 macosx/tclMacOSXNotify.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c
index 9b7bd1a..21d95e5 100644
--- a/macosx/tclMacOSXNotify.c
+++ b/macosx/tclMacOSXNotify.c
@@ -1243,6 +1243,13 @@ Tcl_WaitForEvent(
 	     */
 
 	    polling = 1;
+
+	    /*
+	     * Set a small positive waitTime so that when the runloop is started
+	     * it will process all of its sources.
+	     */
+
+	    waitTime = 0.005;
 	}
     }
 
@@ -1264,11 +1271,16 @@ Tcl_WaitForEvent(
 
     runLoopRunning = tsdPtr->runLoopRunning;
     tsdPtr->runLoopRunning = 1;
-    runLoopStatus = CFRunLoopRunInMode(tsdPtr->runLoopServicingEvents ||
-	    runLoopRunning ? tclEventsOnlyRunLoopMode : kCFRunLoopDefaultMode,
-	    waitTime, TRUE);
+    runLoopStatus = CFRunLoopRunInMode(
+	tsdPtr->runLoopServicingEvents || runLoopRunning ?
+	tclEventsOnlyRunLoopMode : kCFRunLoopDefaultMode,
+	waitTime, TRUE);
     tsdPtr->runLoopRunning = runLoopRunning;
 
+    if (polling) {
+    	return tsdPtr->runLoopSourcePerformed ? 0 : 1;
+    }
+
     LOCK_NOTIFIER_TSD;
     tsdPtr->polling = 0;
     UNLOCK_NOTIFIER_TSD;
@@ -1384,7 +1396,6 @@ UpdateWaitingListAndServiceEvents(
     void *info)
 {
     ThreadSpecificData *tsdPtr = info;
-
     if (tsdPtr->sleeping) {
 	return;
     }
@@ -1407,16 +1418,6 @@ UpdateWaitingListAndServiceEvents(
 	}
 	tsdPtr->runLoopNestingLevel--;
 	break;
-    case kCFRunLoopBeforeWaiting:
-	if (tsdPtr->runLoopTimer && !tsdPtr->runLoopServicingEvents &&
-		(tsdPtr->runLoopNestingLevel > 1
-			|| !tsdPtr->runLoopRunning)) {
-	    tsdPtr->runLoopServicingEvents = 1;
-            /* This call seems to simply force event processing through and prevents hangups that have long been observed with Tk-Cocoa.  */
-	    Tcl_ServiceAll();
-	    tsdPtr->runLoopServicingEvents = 0;
-	}
-	break;
     default:
 	break;
     }
-- 
cgit v0.12