]> granicus.if.org Git - vim/commitdiff
patch 8.0.0683: visual bell flashes too quickly v8.0.0683
authorBram Moolenaar <Bram@vim.org>
Tue, 27 Jun 2017 15:09:37 +0000 (17:09 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 27 Jun 2017 15:09:37 +0000 (17:09 +0200)
Problem:    When using a visual bell there is no delay, causing the flash to
            be very short, possibly unnoticeable.  Also, the flash and the
            beep can lockup the UI when repeated often.
Solution:   Do the delay in Vim or flush the output before the delay. Limit the
            bell to once per half a second. (Ozaki Kiichi, closes #1789)

src/misc1.c
src/proto/term.pro
src/term.c
src/version.c

index bc927b16284b787e68d2d7327c3b8f755fbbca46..7c2f26cfe4d0b3b684c402bc7d79081237cf3403 100644 (file)
@@ -3685,16 +3685,30 @@ vim_beep(
     {
        if (!((bo_flags & val) || (bo_flags & BO_ALL)))
        {
-           if (p_vb
+#ifdef ELAPSED_FUNC
+           static int          did_init = FALSE;
+           static ELAPSED_TYPE start_tv;
+
+           /* Only beep once per half a second, otherwise a sequence of beeps
+            * would freeze Vim. */
+           if (!did_init || ELAPSED_FUNC(start_tv) > 500)
+           {
+               did_init = TRUE;
+               ELAPSED_INIT(start_tv);
+#endif
+               if (p_vb
 #ifdef FEAT_GUI
-                   /* While the GUI is starting up the termcap is set for the
-                    * GUI but the output still goes to a terminal. */
-                   && !(gui.in_use && gui.starting)
+                       /* While the GUI is starting up the termcap is set for
+                        * the GUI but the output still goes to a terminal. */
+                       && !(gui.in_use && gui.starting)
+#endif
+                       )
+                   out_str_cf(T_VB);
+               else
+                   out_char(BELL);
+#ifdef ELAPSED_FUNC
+           }
 #endif
-                   )
-               out_str(T_VB);
-           else
-               out_char(BELL);
        }
 
        /* When 'verbose' is set and we are sourcing a script or executing a
index 7d9fc6ae71ee0489eb5cd91627f6cdc5c8053098..9af725ff837776ddf131cd72c578f4db709873b8 100644 (file)
@@ -16,6 +16,7 @@ void out_flush_check(void);
 void out_trash(void);
 void out_char(unsigned c);
 void out_str_nf(char_u *s);
+void out_str_cf(char_u *s);
 void out_str(char_u *s);
 void term_windgoto(int row, int col);
 void term_cursor_right(int i);
index 56d698bb256738801064bc71671a21b6190a6afe..0dbe6d500b263ffd9511d87249908d40f43c2a9e 100644 (file)
@@ -2513,6 +2513,75 @@ out_str_nf(char_u *s)
 }
 #endif
 
+/*
+ * A conditional-flushing out_str, mainly for visualbell.
+ * Handles a delay internally, because termlib may not respect the delay or do
+ * it at the wrong time.
+ * Note: Only for terminal strings.
+ */
+    void
+out_str_cf(char_u *s)
+{
+    if (s != NULL && *s)
+    {
+       char_u *p;
+
+#ifdef FEAT_GUI
+       /* Don't use tputs() when GUI is used, ncurses crashes. */
+       if (gui.in_use)
+       {
+           out_str_nf(s);
+           return;
+       }
+#endif
+       if (out_pos > OUT_SIZE - 20)
+           out_flush();
+#ifdef HAVE_TGETENT
+       for (p = s; *s; ++s)
+       {
+           /* flush just before delay command */
+           if (*s == '$' && *(s + 1) == '<')
+           {
+               char_u save_c = *s;
+               int duration = atoi((char *)s + 2);
+
+               *s = NUL;
+               tputs((char *)p, 1, TPUTSFUNCAST out_char_nf);
+               *s = save_c;
+               out_flush();
+#ifdef ELAPSED_FUNC
+               /* Only sleep here if we can limit this happening in
+                * vim_beep(). */
+               p = vim_strchr(s, '>');
+               if (p == NULL || duration <= 0)
+               {
+                   /* can't parse the time, don't sleep here */
+                   p = s;
+               }
+               else
+               {
+                   ++p;
+                   do_sleep(duration);
+               }
+#else
+               /* Rely on the terminal library to sleep. */
+               p = s;
+#endif
+               break;
+           }
+       }
+       tputs((char *)p, 1, TPUTSFUNCAST out_char_nf);
+#else
+       while (*s)
+           out_char_nf(*s++);
+#endif
+
+       /* For testing we write one string at a time. */
+       if (p_wd)
+           out_flush();
+    }
+}
+
 /*
  * out_str(s): Put a character string a byte at a time into the output buffer.
  * If HAVE_TGETENT is defined use the termcap parser. (jw)
index c1d5ec84146361fa8e171ea0378b221d59126ee5..a5f6f18a6a81ad156e1bc4d2923da51a1c301c89 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    683,
 /**/
     682,
 /**/