]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.0850: MS-Windows Terminal has unstable color control v9.0.0850
authorChristopher Plewright <chris@createng.com>
Wed, 9 Nov 2022 23:55:52 +0000 (23:55 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 9 Nov 2022 23:55:52 +0000 (23:55 +0000)
Problem:    MS-Windows Terminal has unstable color control.
Solution:   Do not try to read the old command prompt colortable, use modern
            VT sequences. (Christopher Plewright, closes #11450,
            closes #11373)

src/os_win32.c
src/term.c
src/version.c

index b5ded95d597fc61cbe8b7b28483cd81cf77cbb94..a9d48633d06a7c062b69cd31bf1bba9f009c0f79 100644 (file)
@@ -204,21 +204,17 @@ 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;
-static guicolor_T store_console_fg_rgb;
-
 static int g_color_index_bg = 0;
 static int g_color_index_fg = 7;
 
 # ifdef FEAT_TERMGUICOLORS
+static guicolor_T save_console_bg_rgb;
+static guicolor_T save_console_fg_rgb;
+static guicolor_T store_console_bg_rgb;
+static guicolor_T store_console_fg_rgb;
 static int default_console_color_bg = 0x000000; // black
 static int default_console_color_fg = 0xc0c0c0; // white
-# endif
-
-# ifdef FEAT_TERMGUICOLORS
-#  define USE_VTP              (vtp_working && is_term_win32() && (p_tgc || (!p_tgc && t_colors >= 256)))
+#  define USE_VTP              (vtp_working && is_term_win32())
 #  define USE_WT               (wt_working)
 # else
 #  define USE_VTP              0
@@ -334,7 +330,7 @@ read_console_input(
 
     if (s_dwMax == 0)
     {
-       if (!USE_WT && nLength == -1)
+       if (!vtp_working && nLength == -1)
            return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents);
        GetNumberOfConsoleInputEvents(hInput, &dwEvents);
        if (dwEvents == 0 && nLength == -1)
@@ -1255,7 +1251,6 @@ mch_bevalterm_changed(void)
     static void
 decode_mouse_wheel(MOUSE_EVENT_RECORD *pmer)
 {
-    win_T   *wp;
     int            horizontal = (pmer->dwEventFlags == MOUSE_HWHEELED);
     int            zDelta = pmer->dwButtonState;
 
@@ -1265,7 +1260,7 @@ decode_mouse_wheel(MOUSE_EVENT_RECORD *pmer)
 #ifdef FEAT_PROP_POPUP
     int lcol = g_xMouse;
     int lrow = g_yMouse;
-    wp = mouse_find_win(&lrow, &lcol, FIND_POPUP);
+    win_T *wp = mouse_find_win(&lrow, &lcol, FIND_POPUP);
     if (wp != NULL && popup_is_popup(wp))
     {
        g_nMouseClick = -1;
@@ -1605,7 +1600,7 @@ decode_mouse_event(
     static void
 mch_set_cursor_shape(int thickness)
 {
-    if (USE_VTP || USE_WT)
+    if (vtp_working)
     {
        if (*T_CSI == NUL)
        {
@@ -2977,6 +2972,9 @@ mch_init_c(void)
        create_conin();
     g_hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
 
+    wt_init();
+    vtp_flag_init();
+    vtp_init();
 # ifdef FEAT_RESTORE_ORIG_SCREEN
     // Save the initial console buffer for later restoration
     SaveConsoleBuffer(&g_cbOrig);
@@ -3033,10 +3031,6 @@ mch_init_c(void)
 # ifdef FEAT_CLIPBOARD
     win_clip_init();
 # endif
-
-    vtp_flag_init();
-    vtp_init();
-    wt_init();
 }
 
 /*
@@ -5854,7 +5848,7 @@ termcap_mode_end(void)
 
     g_fTermcapMode = FALSE;
 }
-#endif // FEAT_GUI_MSWIN
+#endif // !FEAT_GUI_MSWIN || VIMDLL
 
 
 #if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)
@@ -5876,7 +5870,7 @@ clear_chars(
     COORD coord,
     DWORD n)
 {
-    if (!USE_VTP)
+    if (!vtp_working)
     {
        DWORD dwDummy;
 
@@ -5901,7 +5895,7 @@ clear_screen(void)
 {
     g_coord.X = g_coord.Y = 0;
 
-    if (!USE_VTP)
+    if (!vtp_working)
        clear_chars(g_coord, Rows * Columns);
     else
     {
@@ -5920,7 +5914,7 @@ clear_to_end_of_display(void)
 {
     COORD save = g_coord;
 
-    if (!USE_VTP)
+    if (!vtp_working)
        clear_chars(g_coord, (Rows - g_coord.Y - 1)
                                           * Columns + (Columns - g_coord.X));
     else
@@ -5943,7 +5937,7 @@ clear_to_end_of_line(void)
 {
     COORD save = g_coord;
 
-    if (!USE_VTP)
+    if (!vtp_working)
        clear_chars(g_coord, Columns - g_coord.X);
     else
     {
@@ -6045,7 +6039,11 @@ insert_lines(unsigned cLines)
     clip.Bottom = g_srScrollRegion.Bottom;
 
     fill.Char.AsciiChar = ' ';
-    if (!USE_VTP)
+    if (!(vtp_working
+#ifdef FEAT_TERMGUICOLORS
+               && (p_tgc || t_colors >= 256)
+#endif
+        ))
        fill.Attributes = g_attrCurrent;
     else
        fill.Attributes = g_attrDefault;
@@ -6074,7 +6072,7 @@ insert_lines(unsigned cLines)
        }
     }
 
-    if (USE_WT)
+    if (vtp_working)
     {
        COORD coord;
        int i;
@@ -6116,7 +6114,7 @@ delete_lines(unsigned cLines)
     clip.Bottom = g_srScrollRegion.Bottom;
 
     fill.Char.AsciiChar = ' ';
-    if (!USE_VTP)
+    if (!vtp_working)
        fill.Attributes = g_attrCurrent;
     else
        fill.Attributes = g_attrDefault;
@@ -6143,7 +6141,7 @@ delete_lines(unsigned cLines)
        }
     }
 
-    if (USE_WT)
+    if (vtp_working)
     {
        COORD coord;
        int i;
@@ -6169,7 +6167,11 @@ gotoxy(
     if (x < 1 || x > (unsigned)Columns || y < 1 || y > (unsigned)Rows)
        return;
 
-    if (!USE_VTP)
+    if (!(vtp_working
+#ifdef FEAT_TERMGUICOLORS
+               && (p_tgc || t_colors >= 256)
+#endif
+        ))
     {
        // There are reports of double-width characters not displayed
        // correctly.  This workaround should fix it, similar to how it's done
@@ -6215,7 +6217,7 @@ textcolor(WORD wAttr)
 {
     g_attrCurrent = (g_attrCurrent & 0xf0) + (wAttr & 0x0f);
 
-    if (!USE_VTP)
+    if (!vtp_working)
        SetConsoleTextAttribute(g_hConOut, g_attrCurrent);
     else
        vtp_sgr_bulk(wAttr);
@@ -6227,7 +6229,7 @@ textbackground(WORD wAttr)
 {
     g_attrCurrent = (g_attrCurrent & 0x0f) + ((wAttr & 0x0f) << 4);
 
-    if (!USE_VTP)
+    if (!vtp_working)
        SetConsoleTextAttribute(g_hConOut, g_attrCurrent);
     else
        vtp_sgr_bulk(wAttr);
@@ -6240,7 +6242,7 @@ textbackground(WORD wAttr)
     static void
 normvideo(void)
 {
-    if (!USE_VTP)
+    if (!vtp_working)
        textattr(g_attrDefault);
     else
        vtp_sgr_bulk(0);
@@ -6326,7 +6328,7 @@ visual_bell(void)
                               coordOrigin, &dwDummy);
 
     Sleep(15);     // wait for 15 msec
-    if (!USE_VTP)
+    if (!vtp_working)
        WriteConsoleOutputAttribute(g_hConOut, oldattrs, Rows * Columns,
                                coordOrigin, &dwDummy);
     vim_free(oldattrs);
@@ -6341,7 +6343,7 @@ cursor_visible(BOOL fVisible)
 {
     s_cursor_visible = fVisible;
 
-    if (USE_VTP)
+    if (vtp_working)
        vtp_printf("\033[?25%c", fVisible ? 'h' : 'l');
 
 # ifdef MCH_CURSOR_SHAPE
@@ -6413,7 +6415,11 @@ write_chars(
        }
     }
 
-    if (!USE_VTP)
+    if (!(vtp_working
+#ifdef FEAT_TERMGUICOLORS
+           && (p_tgc || t_colors >= 256)
+#endif
+       ))
     {
        FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cells,
                                    coord, &written);
@@ -6453,7 +6459,11 @@ write_chars(
     }
 
     // Cursor under VTP is always in the correct position, no need to reset.
-    if (!USE_VTP)
+    if (!(vtp_working
+#ifdef FEAT_TERMGUICOLORS
+               && (p_tgc || t_colors >= 256)
+#endif
+        ))
        gotoxy(g_coord.X + 1, g_coord.Y + 1);
 
     return written;
@@ -6749,12 +6759,16 @@ notsgr:
                        normvideo();
                    else if (argc == 1)
                    {
-                       if (USE_VTP)
-                           textcolor((WORD) arg1);
+                       if (vtp_working
+# ifdef FEAT_TERMGUICOLORS
+                               && (p_tgc || t_colors >= 256)
+# endif
+                          )
+                           textcolor((WORD)arg1);
                        else
-                           textattr((WORD) arg1);
+                           textattr((WORD)arg1);
                    }
-                   else if (USE_VTP)
+                   else if (vtp_working)
                        vtp_sgr_bulks(argc, args);
                }
                else if (argc == 2 && *p == 'H')
@@ -6893,7 +6907,7 @@ notsgr:
            if (s[l] == ' ' && s[l + 1] == 'q')
            {
                // DECSCUSR (cursor style) sequences
-               if (USE_VTP || USE_WT)
+               if (vtp_working)
                    vtp_printf("%.*s", l + 2, s);   // Pass through
                s += l + 2;
                len -= l + 1;
@@ -7932,6 +7946,8 @@ mch_setenv(char *var, char *value, int x UNUSED)
  * Not stable now.
  */
 #define CONPTY_STABLE_BUILD        MAKE_VER(10, 0, 32767)  // T.B.D.
+// Note: Windows 11 (build >= 22000 means Windows 11, even though the major
+// version says 10!)
 
     static void
 vtp_flag_init(void)
@@ -7978,29 +7994,27 @@ vtp_flag_init(void)
     static void
 vtp_init(void)
 {
-    CONSOLE_SCREEN_BUFFER_INFOEX csbi;
 # ifdef FEAT_TERMGUICOLORS
-    COLORREF fg;
-# endif
-
-    csbi.cbSize = sizeof(csbi);
-    GetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
-    save_console_bg_rgb = (guicolor_T)csbi.ColorTable[g_color_index_bg];
-    save_console_fg_rgb = (guicolor_T)csbi.ColorTable[g_color_index_fg];
-    store_console_bg_rgb = save_console_bg_rgb;
-    store_console_fg_rgb = save_console_fg_rgb;
-
-# ifdef FEAT_TERMGUICOLORS
-    if (!USE_WT)
+    if (!vtp_working)
     {
+       CONSOLE_SCREEN_BUFFER_INFOEX csbi;
+       csbi.cbSize = sizeof(csbi);
+       GetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+       save_console_bg_rgb = (guicolor_T)csbi.ColorTable[g_color_index_bg];
+       save_console_fg_rgb = (guicolor_T)csbi.ColorTable[g_color_index_fg];
+       store_console_bg_rgb = save_console_bg_rgb;
+       store_console_fg_rgb = save_console_fg_rgb;
+
        COLORREF bg;
        bg = (COLORREF)csbi.ColorTable[g_color_index_bg];
        bg = (GetRValue(bg) << 16) | (GetGValue(bg) << 8) | GetBValue(bg);
        default_console_color_bg = bg;
+
+       COLORREF fg;
+       fg = (COLORREF)csbi.ColorTable[g_color_index_fg];
+       fg = (GetRValue(fg) << 16) | (GetGValue(fg) << 8) | GetBValue(fg);
+       default_console_color_fg = fg;
     }
-    fg = (COLORREF)csbi.ColorTable[g_color_index_fg];
-    fg = (GetRValue(fg) << 16) | (GetGValue(fg) << 8) | GetBValue(fg);
-    default_console_color_fg = fg;
 # endif
 
     set_console_color_rgb();
@@ -8217,32 +8231,35 @@ set_console_color_rgb(void)
     guicolor_T fg, bg;
     int                ctermfg, ctermbg;
 
-    if (!USE_VTP)
+    if (!vtp_working)
        return;
 
     get_default_console_color(&ctermfg, &ctermbg, &fg, &bg);
 
-    if (USE_WT)
+    if (p_tgc || t_colors >= 256)
     {
        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);
+    if (!conpty_working)
+    {
+       fg = (GetRValue(fg) << 16) | (GetGValue(fg) << 8) | GetBValue(fg);
+       bg = (GetRValue(bg) << 16) | (GetGValue(bg) << 8) | GetBValue(bg);
 
-    csbi.cbSize = sizeof(csbi);
-    GetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+       csbi.cbSize = sizeof(csbi);
+       GetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
 
-    csbi.cbSize = sizeof(csbi);
-    csbi.srWindow.Right += 1;
-    csbi.srWindow.Bottom += 1;
-    store_console_bg_rgb = csbi.ColorTable[g_color_index_bg];
-    store_console_fg_rgb = csbi.ColorTable[g_color_index_fg];
-    csbi.ColorTable[g_color_index_bg] = (COLORREF)bg;
-    csbi.ColorTable[g_color_index_fg] = (COLORREF)fg;
-    SetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+       csbi.cbSize = sizeof(csbi);
+       csbi.srWindow.Right += 1;
+       csbi.srWindow.Bottom += 1;
+       store_console_bg_rgb = csbi.ColorTable[g_color_index_bg];
+       store_console_fg_rgb = csbi.ColorTable[g_color_index_fg];
+       csbi.ColorTable[g_color_index_bg] = (COLORREF)bg;
+       csbi.ColorTable[g_color_index_fg] = (COLORREF)fg;
+       SetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+    }
 # endif
 }
 
@@ -8259,6 +8276,7 @@ get_default_console_color(
     guicolor_T guibg = INVALCOLOR;
     int ctermfg = 0;
     int ctermbg = 0;
+    int dummynull = 0;
 
     id = syn_name2id((char_u *)"Normal");
     if (id > 0 && p_tgc)
@@ -8267,18 +8285,27 @@ get_default_console_color(
     {
        ctermfg = -1;
        if (id > 0)
-           syn_id2cterm_bg(id, &ctermfg, &ctermbg);
-       guifg = ctermfg != -1 ? ctermtoxterm(ctermfg)
+           syn_id2cterm_bg(id, &ctermfg, &dummynull);
+       if (vtp_working)
+       {
+           cterm_normal_fg_gui_color = guifg =
+                           ctermfg != -1 ? ctermtoxterm(ctermfg) : INVALCOLOR;
+           ctermfg = ctermfg < 0 ? 0 : ctermfg;
+       }
+       else
+       {
+           guifg = ctermfg != -1 ? ctermtoxterm(ctermfg)
                                                    : default_console_color_fg;
-       cterm_normal_fg_gui_color = guifg;
-       ctermfg = ctermfg < 0 ? 0 : ctermfg;
+           cterm_normal_fg_gui_color = guifg;
+           ctermfg = ctermfg < 0 ? 0 : ctermfg;
+       }
     }
     if (guibg == INVALCOLOR)
     {
        ctermbg = -1;
        if (id > 0)
-           syn_id2cterm_bg(id, &ctermfg, &ctermbg);
-       if (USE_WT)
+           syn_id2cterm_bg(id, &dummynull, &ctermbg);
+       if (vtp_working)
        {
            cterm_normal_bg_gui_color = guibg =
                            ctermbg != -1 ? ctermtoxterm(ctermbg) : INVALCOLOR;
@@ -8308,11 +8335,12 @@ get_default_console_color(
 reset_console_color_rgb(void)
 {
 # ifdef FEAT_TERMGUICOLORS
-    CONSOLE_SCREEN_BUFFER_INFOEX csbi;
 
-    if (USE_WT)
+    if (vtp_working)
        return;
 
+    CONSOLE_SCREEN_BUFFER_INFOEX csbi;
+
     csbi.cbSize = sizeof(csbi);
     GetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
 
@@ -8332,6 +8360,9 @@ reset_console_color_rgb(void)
 restore_console_color_rgb(void)
 {
 # ifdef FEAT_TERMGUICOLORS
+    if (vtp_working)
+       return;
+
     CONSOLE_SCREEN_BUFFER_INFOEX csbi;
 
     csbi.cbSize = sizeof(csbi);
@@ -8349,7 +8380,7 @@ restore_console_color_rgb(void)
     void
 control_console_color_rgb(void)
 {
-    if (USE_VTP)
+    if (vtp_working)
        set_console_color_rgb();
     else
        reset_console_color_rgb();
index e4b6587cdf5bf76e76e79578465d732f326594b6..4d43139e9b560f7793bed53b3dc3dac90a1a90ff 100644 (file)
@@ -2987,7 +2987,7 @@ term_rgb_color(char_u *s, guicolor_T rgb)
     vim_snprintf(buf, MAX_COLOR_STR_LEN,
                                  (char *)s, RED(rgb), GREEN(rgb), BLUE(rgb));
 #ifdef FEAT_VTP
-    if (use_wt())
+    if (has_vtp_working())
     {
        out_flush();
        buf[1] = '[';
@@ -3001,7 +3001,8 @@ term_rgb_color(char_u *s, guicolor_T rgb)
     void
 term_fg_rgb_color(guicolor_T rgb)
 {
-    term_rgb_color(T_8F, rgb);
+    if (rgb != INVALCOLOR)
+       term_rgb_color(T_8F, rgb);
 }
 
     void
index 6884514cd6d1b10aae2449d09b65658a9eee3d99..3433ebce08653ef553eef373b56b599799c4e06a 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    850,
 /**/
     849,
 /**/