From 9fb523a3a383401087a5ce5f1f59dada036e3c62 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Mon, 11 Apr 2016 20:44:27 +0200 Subject: [PATCH] Improve resize/co-dragging GTK The reconfigure event of the main board is not processed directly, but sets a timeout to call the actual handler, which will be restarted when new reconfigure events occur during the timeout period. This makes that the (very timeconsuming) redrawing and moving of all windows will only be done if the stream of events dries up. Unfortunately the ReSize routine called as part of the handling needs to be interruptable, which can cause recursive calling of the reconfigure handler. A variable 'busy' would ignore such recursion, but at the price of missing the interrupting event completely. The attempted fix to set a new timeout was flawed, as delayedDragTag would not have been cleared at that point. So we threw it out. Now 'busy' is a counter, which will remember if there were ignored recursion attempts, and then makes these into a harmless tail recursion, to do the resize/drag once more, based on the latest window parameters. --- gtk/xboard.c | 22 +++++++++++----------- 1 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gtk/xboard.c b/gtk/xboard.c index 96889c8..5ad75b1 100644 --- a/gtk/xboard.c +++ b/gtk/xboard.c @@ -1759,18 +1759,19 @@ static guint delayedDragTag = 0; void DragProc () { - static int busy; - if(busy) { // prevent recursive calling, but postpone interrupting call rather than lose it - if(!delayedDragTag) delayedDragTag = g_timeout_add( 200, (GSourceFunc) DragProc, NULL); - return; - } - busy = 1; + static int busy; + if(busy++) return; // prevent recursive calling, but remember we missed an event in 'busy' + + if(delayedDragTag) g_source_remove(delayedDragTag); // no more timer interrupts from same event! + delayedDragTag = 0; + + do { GetActualPlacement(shellWidget, &wpNew); if(wpNew.x == wpMain.x && wpNew.y == wpMain.y && // not moved wpNew.width == wpMain.width && wpNew.height == wpMain.height) { // not sized - busy = 0; return; // false alarm + busy = 0; break; // false alarm } - ReSize(&wpNew); + ReSize(&wpNew); // this can be interrupted by other events if(appData.useStickyWindows) { if(shellUp[EngOutDlg]) CoDrag(shells[EngOutDlg], &wpEngineOutput); if(shellUp[HistoryDlg]) CoDrag(shells[HistoryDlg], &wpMoveHistory); @@ -1780,9 +1781,8 @@ DragProc () } wpMain = wpNew; DrawPosition(True, NULL); - if(delayedDragTag) g_source_remove(delayedDragTag); - delayedDragTag = 0; // now drag executed, make sure next DelayedDrag will not cancel timer event (which could now be used by other) - busy = 0; + if(busy > 2) busy = 2; // if multiple events were backlogged, only do one more + } while(--busy); } void -- 1.7.0.4