]> granicus.if.org Git - vim/commitdiff
patch 8.2.0356: MS-Windows: feedkeys() with VIMDLL cannot handle CSI v8.2.0356
authorBram Moolenaar <Bram@vim.org>
Wed, 4 Mar 2020 22:21:35 +0000 (23:21 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 4 Mar 2020 22:21:35 +0000 (23:21 +0100)
Problem:    MS-Windows: feedkeys() with VIMDLL cannot handle CSI correctly.
Solution:   Modify mch_inchar() to encode CSI bytes. (Ozaki Kiichi, Ken
            Takata, closes #5726)

src/getchar.c
src/os_win32.c
src/testdir/test_popupwin.vim
src/version.c

index b828c27dd4b687841fba14e40e8be7de4f0dab11..7df4bcebc9ba0656770aa28e050cd9c7957ecfb8 100644 (file)
@@ -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
                            )
                    {
index df63fb7f3ecec1bbe4182489cf289ea2599b927a..e9d22e417a4e2a47bdf88925573e3968acaf46bb 100644 (file)
@@ -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)
index 9c22845c49757c34729bae36cc2c31c6e1f6dd28..ebc8c430693cf57b6bff06bbf597468186915c24 100644 (file)
@@ -3284,11 +3284,9 @@ func Test_popupwin_filter_input_multibyte()
   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
index f494186ffed8734c02ddbeb2ba820745916ee230..3e7115ba30d8d9b605433ed83f7fc39544e6f36a 100644 (file)
@@ -738,6 +738,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    356,
 /**/
     355,
 /**/