@@ -143,6 +143,9 @@ static int rbm_status = STATUS_GET;
143143
144144/* Request cursor style report: */
145145static int rcs_status = STATUS_GET ;
146+
147+ /* Request windos position report: */
148+ static int winpos_status = STATUS_GET ;
146149# endif
147150
148151/*
@@ -2784,9 +2787,9 @@ can_get_termresponse()
27842787 & & p_ek ;
27852788}
27862789
2787- static int winpos_x ;
2788- static int winpos_y ;
2789- static int waiting_for_winpos = FALSE ;
2790+ static int winpos_x = -1 ;
2791+ static int winpos_y = -1 ;
2792+ static int did_request_winpos = 0 ;
27902793
27912794/*
27922795 * Try getting the Vim window position from the terminal.
@@ -2796,29 +2799,43 @@ static int waiting_for_winpos = FALSE;
27962799term_get_winpos (int * x , int * y , varnumber_T timeout )
27972800{
27982801 int count = 0 ;
2802+ int prev_winpos_x = winpos_x ;
2803+ int prev_winpos_y = winpos_y ;
27992804
28002805 if (* T_CGP == NUL || !can_get_termresponse ())
28012806 return FAIL ;
28022807 winpos_x = -1 ;
28032808 winpos_y = -1 ;
2804- waiting_for_winpos = TRUE;
2809+ ++ did_request_winpos ;
2810+ winpos_status = STATUS_SENT ;
28052811 OUT_STR (T_CGP );
28062812 out_flush ();
28072813
28082814 /* Try reading the result for "timeout" msec. */
2809- while (count ++ < timeout / 10 )
2815+ while (count ++ <= timeout / 10 && ! got_int )
28102816 {
28112817 (void )vpeekc_nomap ();
28122818 if (winpos_x >= 0 && winpos_y >= 0 )
28132819 {
28142820 * x = winpos_x ;
28152821 * y = winpos_y ;
2816- waiting_for_winpos = FALSE;
28172822 return OK ;
28182823 }
28192824 ui_delay (10 , FALSE);
28202825 }
2821- waiting_for_winpos = FALSE;
2826+ /* Do not reset "did_request_winpos", if we timed out the response might
2827+ * still come later and we must consume it. */
2828+
2829+ winpos_x = prev_winpos_x ;
2830+ winpos_y = prev_winpos_y ;
2831+ if (timeout < 10 && prev_winpos_y >= 0 && prev_winpos_y >= 0 )
2832+ {
2833+ /* Polling: return previous values if we have them. */
2834+ * x = winpos_x ;
2835+ * y = winpos_y ;
2836+ return OK ;
2837+ }
2838+
28222839 return FALSE;
28232840}
28242841# endif
@@ -3371,7 +3388,8 @@ settmode(int tmode)
33713388#endif
33723389 || rbg_status == STATUS_SENT
33733390 || rbm_status == STATUS_SENT
3374- || rcs_status == STATUS_SENT ))
3391+ || rcs_status == STATUS_SENT
3392+ || winpos_status == STATUS_SENT ))
33753393 (void )vpeekc_nomap ();
33763394 check_for_codes_from_term ();
33773395 }
@@ -3445,7 +3463,8 @@ stoptermcap(void)
34453463# endif
34463464 || rbg_status == STATUS_SENT
34473465 || rbm_status == STATUS_SENT
3448- || rcs_status == STATUS_SENT )
3466+ || rcs_status == STATUS_SENT
3467+ || winpos_status == STATUS_SENT )
34493468 {
34503469# ifdef UNIX
34513470 /* Give the terminal a chance to respond. */
@@ -4474,7 +4493,7 @@ check_termcode(
44744493 */
44754494 char_u * argp = tp [0 ] == ESC ? tp + 2 : tp + 1 ;
44764495
4477- if ((* T_CRV != NUL || * T_U7 != NUL || waiting_for_winpos )
4496+ if ((* T_CRV != NUL || * T_U7 != NUL || did_request_winpos )
44784497 && ((tp [0 ] == ESC && len >= 3 && tp [1 ] == '[' )
44794498 || (tp [0 ] == CSI && len >= 2 ))
44804499 && (VIM_ISDIGIT (* argp ) || * argp == '>' || * argp == '?' ))
@@ -4736,7 +4755,7 @@ check_termcode(
47364755 * Check for a window position response from the terminal:
47374756 * {lead}3;{x}:{y}t
47384757 */
4739- else if (waiting_for_winpos
4758+ else if (did_request_winpos
47404759 && ((len >= 4 && tp [0 ] == ESC && tp [1 ] == '[' )
47414760 || (len >= 3 && tp [0 ] == CSI ))
47424761 && tp [(j = 1 + (tp [0 ] == ESC ))] == '3'
@@ -4758,6 +4777,9 @@ check_termcode(
47584777 key_name [0 ] = (int )KS_EXTRA ;
47594778 key_name [1 ] = (int )KE_IGNORE ;
47604779 slen = i + 1 ;
4780+
4781+ if (-- did_request_winpos <= 0 )
4782+ winpos_status = STATUS_GOT ;
47614783 }
47624784 }
47634785 if (i == len )
0 commit comments