]> granicus.if.org Git - vim/commitdiff
patch 8.1.1315: there is always a delay if a termrequest is never answered v8.1.1315
authorBram Moolenaar <Bram@vim.org>
Fri, 10 May 2019 21:10:31 +0000 (23:10 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 10 May 2019 21:10:31 +0000 (23:10 +0200)
Problem:    There is always a delay if a termrequest is never answered.
Solution:   When the response is not received within two seconds consider the
            request to have failed.

src/term.c
src/version.c

index 462fe6f9811cc2896ddfeb60d0e5eaa40a7862f0..29d4025053a7d0f9b5f37efcac22f95389e45054 100644 (file)
@@ -110,19 +110,29 @@ static void log_tr(const char *fmt, ...);
 #   define LOG_TR(msg) do { /**/ } while (0)
 #  endif
 
-#  define STATUS_GET   1       /* send request when switching to RAW mode */
-#  define STATUS_SENT  2       /* did send request, waiting for response */
-#  define STATUS_GOT   3       /* received response */
+typedef enum {
+    STATUS_GET,                // send request when switching to RAW mode
+    STATUS_SENT,       // did send request, checking for response
+    STATUS_GOT,                // received response
+    STATUS_FAIL                // timed out
+} request_progress_T;
 
-/* Request Terminal Version status: */
-static int crv_status = STATUS_GET;
+typedef struct {
+    request_progress_T     tr_progress;
+    time_t                 tr_start;   // when request was sent, -1 for never
+} termrequest_T;
 
-/* Request Cursor position report: */
-static int u7_status = STATUS_GET;
+#  define TERMREQUEST_INIT {STATUS_GET, -1}
+
+// Request Terminal Version status:
+static termrequest_T crv_status = TERMREQUEST_INIT;
+
+// Request Cursor position report:
+static termrequest_T u7_status = TERMREQUEST_INIT;
 
 #  ifdef FEAT_TERMINAL
-/* Request foreground color report: */
-static int rfg_status = STATUS_GET;
+// Request foreground color report:
+static termrequest_T rfg_status = TERMREQUEST_INIT;
 static int fg_r = 0;
 static int fg_g = 0;
 static int fg_b = 0;
@@ -132,16 +142,29 @@ static int bg_b = 255;
 #  endif
 
 /* Request background color report: */
-static int rbg_status = STATUS_GET;
+static termrequest_T rbg_status = TERMREQUEST_INIT;
 
 /* Request cursor blinking mode report: */
-static int rbm_status = STATUS_GET;
+static termrequest_T rbm_status = TERMREQUEST_INIT;
 
 /* Request cursor style report: */
-static int rcs_status = STATUS_GET;
+static termrequest_T rcs_status = TERMREQUEST_INIT;
 
 /* Request windos position report: */
-static int winpos_status = STATUS_GET;
+static termrequest_T winpos_status = TERMREQUEST_INIT;
+
+static termrequest_T *all_termrequests[] = {
+    &crv_status,
+    &u7_status,
+#  ifdef FEAT_TERMINAL
+    &rfg_status,
+#  endif
+    &rbg_status,
+    &rbm_status,
+    &rcs_status,
+    &winpos_status,
+    NULL
+};
 # endif
 
 /*
@@ -2011,7 +2034,7 @@ set_termname(char_u *term)
     set_term_defaults();       /* use current values as defaults */
 #ifdef FEAT_TERMRESPONSE
     LOG_TR(("setting crv_status to STATUS_GET"));
-    crv_status = STATUS_GET;   /* Get terminal version later */
+    crv_status.tr_progress = STATUS_GET;       // Get terminal version later
 #endif
 
     /*
@@ -2833,12 +2856,47 @@ can_get_termresponse()
 {
     return cur_tmode == TMODE_RAW
            && termcap_active
-# ifdef UNIX
+#  ifdef UNIX
            && (is_not_a_term() || (isatty(1) && isatty(read_cmd_fd)))
-# endif
+#  endif
            && p_ek;
 }
 
+/*
+ * Set "status" to STATUS_SENT.
+ */
+    static void
+termrequest_sent(termrequest_T *status)
+{
+    status->tr_progress = STATUS_SENT;
+    status->tr_start = time(NULL);
+}
+
+/*
+ * Return TRUE if any of the requests are in STATUS_SENT.
+ */
+    static int
+termrequest_any_pending()
+{
+    int            i;
+    time_t  now = time(NULL);
+
+    for (i = 0; all_termrequests[i] != NULL; ++i)
+    {
+       if (all_termrequests[i]->tr_progress == STATUS_SENT)
+       {
+           if (all_termrequests[i]->tr_start > 0 && now > 0
+                                   && all_termrequests[i]->tr_start + 2 < now)
+               // Sent the request more than 2 seconds ago and didn't get a
+               // response, assume it failed.
+               all_termrequests[i]->tr_progress = STATUS_FAIL;
+           else
+               return TRUE;
+       }
+    }
+    return FALSE;
+}
+
 static int winpos_x = -1;
 static int winpos_y = -1;
 static int did_request_winpos = 0;
@@ -2860,7 +2918,7 @@ term_get_winpos(int *x, int *y, varnumber_T timeout)
     winpos_x = -1;
     winpos_y = -1;
     ++did_request_winpos;
-    winpos_status = STATUS_SENT;
+    termrequest_sent(&winpos_status);
     OUT_STR(T_CGP);
     out_flush();
 
@@ -3478,18 +3536,10 @@ settmode(int tmode)
            if (!gui.in_use && !gui.starting)
 # endif
            {
-               /* May need to check for T_CRV response and termcodes, it
-                * doesn't work in Cooked mode, an external program may get
-                * them. */
-               if (tmode != TMODE_RAW && (crv_status == STATUS_SENT
-                                        || u7_status == STATUS_SENT
-#ifdef FEAT_TERMINAL
-                                        || rfg_status == STATUS_SENT
-#endif
-                                        || rbg_status == STATUS_SENT
-                                        || rbm_status == STATUS_SENT
-                                        || rcs_status == STATUS_SENT
-                                        || winpos_status == STATUS_SENT))
+               // May need to check for T_CRV response and termcodes, it
+               // doesn't work in Cooked mode, an external program may get
+               // them.
+               if (tmode != TMODE_RAW && termrequest_any_pending())
                    (void)vpeekc_nomap();
                check_for_codes_from_term();
            }
@@ -3540,7 +3590,7 @@ starttermcap(void)
            may_req_termresponse();
            /* Immediately check for a response.  If t_Co changes, we don't
             * want to redraw with wrong colors first. */
-           if (crv_status == STATUS_SENT)
+           if (crv_status.tr_progress == STATUS_SENT)
                check_for_codes_from_term();
        }
 #endif
