# HG changeset patch # User Bram Moolenaar # Date 1590854404 -7200 # Node ID ecaceb5c5644759ae69fae9ff8ab19d59f013af1 # Parent 7d6b68ad708ca6d3d253f26aa7a8876d2e4453cd patch 8.2.0848: MS-Windows: the Windows terminal code has some flaws Commit: https://github.com/vim/vim/commit/06b7b58455f9c09be3d1c36d174ffbfdf4efcd79 Author: Bram Moolenaar Date: Sat May 30 17:49:25 2020 +0200 patch 8.2.0848: MS-Windows: the Windows terminal code has some flaws 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) diff --git a/src/os_win32.c b/src/os_win32.c --- a/src/os_win32.c +++ b/src/os_win32.c @@ -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 = 0x # 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); diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro --- a/src/proto/os_win32.pro +++ b/src/proto/os_win32.pro @@ -71,6 +71,8 @@ void used_file_arg(char *name, int liter 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); diff --git a/src/term.c b/src/term.c --- a/src/term.c +++ b/src/term.c @@ -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 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 848, +/**/ 847, /**/ 846,