changeset 19599:5eb0ead1415f v8.2.0356

patch 8.2.0356: MS-Windows: feedkeys() with VIMDLL cannot handle CSI Commit: https://github.com/vim/vim/commit/8f027fe470555252b258508c455e93700a969cb1 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Mar 4 23:21:35 2020 +0100 patch 8.2.0356: MS-Windows: feedkeys() with VIMDLL cannot handle CSI Problem: MS-Windows: feedkeys() with VIMDLL cannot handle CSI correctly. Solution: Modify mch_inchar() to encode CSI bytes. (Ozaki Kiichi, Ken Takata, closes #5726)
author Bram Moolenaar <Bram@vim.org>
date Wed, 04 Mar 2020 23:30:04 +0100
parents e5054307d4bb
children 911eb7bbfebb
files src/getchar.c src/os_win32.c src/testdir/test_popupwin.vim src/version.c
diffstat 4 files changed, 49 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1623,7 +1623,7 @@ vgetc(void)
 	    // Get two extra bytes for special keys
 	    if (c == K_SPECIAL
 #ifdef FEAT_GUI
-		    || (gui.in_use && c == CSI)
+		    || (c == CSI)
 #endif
 	       )
 	    {
@@ -1678,23 +1678,19 @@ vgetc(void)
 		}
 #endif
 #ifdef FEAT_GUI
-		if (gui.in_use)
+		// Handle focus event here, so that the caller doesn't need to
+		// know about it.  Return K_IGNORE so that we loop once (needed
+		// if 'lazyredraw' is set).
+		if (c == K_FOCUSGAINED || c == K_FOCUSLOST)
 		{
-		    // Handle focus event here, so that the caller doesn't
-		    // need to know about it.  Return K_IGNORE so that we loop
-		    // once (needed if 'lazyredraw' is set).
-		    if (c == K_FOCUSGAINED || c == K_FOCUSLOST)
-		    {
-			ui_focus_change(c == K_FOCUSGAINED);
-			c = K_IGNORE;
-		    }
-
-		    // Translate K_CSI to CSI.  The special key is only used
-		    // to avoid it being recognized as the start of a special
-		    // key.
-		    if (c == K_CSI)
-			c = CSI;
+		    ui_focus_change(c == K_FOCUSGAINED);
+		    c = K_IGNORE;
 		}
+
+		// Translate K_CSI to CSI.  The special key is only used to
+		// avoid it being recognized as the start of a special key.
+		if (c == K_CSI)
+		    c = CSI;
 #endif
 	    }
 	    // a keypad or special function key was not mapped, use it like
@@ -1772,11 +1768,7 @@ vgetc(void)
 		    buf[i] = vgetorpeek(TRUE);
 		    if (buf[i] == K_SPECIAL
 #ifdef FEAT_GUI
-			    || (
-# ifdef VIMDLL
-				gui.in_use &&
-# endif
-				buf[i] == CSI)
+			    || (buf[i] == CSI)
 #endif
 			    )
 		    {
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -1782,7 +1782,13 @@ mch_inchar(
 
     int		len;
     int		c;
-# define TYPEAHEADLEN 20
+# ifdef VIMDLL
+// Extra space for maximum three CSIs. E.g. U+1B6DB -> 0xF0 0x9B 0x9B 0x9B.
+#  define TYPEAHEADSPACE    6
+# else
+#  define TYPEAHEADSPACE    0
+# endif
+# define TYPEAHEADLEN	    (20 + TYPEAHEADSPACE)
     static char_u   typeahead[TYPEAHEADLEN];	// previously typed bytes.
     static int	    typeaheadlen = 0;
 
@@ -1838,7 +1844,7 @@ mch_inchar(
     // to get and still room in the buffer (up to two bytes for a char and
     // three bytes for a modifier).
     while ((typeaheadlen == 0 || WaitForChar(0L, FALSE))
-					  && typeaheadlen + 5 <= TYPEAHEADLEN)
+		         && typeaheadlen + 5 + TYPEAHEADSPACE <= TYPEAHEADLEN)
     {
 	if (typebuf_changed(tb_change_cnt))
 	{
@@ -1890,7 +1896,7 @@ mch_inchar(
 
 		if (ch2 == NUL)
 		{
-		    int	    i;
+		    int	    i, j;
 		    char_u  *p;
 		    WCHAR   ch[2];
 
@@ -1903,13 +1909,33 @@ mch_inchar(
 		    p = utf16_to_enc(ch, &n);
 		    if (p != NULL)
 		    {
-			for (i = 0; i < n; i++)
-			    typeahead[typeaheadlen + i] = p[i];
+			for (i = 0, j = 0; i < n; i++)
+			{
+			    typeahead[typeaheadlen + j++] = p[i];
+# ifdef VIMDLL
+			    if (p[i] == CSI)
+			    {
+				typeahead[typeaheadlen + j++] = KS_EXTRA;
+				typeahead[typeaheadlen + j++] = KE_CSI;
+			    }
+# endif
+			}
+			n = j;
 			vim_free(p);
 		    }
 		}
 		else
+		{
 		    typeahead[typeaheadlen] = c;
+# ifdef VIMDLL
+		    if (c == CSI)
+		    {
+			typeahead[typeaheadlen + 1] = KS_EXTRA;
+			typeahead[typeaheadlen + 2] = KE_CSI;
+			n = 3;
+		    }
+# endif
+		}
 		if (ch2 != NUL)
 		{
 		    if (c == K_NUL)
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -3284,11 +3284,9 @@ func Test_popupwin_filter_input_multibyt
   call feedkeys("\u3000", 'xt')
   call assert_equal([0xe3, 0x80, 0x80], g:bytes)
 
-  if has('gui')
-    " UTF-8: E3 80 9B, including CSI(0x9B)
-    call feedkeys("\u301b", 'xt')
-    call assert_equal([0xe3, 0x80, 0x9b], g:bytes)
-  endif
+  " UTF-8: E3 80 9B, including CSI(0x9B)
+  call feedkeys("\u301b", 'xt')
+  call assert_equal([0xe3, 0x80, 0x9b], g:bytes)
 
   call popup_clear()
   delfunc MyPopupFilter
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    356,
+/**/
     355,
 /**/
     354,