]> granicus.if.org Git - vim/commitdiff
patch 8.2.0848: MS-Windows: the Windows terminal code has some flaws v8.2.0848
authorBram Moolenaar <Bram@vim.org>
Sat, 30 May 2020 15:49:25 +0000 (17:49 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 30 May 2020 15:49:25 +0000 (17:49 +0200)
Problem:    MS-Windows: the Windows terminal code has some flaws.
Solution:   Do not redraw the right edge of the screen.  Remove the background
            color trick.  Flush the screen output buffer often.  (Nobuhiro
            Takasaki, #5546)

src/os_win32.c
src/proto/os_win32.pro
src/term.c
src/version.c

index 89c7c5e3aaa9bb0e09960923ed3b93d164173050..2c5670d9ddef1ce12bf3125731f71f484b7a58cf 100644 (file)
@@ -195,10 +195,12 @@ static void vtp_flag_init();
 static int vtp_working = 0;
 static void vtp_init();
 static void vtp_exit();
-static int vtp_printf(char *format, ...);
 static void vtp_sgr_bulk(int arg);
 static void vtp_sgr_bulks(int argc, int *argv);
 
+static int wt_working = 0;
+static void wt_init();
+
 static guicolor_T save_console_bg_rgb;
 static guicolor_T save_console_fg_rgb;
 static guicolor_T store_console_bg_rgb;
@@ -214,8 +216,10 @@ static int default_console_color_fg = 0xc0c0c0; // white
 
 # ifdef FEAT_TERMGUICOLORS
 #  define USE_VTP              (vtp_working && is_term_win32() && (p_tgc || (!p_tgc && t_colors >= 256)))
+#  define USE_WT               (wt_working)
 # else
 #  define USE_VTP              0
+#  define USE_WT               0
 # endif
 
 static void set_console_color_rgb(void);
@@ -236,6 +240,12 @@ static char_u *exe_path = NULL;
 
 static BOOL win8_or_later = FALSE;
 
+# if defined(__GNUC__) && !defined(__MINGW32__)  && !defined(__CYGWIN__)
+#  define UChar UnicodeChar
+# else
+#  define UChar uChar.UnicodeChar
+# endif
+
 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
 // Dynamic loading for portability
 typedef struct _DYN_CONSOLE_SCREEN_BUFFER_INFOEX
@@ -286,6 +296,30 @@ get_build_number(void)
 }
 
 #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
+    static BOOL
+is_ambiwidth_event(
+    INPUT_RECORD *ir)
+{
+    return ir->EventType == KEY_EVENT
+               && ir->Event.KeyEvent.bKeyDown
+               && ir->Event.KeyEvent.wRepeatCount == 1
+               && ir->Event.KeyEvent.wVirtualKeyCode == 0x12
+               && ir->Event.KeyEvent.wVirtualScanCode == 0x38
+               && ir->Event.KeyEvent.UChar == 0
+               && ir->Event.KeyEvent.dwControlKeyState == 2;
+}
+
+    static void
+make_ambiwidth_event(
+    INPUT_RECORD *down,
+    INPUT_RECORD *up)
+{
+    down->Event.KeyEvent.wVirtualKeyCode = 0;
+    down->Event.KeyEvent.wVirtualScanCode = 0;
+    down->Event.KeyEvent.UChar = up->Event.KeyEvent.UChar;
+    down->Event.KeyEvent.dwControlKeyState = 0;
+}
+
 /*
  * Version of ReadConsoleInput() that works with IME.
  * Works around problems on Windows 8.
@@ -322,10 +356,12 @@ read_console_input(
 
     if (s_dwMax == 0)
     {
-       if (nLength == -1)
+       if (!USE_WT && nLength == -1)
            return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents);
-       if (!ReadConsoleInputW(hInput, s_irCache, IRSIZE, &dwEvents))
-           return FALSE;
+       GetNumberOfConsoleInputEvents(hInput, &dwEvents);
+       if (dwEvents == 0 && nLength == -1)
+           return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents);
+       ReadConsoleInputW(hInput, s_irCache, IRSIZE, &dwEvents);
        s_dwIndex = 0;
        s_dwMax = dwEvents;
        if (dwEvents == 0)
@@ -334,6 +370,10 @@ read_console_input(
            return TRUE;
        }
 
+       for (i = s_dwIndex; i < (int)s_dwMax - 1; ++i)
+           if (is_ambiwidth_event(&s_irCache[i]))
+               make_ambiwidth_event(&s_irCache[i], &s_irCache[i + 1]);
+
        if (s_dwMax > 1)
        {
            head = 0;
@@ -937,12 +977,6 @@ static const struct
 };
 
 
-# if defined(__GNUC__) && !defined(__MINGW32__)  && !defined(__CYGWIN__)
-#  define UChar UnicodeChar
-# else
-#  define UChar uChar.UnicodeChar
-# endif
-
 /*
  * The return code indicates key code size.
  */
@@ -2689,6 +2723,7 @@ mch_init_c(void)
 
     vtp_flag_init();
     vtp_init();
+    wt_init();
 }
 
 /*
@@ -5781,6 +5816,19 @@ insert_lines(unsigned cLines)
            clear_chars(coord, source.Right - source.Left + 1);
        }
     }
+
+    if (USE_WT)
+    {
+       COORD coord;
+       int i;
+
+       coord.X = source.Left;
+       for (i = source.Top; i < dest.Y; ++i)
+       {
+           coord.Y = i;
+           clear_chars(coord, source.Right - source.Left + 1);
+       }
+    }
 }
 
 
@@ -5837,6 +5885,19 @@ delete_lines(unsigned cLines)
            clear_chars(coord, source.Right - source.Left + 1);
        }
     }
+
+    if (USE_WT)
+    {
+       COORD coord;
+       int i;
+
+       coord.X = source.Left;
+       for (i = nb; i <= source.Bottom; ++i)
+       {
+           coord.Y = i;
+           clear_chars(coord, source.Right - source.Left + 1);
+       }
+    }
 }
 
 
@@ -7587,7 +7648,7 @@ vtp_exit(void)
     restore_console_color_rgb();
 }
 
-    static int
+    int
 vtp_printf(
     char *format,
     ...)
@@ -7760,6 +7821,18 @@ vtp_sgr_bulks(
     }
 }
 
+    static void
+wt_init(void)
+{
+    wt_working = (mch_getenv("WT_SESSION") != NULL);
+}
+
+    int
+use_wt(void)
+{
+    return USE_WT;
+}
+
 # ifdef FEAT_TERMGUICOLORS
     static int
 ctermtoxterm(
@@ -7785,6 +7858,13 @@ set_console_color_rgb(void)
 
     get_default_console_color(&ctermfg, &ctermbg, &fg, &bg);
 
+    if (USE_WT)
+    {
+       term_fg_rgb_color(fg);
+       term_bg_rgb_color(bg);
+       return;
+    }
+
     fg = (GetRValue(fg) << 16) | (GetGValue(fg) << 8) | GetBValue(fg);
     bg = (GetRValue(bg) << 16) | (GetGValue(bg) << 8) | GetBValue(bg);
 
@@ -7858,6 +7938,9 @@ reset_console_color_rgb(void)
 # ifdef FEAT_TERMGUICOLORS
     DYN_CONSOLE_SCREEN_BUFFER_INFOEX csbi;
 
+    if (USE_WT)
+       return;
+
     csbi.cbSize = sizeof(csbi);
     if (has_csbiex)
        pGetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
index d8f9ac36b219227149d8e0fef497de605c47e793..85c09c0ba17e174839862b4a44be5ed41e38c576 100644 (file)
@@ -71,6 +71,8 @@ void used_file_arg(char *name, int literal, int full_path, int diff_mode);
 void set_alist_count(void);
 void fix_arg_enc(void);
 int mch_setenv(char *var, char *value, int x);
+int vtp_printf(char *format, ...);
+int use_wt(void);
 void get_default_console_color(int *cterm_fg, int *cterm_bg, guicolor_T *gui_fg, guicolor_T *gui_bg);
 void control_console_color_rgb(void);
 int use_vtp(void);
index 588058941db87d2e31c4f72984ea88ac23e8adbe..d774ebc98c5c6aa7449b3701fffa11287f2505f7 100644 (file)
@@ -2956,7 +2956,16 @@ term_rgb_color(char_u *s, guicolor_T rgb)
 
     vim_snprintf(buf, MAX_COLOR_STR_LEN,
                                  (char *)s, RED(rgb), GREEN(rgb), BLUE(rgb));
-    OUT_STR(buf);
+#ifdef FEAT_VTP
+    if (use_wt())
+    {
+       out_flush();
+       buf[1] = '[';
+       vtp_printf(buf);
+    }
+    else
+#endif
+       OUT_STR(buf);
 }
 
     void
index 7eafcc1df61a843a5295854656ae8bd355f4b074..47538a6e11c63ebb2aae5ec32c2353f6eb86dbea 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    848,
 /**/
     847,
 /**/