@@ -3559,23 +3609,15 @@ stoptermcap(void)
        if (!gui.in_use && !gui.starting)
 # endif
        {
-           /* May need to discard T_CRV, T_U7 or T_RBG response. */
-           if (crv_status == STATUS_SENT
-                   || u7_status == STATUS_SENT
-# ifdef FEAT_TERMINAL
-                   || rfg_status == STATUS_SENT
-# endif
-                   || rbg_status == STATUS_SENT
-                   || rbm_status == STATUS_SENT
-                   || rcs_status == STATUS_SENT
-                   || winpos_status == STATUS_SENT)
+           // May need to discard T_CRV, T_U7 or T_RBG response.
+           if (termrequest_any_pending())
            {
 # ifdef UNIX
-               /* Give the terminal a chance to respond. */
+               // Give the terminal a chance to respond.
                mch_delay(100L, FALSE);
 # endif
 # ifdef TCIFLUSH
-               /* Discard data received but not read. */
+               // Discard data received but not read.
                if (exiting)
                    tcflush(fileno(stdin), TCIFLUSH);
 # endif
@@ -3614,14 +3656,14 @@ stoptermcap(void)
     void
 may_req_termresponse(void)
 {
-    if (crv_status == STATUS_GET
+    if (crv_status.tr_progress == STATUS_GET
            && can_get_termresponse()
            && starting == 0
            && *T_CRV != NUL)
     {
        LOG_TR(("Sending CRV request"));
        out_str(T_CRV);
-       crv_status = STATUS_SENT;
+       termrequest_sent(&crv_status);
        /* check for the characters now, otherwise they might be eaten by
         * get_keystroke() */
        out_flush();
@@ -3641,37 +3683,37 @@ may_req_termresponse(void)
     void
 may_req_ambiguous_char_width(void)
 {
-    if (u7_status == STATUS_GET
+    if (u7_status.tr_progress == STATUS_GET
            && can_get_termresponse()
            && starting == 0
            && *T_U7 != NUL
            && !option_was_set((char_u *)"ambiwidth"))
     {
-        char_u buf[16];
-
-        LOG_TR(("Sending U7 request"));
-        /* Do this in the second row.  In the first row the returned sequence
-         * may be CSI 1;2R, which is the same as <S-F3>. */
-        term_windgoto(1, 0);
-        buf[mb_char2bytes(0x25bd, buf)] = 0;
-        out_str(buf);
-        out_str(T_U7);
-        u7_status = STATUS_SENT;
-        out_flush();
-
-        /* This overwrites a few characters on the screen, a redraw is needed
-         * after this. Clear them out for now. */
-        term_windgoto(1, 0);
-        out_str((char_u *)"  ");
-        term_windgoto(0, 0);
-
-        /* Need to reset the known cursor position. */
-        screen_start();
-
-        /* check for the characters now, otherwise they might be eaten by
-         * get_keystroke() */
-        out_flush();
-        (void)vpeekc_nomap();
+       char_u  buf[16];
+
+       LOG_TR(("Sending U7 request"));
+       /* Do this in the second row.  In the first row the returned sequence
+        * may be CSI 1;2R, which is the same as <S-F3>. */
+       term_windgoto(1, 0);
+       buf[mb_char2bytes(0x25bd, buf)] = 0;
+       out_str(buf);
+       out_str(T_U7);
+       termrequest_sent(&u7_status);
+       out_flush();
+
+       /* This overwrites a few characters on the screen, a redraw is needed
+        * after this. Clear them out for now. */
+       term_windgoto(1, 0);
+       out_str((char_u *)"  ");
+       term_windgoto(0, 0);
+
+       /* Need to reset the known cursor position. */
+       screen_start();
+
+       /* check for the characters now, otherwise they might be eaten by
+        * get_keystroke() */
+       out_flush();
+       (void)vpeekc_nomap();
     }
 }
 
@@ -3688,21 +3730,21 @@ may_req_bg_color(void)
 
 # ifdef FEAT_TERMINAL
        /* Only request foreground if t_RF is set. */
-       if (rfg_status == STATUS_GET && *T_RFG != NUL)
+       if (rfg_status.tr_progress == STATUS_GET && *T_RFG != NUL)
        {
            LOG_TR(("Sending FG request"));
            out_str(T_RFG);
-           rfg_status = STATUS_SENT;
+           termrequest_sent(&rfg_status);
            didit = TRUE;
        }
 # endif
 
        /* Only request background if t_RB is set. */
-       if (rbg_status == STATUS_GET && *T_RBG != NUL)
+       if (rbg_status.tr_progress == STATUS_GET && *T_RBG != NUL)
        {
            LOG_TR(("Sending BG request"));
            out_str(T_RBG);
-           rbg_status = STATUS_SENT;
+           termrequest_sent(&rbg_status);
            didit = TRUE;
        }
 
@@ -3962,7 +4004,7 @@ term_cursor_color(char_u *color)
 blink_state_is_inverted()
 {
 #ifdef FEAT_TERMRESPONSE
-    return rbm_status == STATUS_GOT && rcs_status == STATUS_GOT
+    return rbm_status.tr_progress == STATUS_GOT && rcs_status.tr_progress == STATUS_GOT
                && initial_cursor_blink != initial_cursor_shape_blink;
 #else
     return FALSE;
@@ -4651,7 +4693,7 @@ check_termcode(
                        char *aw = NULL;
 
                        LOG_TR(("Received U7 status: %s", tp));
-                       u7_status = STATUS_GOT;
+                       u7_status.tr_progress = STATUS_GOT;
                        did_cursorhold = TRUE;
                        if (col == 2)
                            aw = "single";
@@ -4689,7 +4731,7 @@ check_termcode(
                    int version = col;
 
                    LOG_TR(("Received CRV response: %s", tp));
-                   crv_status = STATUS_GOT;
+                   crv_status.tr_progress = STATUS_GOT;
                    did_cursorhold = TRUE;
 
                    /* If this code starts with CSI, you can bet that the
@@ -4804,7 +4846,7 @@ check_termcode(
                         * 279 (otherwise it returns 0x18).
                         * Not for Terminal.app, it can't handle t_RS, it
                         * echoes the characters to the screen. */
-                       if (rcs_status == STATUS_GET
+                       if (rcs_status.tr_progress == STATUS_GET
                                && version >= 279
                                && !is_not_xterm
                                && *T_CSH != NUL
@@ -4812,20 +4854,20 @@ check_termcode(
                        {
                            LOG_TR(("Sending cursor style request"));
                            out_str(T_CRS);
-                           rcs_status = STATUS_SENT;
+                           termrequest_sent(&rcs_status);
                            need_flush = TRUE;
                        }
 
                        /* Only request the cursor blink mode if t_RC set. Not
                         * for Gnome terminal, it can't handle t_RC, it
                         * echoes the characters to the screen. */
-                       if (rbm_status == STATUS_GET
+                       if (rbm_status.tr_progress == STATUS_GET
                                && !is_not_xterm
                                && *T_CRC != NUL)
                        {
                            LOG_TR(("Sending cursor blink mode request"));
                            out_str(T_CRC);
-                           rbm_status = STATUS_SENT;
+                           termrequest_sent(&rbm_status);
                            need_flush = TRUE;
                        }
 
@@ -4848,7 +4890,7 @@ check_termcode(
                 *
                 * {lead} can be <Esc>[ or CSI
                 */
-               else if (rbm_status == STATUS_SENT
+               else if (rbm_status.tr_progress == STATUS_SENT
                        && tp[(j = 1 + (tp[0] == ESC))] == '?'
                        && i == j + 6
                        && tp[j + 1] == '1'
@@ -4858,7 +4900,7 @@ check_termcode(
                        && tp[i] == 'y')
                {
                    initial_cursor_blink = (tp[j + 4] == '1');
-                   rbm_status = STATUS_GOT;
+                   rbm_status.tr_progress = STATUS_GOT;
                    LOG_TR(("Received cursor blinking mode response: %s", tp));
                    key_name[0] = (int)KS_EXTRA;
                    key_name[1] = (int)KE_IGNORE;
@@ -4896,7 +4938,7 @@ check_termcode(
                            slen = i + 1;
 
                            if (--did_request_winpos <= 0)
-                               winpos_status = STATUS_GOT;
+                               winpos_status.tr_progress = STATUS_GOT;
                        }
                    }
                    if (i == len)
@@ -4948,7 +4990,7 @@ check_termcode(
                                                + tp[j+17]) ? "light" : "dark";
 
                                LOG_TR(("Received RBG response: %s", tp));
-                               rbg_status = STATUS_GOT;
+                               rbg_status.tr_progress = STATUS_GOT;
 # ifdef FEAT_TERMINAL
                                bg_r = rval;
                                bg_g = gval;
@@ -4968,7 +5010,7 @@ check_termcode(
                            else
                            {
                                LOG_TR(("Received RFG response: %s", tp));
-                               rfg_status = STATUS_GOT;
+                               rfg_status.tr_progress = STATUS_GOT;
                                fg_r = rval;
                                fg_g = gval;
                                fg_b = bval;
@@ -5008,7 +5050,7 @@ check_termcode(
             *
             * Consume any code that starts with "{lead}.+r" or "{lead}.$r".
             */
-           else if ((check_for_codes || rcs_status == STATUS_SENT)
+           else if ((check_for_codes || rcs_status.tr_progress == STATUS_SENT)
                    && ((tp[0] == ESC && len >= 2 && tp[1] == 'P')
                        || tp[0] == DCS))
            {
@@ -5061,7 +5103,7 @@ check_termcode(
                             * the value set with T_SH. */
                            initial_cursor_shape_blink =
                                                   (number & 1) ? FALSE : TRUE;
-                           rcs_status = STATUS_GOT;
+                           rcs_status.tr_progress = STATUS_GOT;
                            LOG_TR(("Received cursor shape response: %s", tp));
 
                            key_name[0] = (int)KS_EXTRA;
@@ -6045,7 +6087,7 @@ check_termcode(
     void
 term_get_fg_color(char_u *r, char_u *g, char_u *b)
 {
-    if (rfg_status == STATUS_GOT)
+    if (rfg_status.tr_progress == STATUS_GOT)
     {
        *r = fg_r;
        *g = fg_g;
@@ -6059,7 +6101,7 @@ term_get_fg_color(char_u *r, char_u *g, char_u *b)
     void
 term_get_bg_color(char_u *r, char_u *g, char_u *b)
 {
-    if (rbg_status == STATUS_GOT)
+    if (rbg_status.tr_progress == STATUS_GOT)
     {
        *r = bg_r;
        *g = bg_g;
index 50c8339adfc7c2b83c426f6d2db228b7118afe9c..0e40f619a7aa8cbb8e8a7102444bab47dae2e521 100644 (file)
@@ -767,6 +767,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1315,
 /**/
     1314,
 /**/