changeset 9179:5e18efdad322 v7.4.1873

commit https://github.com/vim/vim/commit/4231da403e3c879dd6ac261e51f4ca60813935e3 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jun 2 14:30:04 2016 +0200 patch 7.4.1873 Problem: When a callback adds a timer the GUI doesn't use it until later. (Ramel Eshed) Solution: Return early if a callback adds a timer.
author Christian Brabandt <cb@256bit.org>
date Thu, 02 Jun 2016 14:30:08 +0200
parents 4f47bb74ecb7
children 3015b50926e4
files src/ex_cmds2.c src/globals.h src/gui_gtk_x11.c src/gui_w32.c src/gui_x11.c src/version.c
diffstat 6 files changed, 77 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1101,6 +1101,7 @@ insert_timer(timer_T *timer)
     if (first_timer != NULL)
 	first_timer->tr_prev = timer;
     first_timer = timer;
+    did_add_timer = TRUE;
 }
 
 /*
--- a/src/globals.h
+++ b/src/globals.h
@@ -1635,6 +1635,10 @@ EXTERN int  disable_char_avail_for_testi
 EXTERN int  in_free_unref_items INIT(= FALSE);
 #endif
 
+#ifdef FEAT_TIMERS
+EXTERN int  did_add_timer INIT(= FALSE);
+#endif
+
 /*
  * Optional Farsi support.  Include it here, so EXTERN and INIT are defined.
  */
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -6535,15 +6535,15 @@ input_timer_cb(gpointer data)
     int
 gui_mch_wait_for_chars(long wtime)
 {
-    int focus;
-    guint timer;
-    static int timed_out;
+    int		focus;
+    guint	timer;
+    static int	timed_out;
+    int		retval = FAIL;
 
     timed_out = FALSE;
 
     /* this timeout makes sure that we will return if no characters arrived in
      * time */
-
     if (wtime > 0)
 #if GTK_CHECK_VERSION(3,0,0)
 	timer = g_timeout_add((guint)wtime, input_timer_cb, &timed_out);
@@ -6568,7 +6568,15 @@ gui_mch_wait_for_chars(long wtime)
 	}
 
 #ifdef MESSAGE_QUEUE
+# ifdef FEAT_TIMERS
+	did_add_timer = FALSE;
+# endif
 	parse_queued_messages();
+# ifdef FEAT_TIMERS
+	if (did_add_timer)
+	    /* Need to recompute the waiting time. */
+	    goto theend;
+# endif
 #endif
 
 	/*
@@ -6582,13 +6590,8 @@ gui_mch_wait_for_chars(long wtime)
 	/* Got char, return immediately */
 	if (input_available())
 	{
-	    if (timer != 0 && !timed_out)
-#if GTK_CHECK_VERSION(3,0,0)
-		g_source_remove(timer);
-#else
-		gtk_timeout_remove(timer);
-#endif
-	    return OK;
+	    retval = OK;
+	    goto theend;
 	}
     } while (wtime < 0 || !timed_out);
 
@@ -6597,7 +6600,15 @@ gui_mch_wait_for_chars(long wtime)
      */
     gui_mch_update();
 
-    return FAIL;
+theend:
+    if (timer != 0 && !timed_out)
+#if GTK_CHECK_VERSION(3,0,0)
+	g_source_remove(timer);
+#else
+	gtk_timeout_remove(timer);
+#endif
+
+    return retval;
 }
 
 
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -2022,6 +2022,22 @@ gui_mch_update(void)
 	    process_message();
 }
 
+    static void
+remove_any_timer(void)
+{
+    MSG		msg;
+
+    if (s_wait_timer != 0 && !s_timed_out)
+    {
+	KillTimer(NULL, s_wait_timer);
+
+	/* Eat spurious WM_TIMER messages */
+	while (pPeekMessage(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
+	    ;
+	s_wait_timer = 0;
+    }
+}
+
 /*
  * GUI input routine called by gui_wait_for_chars().  Waits for a character
  * from the keyboard.
@@ -2073,6 +2089,9 @@ gui_mch_wait_for_chars(int wtime)
 	    s_need_activate = FALSE;
 	}
 
+#ifdef FEAT_TIMERS
+	did_add_timer = FALSE;
+#endif
 #ifdef MESSAGE_QUEUE
 	/* Check channel while waiting message. */
 	for (;;)
@@ -2098,15 +2117,7 @@ gui_mch_wait_for_chars(int wtime)
 
 	if (input_available())
 	{
-	    if (s_wait_timer != 0 && !s_timed_out)
-	    {
-		KillTimer(NULL, s_wait_timer);
-
-		/* Eat spurious WM_TIMER messages */
-		while (pPeekMessage(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
-		    ;
-		s_wait_timer = 0;
-	    }
+	    remove_any_timer();
 	    allow_scrollbar = FALSE;
 
 	    /* Clear pending mouse button, the release event may have been
@@ -2117,6 +2128,15 @@ gui_mch_wait_for_chars(int wtime)
 
 	    return OK;
 	}
+
+#ifdef FEAT_TIMERS
+	if (did_add_timer)
+	{
+	    /* Need to recompute the waiting time. */
+	    remove_any_timer();
+	    break;
+	}
+#endif
     }
     allow_scrollbar = FALSE;
     return FAIL;
--- a/src/gui_x11.c
+++ b/src/gui_x11.c
@@ -2368,7 +2368,7 @@ find_closest_color(Colormap colormap, XC
 
     for (i = 0; i  < cmap_size; i++)
 	colortable[i].pixel = (unsigned long)i;
-    XQueryColors (gui.dpy, colormap, colortable, cmap_size);
+    XQueryColors(gui.dpy, colormap, colortable, cmap_size);
 
     /*
      * Find the color that best approximates the desired one, then
@@ -2792,7 +2792,8 @@ gui_mch_update(void)
     int
 gui_mch_wait_for_chars(long wtime)
 {
-    int		    focus;
+    int	    focus;
+    int	    retval = FAIL;
 
     /*
      * Make this static, in case gui_x11_timer_cb is called after leaving
@@ -2828,7 +2829,15 @@ gui_mch_wait_for_chars(long wtime)
 	}
 
 #ifdef MESSAGE_QUEUE
+# ifdef FEAT_TIMERS
+	did_add_timer = FALSE;
+# endif
 	parse_queued_messages();
+# ifdef FEAT_TIMERS
+	if (did_add_timer)
+	    /* Need to recompute the waiting time. */
+	    break;
+# endif
 #endif
 
 	/*
@@ -2843,12 +2852,15 @@ gui_mch_wait_for_chars(long wtime)
 
 	if (input_available())
 	{
-	    if (timer != (XtIntervalId)0 && !timed_out)
-		XtRemoveTimeOut(timer);
-	    return OK;
+	    retval = OK;
+	    break;
 	}
     }
-    return FAIL;
+
+    if (timer != (XtIntervalId)0 && !timed_out)
+	XtRemoveTimeOut(timer);
+
+    return retval;
 }
 
 /*
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1873,
+/**/
     1872,
 /**/
     1871,