summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-05-30 17:49:25 +0200
committerBram Moolenaar <Bram@vim.org>2020-05-30 17:49:25 +0200
commit06b7b58455f9c09be3d1c36d174ffbfdf4efcd79 (patch)
tree9c5cdb61f44c35413acc043f9a118fbbb41bd743
parent367d59e6ba65cf554d167933775fa17e40dcc6a7 (diff)
downloadvim-git-06b7b58455f9c09be3d1c36d174ffbfdf4efcd79.tar.gz
patch 8.2.0848: MS-Windows: the Windows terminal code has some flawsv8.2.0848
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)
-rw-r--r--src/os_win32.c105
-rw-r--r--src/proto/os_win32.pro2
-rw-r--r--src/term.c11
-rw-r--r--src/version.c2
4 files changed, 108 insertions, 12 deletions
diff --git a/src/os_win32.c b/src/os_win32.c
index 89c7c5e3a..2c5670d9d 100644
--- 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 = 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);
diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro
index d8f9ac36b..85c09c0ba 100644
--- a/src/proto/os_win32.pro
+++ b/src/proto/os_win32.pro
@@ -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);
diff --git a/src/term.c b/src/term.c
index 588058941..d774ebc98 100644
--- 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
index 7eafcc1df..47538a6e1 100644
--- 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,