summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-06-27 17:09:37 +0200
committerBram Moolenaar <Bram@vim.org>2017-06-27 17:09:37 +0200
commit2e147caa14f622dfd1c1def8e07c113b9b85d4b2 (patch)
tree53c69cc89daa1da1462c061da18e104ae3972f7e
parent0b2eef24bcbe2c85c90bbde914a1782cbedc5c72 (diff)
patch 8.0.0683: visual bell flashes too quicklyv8.0.0683
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)
-rw-r--r--src/misc1.c30
-rw-r--r--src/proto/term.pro1
-rw-r--r--src/term.c69
-rw-r--r--src/version.c2
4 files changed, 94 insertions, 8 deletions
diff --git a/src/misc1.c b/src/misc1.c
index bc927b1628..7c2f26cfe4 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -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
diff --git a/src/proto/term.pro b/src/proto/term.pro
index 7d9fc6ae71..9af725ff83 100644
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -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);
diff --git a/src/term.c b/src/term.c
index 56d698bb25..0dbe6d500b 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2514,6 +2514,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)
* This should only be used for writing terminal codes, not for outputting
diff --git a/src/version.c b/src/version.c
index c1d5ec8414..a5f6f18a6a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 683,
+/**/
682,
/**/
681,