From 37c12f688751bcc6c13ca455d52451c2833aa457 Mon Sep 17 00:00:00 2001
From: fvogel <fvogelnew1@free.fr>
Date: Fri, 19 Jan 2018 20:54:18 +0000
Subject: [PATCH 121/693] Latest fix proposal from Christian Werner: revert the
 two previous commits and add XSync() just before the garbage collector, which
 minimizes the number of XSync() calls, therefore optimizing performance while
 still fixing the bug.

---
 generic/tkError.c   | 28 ++++++++++++++++++----------
 unix/tkUnixColor.c  |  1 -
 unix/tkUnixEmbed.c  |  3 ---
 unix/tkUnixFocus.c  |  1 -
 unix/tkUnixRFont.c  |  4 ----
 unix/tkUnixSelect.c |  3 ---
 unix/tkUnixSend.c   |  1 -
 unix/tkUnixWm.c     |  9 ++-------
 8 files changed, 20 insertions(+), 30 deletions(-)

diff --git a/generic/tkError.c b/generic/tkError.c
index fc223e6b3..277d7f0e0 100644
--- a/generic/tkError.c
+++ b/generic/tkError.c
@@ -82,8 +82,8 @@ Tk_CreateErrorHandler(
 				 * errors. */
     ClientData clientData)	/* Arbitrary value to pass to errorProc. */
 {
-    register TkErrorHandler *errorPtr;
-    register TkDisplay *dispPtr;
+    TkErrorHandler *errorPtr;
+    TkDisplay *dispPtr;
 
     /*
      * Find the display. If Tk doesn't know about this display then it's an
@@ -147,8 +147,8 @@ Tk_DeleteErrorHandler(
     Tk_ErrorHandler handler)	/* Token for handler to delete; was previous
 				 * return value from Tk_CreateErrorHandler. */
 {
-    register TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
-    register TkDisplay *dispPtr = errorPtr->dispPtr;
+    TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
+    TkDisplay *dispPtr = errorPtr->dispPtr;
 
     errorPtr->lastRequest = NextRequest(dispPtr->display) - 1;
 
@@ -166,12 +166,20 @@ Tk_DeleteErrorHandler(
 
     dispPtr->deleteCount += 1;
     if (dispPtr->deleteCount >= 10) {
-	register TkErrorHandler *prevPtr;
+	TkErrorHandler *prevPtr;
 	TkErrorHandler *nextPtr;
-	int lastSerial;
+	int lastSerial = LastKnownRequestProcessed(dispPtr->display);
 
+	/*
+	 * Last chance to catch errors for this handler: if no event/error
+	 * processing took place to follow up the end of this error handler
+	 * we need a round trip with the X server now.
+	 */
+
+	if (errorPtr->lastRequest > (unsigned long) lastSerial) {
+	    XSync(dispPtr->display, False);
+	}
 	dispPtr->deleteCount = 0;
-	lastSerial = LastKnownRequestProcessed(dispPtr->display);
 	errorPtr = dispPtr->errorPtr;
 	for (prevPtr = NULL; errorPtr != NULL; errorPtr = nextPtr) {
 	    nextPtr = errorPtr->nextPtr;
@@ -213,11 +221,11 @@ Tk_DeleteErrorHandler(
 static int
 ErrorProc(
     Display *display,		/* Display for which error occurred. */
-    register XErrorEvent *errEventPtr)
+    XErrorEvent *errEventPtr)
 				/* Information about error. */
 {
-    register TkDisplay *dispPtr;
-    register TkErrorHandler *errorPtr;
+    TkDisplay *dispPtr;
+    TkErrorHandler *errorPtr;
 
     /*
      * See if we know anything about the display. If not, then invoke the
diff --git a/unix/tkUnixColor.c b/unix/tkUnixColor.c
index b11a1ebbc..43500ad5b 100644
--- a/unix/tkUnixColor.c
+++ b/unix/tkUnixColor.c
@@ -94,7 +94,6 @@ TkpFreeColor(
 		-1, -1, -1, NULL, NULL);
 	XFreeColors(DisplayOfScreen(screen), tkColPtr->colormap,
 		&tkColPtr->color.pixel, 1, 0L);
-        XSync(DisplayOfScreen(screen), False);
 	Tk_DeleteErrorHandler(handler);
     }
     DeleteStressedCmap(DisplayOfScreen(screen), tkColPtr->colormap);
diff --git a/unix/tkUnixEmbed.c b/unix/tkUnixEmbed.c
index b285fbe73..b170ad037 100644
--- a/unix/tkUnixEmbed.c
+++ b/unix/tkUnixEmbed.c
@@ -472,7 +472,6 @@ ContainerEventProc(
 
 	Tk_DestroyWindow((Tk_Window) winPtr);
     }
-    XSync(eventPtr->xfocus.display, False);
     Tk_DeleteErrorHandler(errHandler);
 }
 
@@ -516,7 +515,6 @@ EmbedStructureProc(
 		    containerPtr->wrapper, 0, 0,
 		    (unsigned) Tk_Width((Tk_Window) containerPtr->parentPtr),
 		    (unsigned) Tk_Height((Tk_Window) containerPtr->parentPtr));
-            XSync(eventPtr->xfocus.display, False);
 	    Tk_DeleteErrorHandler(errHandler);
 	}
     } else if (eventPtr->type == DestroyNotify) {
@@ -566,7 +564,6 @@ EmbedFocusProc(
 		    -1, -1, NULL, NULL);
 	    XSetInputFocus(display, containerPtr->wrapper, RevertToParent,
 		    CurrentTime);
-            XSync(eventPtr->xfocus.display, False);
 	    Tk_DeleteErrorHandler(errHandler);
 	}
     }
diff --git a/unix/tkUnixFocus.c b/unix/tkUnixFocus.c
index 7f4771e9d..07676181d 100644
--- a/unix/tkUnixFocus.c
+++ b/unix/tkUnixFocus.c
@@ -112,7 +112,6 @@ TkpChangeFocus(
     }
     XSetInputFocus(dispPtr->display, winPtr->window, RevertToParent,
 	    CurrentTime);
-    XSync(dispPtr->display, False);
     Tk_DeleteErrorHandler(errHandler);
 
     /*
diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c
index 44e733944..d43ed2460 100644
--- a/unix/tkUnixRFont.c
+++ b/unix/tkUnixRFont.c
@@ -388,7 +388,6 @@ FinishedWithFont(
     if (fontPtr->fontset) {
 	FcFontSetDestroy(fontPtr->fontset);
     }
-    XSync(fontPtr->display, False);
     Tk_DeleteErrorHandler(handler);
 }
 
@@ -876,7 +875,6 @@ Tk_DrawChars(
 		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
 
 	XftDrawChange(fontPtr->ftDraw, drawable);
-        XSync(display, False);
 	Tk_DeleteErrorHandler(handler);
     }
     XGetGCValues(display, gc, GCForeground, &values);
@@ -1010,7 +1008,6 @@ TkDrawAngledChars(
 		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
 
 	XftDrawChange(fontPtr->ftDraw, drawable);
-        XSync(display, False);
 	Tk_DeleteErrorHandler(handler);
     }
 
@@ -1100,7 +1097,6 @@ TkDrawAngledChars(
 		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
 
 	XftDrawChange(fontPtr->ftDraw, drawable);
-        XSync(display, False);
 	Tk_DeleteErrorHandler(handler);
     }
     XGetGCValues(display, gc, GCForeground, &values);
diff --git a/unix/tkUnixSelect.c b/unix/tkUnixSelect.c
index 9313df5c0..6d379ecc8 100644
--- a/unix/tkUnixSelect.c
+++ b/unix/tkUnixSelect.c
@@ -470,7 +470,6 @@ TkSelPropProc(
 		    ckfree(propPtr);
 		}
 	    }
-            XSync(eventPtr->xproperty.display, False);
 	    Tk_DeleteErrorHandler(errorHandler);
 
 	    /*
@@ -1049,7 +1048,6 @@ ConvertSelection(
 	reply.xsel.property = incr.multAtoms[1];
     }
     XSendEvent(reply.xsel.display, reply.xsel.requestor, False, 0, &reply.ev);
-    XSync(reply.xsel.display, False);
     Tk_DeleteErrorHandler(errorHandler);
 
     /*
@@ -1068,7 +1066,6 @@ ConvertSelection(
 	errorHandler = Tk_CreateErrorHandler(winPtr->display,
 		-1, -1, -1, (int (*)()) NULL, NULL);
 	XSelectInput(reply.xsel.display, reply.xsel.requestor, 0L);
-        XSync(winPtr->display, False);
 	Tk_DeleteErrorHandler(errorHandler);
 	if (tsdPtr->pendingIncrs == &incr) {
 	    tsdPtr->pendingIncrs = incr.nextPtr;
diff --git a/unix/tkUnixSend.c b/unix/tkUnixSend.c
index 0322a78d5..bbbdd774c 100644
--- a/unix/tkUnixSend.c
+++ b/unix/tkUnixSend.c
@@ -1748,7 +1748,6 @@ AppendPropCarefully(
 	    pendingPtr);
     XChangeProperty(display, window, property, XA_STRING, 8,
 	    PropModeAppend, (unsigned char *) value, length);
-    XSync(display, False);
     Tk_DeleteErrorHandler(handler);
 }
 
diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c
index 31e14cb72..19ac86cb5 100644
--- a/unix/tkUnixWm.c
+++ b/unix/tkUnixWm.c
@@ -4084,7 +4084,6 @@ ConfigureEvent(
     XMoveResizeWindow(winPtr->display, winPtr->window, 0,
 	    wmPtr->menuHeight, (unsigned) wrapperPtr->changes.width,
 	    (unsigned) (wrapperPtr->changes.height - wmPtr->menuHeight));
-    XSync(winPtr->display, False);
     Tk_DeleteErrorHandler(handler);
     if ((wmPtr->menubar != NULL)
 	    && ((Tk_Width(wmPtr->menubar) != wrapperPtr->changes.width)
@@ -4421,11 +4420,10 @@ WrapperEventProc(
 	     * Tk_DestroyWindow will try to destroy the window, but of course
 	     * it's already gone.
 	     */
-            Display *display = wmPtr->winPtr->display;
 
-	    handler = Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
+	    handler = Tk_CreateErrorHandler(wmPtr->winPtr->display, -1, -1, -1,
+		    NULL, NULL);
 	    Tk_DestroyWindow((Tk_Window) wmPtr->winPtr);
-            XSync(display, False);
 	    Tk_DeleteErrorHandler(handler);
 	}
 	if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
@@ -5848,12 +5846,10 @@ Tk_CoordsToWindow(
 	     * deleted
 	     */
 
-            XSync(Tk_Display(tkwin), False);
 	    Tk_DeleteErrorHandler(handler);
 	    return NULL;
 	}
 	if (child == None) {
-            XSync(Tk_Display(tkwin), False);
 	    Tk_DeleteErrorHandler(handler);
 	    return NULL;
 	}
@@ -5883,7 +5879,6 @@ Tk_CoordsToWindow(
 	 * or below
 	 */
 
-        XSync(Tk_Display(tkwin), False);
 	Tk_DeleteErrorHandler(handler);
 	handler = NULL;
     }
-- 
2.19.1

