@@ -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/*
@@ -2778,9 +2781,9 @@ can_get_termresponse()
27782781 & & p_ek ;
27792782}
27802783
2781- static int winpos_x ;
2782- static int winpos_y ;
2783- static int waiting_for_winpos = FALSE ;
2784+ static int winpos_x = -1 ;
2785+ static int winpos_y = -1 ;
2786+ static int did_request_winpos = 0 ;
27842787
27852788/*
27862789 * Try getting the Vim window position from the terminal.
@@ -2790,29 +2793,43 @@ static int waiting_for_winpos = FALSE;
27902793term_get_winpos (int * x , int * y , varnumber_T timeout )
27912794{
27922795 int count = 0 ;
2796+ int prev_winpos_x = winpos_x ;
2797+ int prev_winpos_y = winpos_y ;
27932798
27942799 if (* T_CGP == NUL || !can_get_termresponse ())
27952800 return FAIL ;
27962801 winpos_x = -1 ;
27972802 winpos_y = -1 ;
2798- waiting_for_winpos = TRUE;
2803+ ++ did_request_winpos ;
2804+ winpos_status = STATUS_SENT ;
27992805 OUT_STR (T_CGP );
28002806 out_flush ();
28012807
28022808 /* Try reading the result for "timeout" msec. */
2803- while (count ++ < timeout / 10 )
2809+ while (count ++ <= timeout / 10 && ! got_int )
28042810 {
28052811 (void )vpeekc_nomap ();
28062812 if (winpos_x >= 0 && winpos_y >= 0 )
28072813 {
28082814 * x = winpos_x ;
28092815 * y = winpos_y ;
2810- waiting_for_winpos = FALSE;
28112816 return OK ;
28122817 }
28132818 ui_delay (10 , FALSE);
28142819 }
2815- waiting_for_winpos = FALSE;
2820+ /* Do not reset "did_request_winpos", if we timed out the response might
2821+ * still come later and we must consume it. */
2822+
2823+ winpos_x = prev_winpos_x ;
2824+ winpos_y = prev_winpos_y ;
2825+ if (timeout < 10 && prev_winpos_y >= 0 && prev_winpos_y >= 0 )
2826+ {
2827+ /* Polling: return previous values if we have them. */
2828+ * x = winpos_x ;
2829+ * y = winpos_y ;
2830+ return OK ;
2831+ }
2832+
28162833 return FALSE;
28172834}
28182835# endif
@@ -3365,7 +3382,8 @@ settmode(int tmode)
33653382#endif
33663383 || rbg_status == STATUS_SENT
33673384 || rbm_status == STATUS_SENT
3368- || rcs_status == STATUS_SENT ))
3385+ || rcs_status == STATUS_SENT
3386+ || winpos_status == STATUS_SENT ))
33693387 (void )vpeekc_nomap ();
33703388 check_for_codes_from_term ();
33713389 }
@@ -3439,7 +3457,8 @@ stoptermcap(void)
34393457# endif
34403458 || rbg_status == STATUS_SENT
34413459 || rbm_status == STATUS_SENT
3442- || rcs_status == STATUS_SENT )
3460+ || rcs_status == STATUS_SENT
3461+ || winpos_status == STATUS_SENT )
34433462 {
34443463# ifdef UNIX
34453464 /* Give the terminal a chance to respond. */
@@ -4468,7 +4487,7 @@ check_termcode(
44684487 */
44694488 char_u * argp = tp [0 ] == ESC ? tp + 2 : tp + 1 ;
44704489
4471- if ((* T_CRV != NUL || * T_U7 != NUL || waiting_for_winpos )
4490+ if ((* T_CRV != NUL || * T_U7 != NUL || did_request_winpos )
44724491 && ((tp [0 ] == ESC && len >= 3 && tp [1 ] == '[' )
44734492 || (tp [0 ] == CSI && len >= 2 ))
44744493 && (VIM_ISDIGIT (* argp ) || * argp == '>' || * argp == '?' ))
@@ -4730,7 +4749,7 @@ check_termcode(
47304749 * Check for a window position response from the terminal:
47314750 * {lead}3;{x}:{y}t
47324751 */
4733- else if (waiting_for_winpos
4752+ else if (did_request_winpos
47344753 && ((len >= 4 && tp [0 ] == ESC && tp [1 ] == '[' )
47354754 || (len >= 3 && tp [0 ] == CSI ))
47364755 && tp [(j = 1 + (tp [0 ] == ESC ))] == '3'
@@ -4752,6 +4771,9 @@ check_termcode(
47524771 key_name [0 ] = (int )KS_EXTRA ;
47534772 key_name [1 ] = (int )KE_IGNORE ;
47544773 slen = i + 1 ;
4774+
4775+ if (-- did_request_winpos <= 0 )
4776+ winpos_status = STATUS_GOT ;
47554777 }
47564778 }
47574779 if (i == len )
0 commit comments