APPROVE COMMIT 21.5
This is a version of the earlier patch with cleaner comments.
diff -r 27b87c12a3ab -r 4dcbe828fa9c src/ChangeLog
--- a/src/ChangeLog	Fri Dec 29 10:50:19 2017 +0000
+++ b/src/ChangeLog	Fri Dec 29 20:45:41 2017 +0900
@@ -1,3 +1,8 @@
+2017-12-29  Stephen J. Turnbull  <stephen(a)xemacs.org>
+
+	* event-gtk.c (emacs_gtk_drain_queue):
+	Work around gdk_events_pending lossage.
+
 2017-12-29  Aidan Kehoe  <kehoea(a)parhasard.net>
 
 	* doprnt.c (emacs_vsprintf_string):
diff -r 27b87c12a3ab -r 4dcbe828fa9c src/event-gtk.c
--- a/src/event-gtk.c	Fri Dec 29 10:50:19 2017 +0000
+++ b/src/event-gtk.c	Fri Dec 29 20:45:41 2017 +0900
@@ -1699,12 +1699,21 @@
      it on the queue, then we go into Fnext_event(), which calls
      emacs_gtk_drain_queue().  But gtk_events_pending() will always return
      TRUE if there are file-descriptor (aka our process) events
-     pending.  Using GDK_events_pending() only shows us windowing
-     system events.
+     pending.
+     GDK_events_pending() documentation says it only shows us
+     windowing system events, but in GTK3 on Mac OS X "High Sierra" at least
+     it returns true even though gdk_event_peek returns NULL.  So we use the
+     the latter.
   */
   if (gdk_display_get_default ())
-    while (gdk_events_pending ())
-      gtk_main_iteration_do (FALSE);
+    {
+      GdkEvent *e = gdk_event_peek();
+      while (e) {
+	gtk_main_iteration_do (FALSE);
+	gdk_event_free(e);
+	e = gdk_event_peek();
+      }
+    }
 
 #ifdef HAVE_TTY
   drain_tty_devices ();