To: vim_dev@googlegroups.com Subject: Patch 9.0.0850 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0850 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) Files: src/os_win32.c, src/term.c *** ../vim-9.0.0849/src/os_win32.c 2022-11-06 11:27:35.894580888 +0000 --- src/os_win32.c 2022-11-09 23:51:51.200100354 +0000 *************** *** 204,224 **** 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 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_WT (wt_working) # else # define USE_VTP 0 --- 204,220 ---- static int wt_working = 0; static void wt_init(); 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 ! # define USE_VTP (vtp_working && is_term_win32()) # define USE_WT (wt_working) # else # define USE_VTP 0 *************** *** 334,340 **** if (s_dwMax == 0) { ! if (!USE_WT && nLength == -1) return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents); GetNumberOfConsoleInputEvents(hInput, &dwEvents); if (dwEvents == 0 && nLength == -1) --- 330,336 ---- if (s_dwMax == 0) { ! if (!vtp_working && nLength == -1) return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents); GetNumberOfConsoleInputEvents(hInput, &dwEvents); if (dwEvents == 0 && nLength == -1) *************** *** 1255,1261 **** static void decode_mouse_wheel(MOUSE_EVENT_RECORD *pmer) { - win_T *wp; int horizontal = (pmer->dwEventFlags == MOUSE_HWHEELED); int zDelta = pmer->dwButtonState; --- 1251,1256 ---- *************** *** 1265,1271 **** #ifdef FEAT_PROP_POPUP int lcol = g_xMouse; int lrow = g_yMouse; ! wp = mouse_find_win(&lrow, &lcol, FIND_POPUP); if (wp != NULL && popup_is_popup(wp)) { g_nMouseClick = -1; --- 1260,1266 ---- #ifdef FEAT_PROP_POPUP int lcol = g_xMouse; int lrow = g_yMouse; ! win_T *wp = mouse_find_win(&lrow, &lcol, FIND_POPUP); if (wp != NULL && popup_is_popup(wp)) { g_nMouseClick = -1; *************** *** 1605,1611 **** static void mch_set_cursor_shape(int thickness) { ! if (USE_VTP || USE_WT) { if (*T_CSI == NUL) { --- 1600,1606 ---- static void mch_set_cursor_shape(int thickness) { ! if (vtp_working) { if (*T_CSI == NUL) { *************** *** 2977,2982 **** --- 2972,2980 ---- 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,3042 **** # ifdef FEAT_CLIPBOARD win_clip_init(); # endif - - vtp_flag_init(); - vtp_init(); - wt_init(); } /* --- 3031,3036 ---- *************** *** 5854,5860 **** g_fTermcapMode = FALSE; } ! #endif // FEAT_GUI_MSWIN #if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) --- 5848,5854 ---- g_fTermcapMode = FALSE; } ! #endif // !FEAT_GUI_MSWIN || VIMDLL #if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) *************** *** 5876,5882 **** COORD coord, DWORD n) { ! if (!USE_VTP) { DWORD dwDummy; --- 5870,5876 ---- COORD coord, DWORD n) { ! if (!vtp_working) { DWORD dwDummy; *************** *** 5901,5907 **** { g_coord.X = g_coord.Y = 0; ! if (!USE_VTP) clear_chars(g_coord, Rows * Columns); else { --- 5895,5901 ---- { g_coord.X = g_coord.Y = 0; ! if (!vtp_working) clear_chars(g_coord, Rows * Columns); else { *************** *** 5920,5926 **** { COORD save = g_coord; ! if (!USE_VTP) clear_chars(g_coord, (Rows - g_coord.Y - 1) * Columns + (Columns - g_coord.X)); else --- 5914,5920 ---- { COORD save = g_coord; ! if (!vtp_working) clear_chars(g_coord, (Rows - g_coord.Y - 1) * Columns + (Columns - g_coord.X)); else *************** *** 5943,5949 **** { COORD save = g_coord; ! if (!USE_VTP) clear_chars(g_coord, Columns - g_coord.X); else { --- 5937,5943 ---- { COORD save = g_coord; ! if (!vtp_working) clear_chars(g_coord, Columns - g_coord.X); else { *************** *** 6045,6051 **** clip.Bottom = g_srScrollRegion.Bottom; fill.Char.AsciiChar = ' '; ! if (!USE_VTP) fill.Attributes = g_attrCurrent; else fill.Attributes = g_attrDefault; --- 6039,6049 ---- clip.Bottom = g_srScrollRegion.Bottom; fill.Char.AsciiChar = ' '; ! if (!(vtp_working ! #ifdef FEAT_TERMGUICOLORS ! && (p_tgc || t_colors >= 256) ! #endif ! )) fill.Attributes = g_attrCurrent; else fill.Attributes = g_attrDefault; *************** *** 6074,6080 **** } } ! if (USE_WT) { COORD coord; int i; --- 6072,6078 ---- } } ! if (vtp_working) { COORD coord; int i; *************** *** 6116,6122 **** clip.Bottom = g_srScrollRegion.Bottom; fill.Char.AsciiChar = ' '; ! if (!USE_VTP) fill.Attributes = g_attrCurrent; else fill.Attributes = g_attrDefault; --- 6114,6120 ---- clip.Bottom = g_srScrollRegion.Bottom; fill.Char.AsciiChar = ' '; ! if (!vtp_working) fill.Attributes = g_attrCurrent; else fill.Attributes = g_attrDefault; *************** *** 6143,6149 **** } } ! if (USE_WT) { COORD coord; int i; --- 6141,6147 ---- } } ! if (vtp_working) { COORD coord; int i; *************** *** 6169,6175 **** if (x < 1 || x > (unsigned)Columns || y < 1 || y > (unsigned)Rows) return; ! if (!USE_VTP) { // There are reports of double-width characters not displayed // correctly. This workaround should fix it, similar to how it's done --- 6167,6177 ---- if (x < 1 || x > (unsigned)Columns || y < 1 || y > (unsigned)Rows) return; ! 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,6221 **** { g_attrCurrent = (g_attrCurrent & 0xf0) + (wAttr & 0x0f); ! if (!USE_VTP) SetConsoleTextAttribute(g_hConOut, g_attrCurrent); else vtp_sgr_bulk(wAttr); --- 6217,6223 ---- { g_attrCurrent = (g_attrCurrent & 0xf0) + (wAttr & 0x0f); ! if (!vtp_working) SetConsoleTextAttribute(g_hConOut, g_attrCurrent); else vtp_sgr_bulk(wAttr); *************** *** 6227,6233 **** { g_attrCurrent = (g_attrCurrent & 0x0f) + ((wAttr & 0x0f) << 4); ! if (!USE_VTP) SetConsoleTextAttribute(g_hConOut, g_attrCurrent); else vtp_sgr_bulk(wAttr); --- 6229,6235 ---- { g_attrCurrent = (g_attrCurrent & 0x0f) + ((wAttr & 0x0f) << 4); ! if (!vtp_working) SetConsoleTextAttribute(g_hConOut, g_attrCurrent); else vtp_sgr_bulk(wAttr); *************** *** 6240,6246 **** static void normvideo(void) { ! if (!USE_VTP) textattr(g_attrDefault); else vtp_sgr_bulk(0); --- 6242,6248 ---- static void normvideo(void) { ! if (!vtp_working) textattr(g_attrDefault); else vtp_sgr_bulk(0); *************** *** 6326,6332 **** coordOrigin, &dwDummy); Sleep(15); // wait for 15 msec ! if (!USE_VTP) WriteConsoleOutputAttribute(g_hConOut, oldattrs, Rows * Columns, coordOrigin, &dwDummy); vim_free(oldattrs); --- 6328,6334 ---- coordOrigin, &dwDummy); Sleep(15); // wait for 15 msec ! if (!vtp_working) WriteConsoleOutputAttribute(g_hConOut, oldattrs, Rows * Columns, coordOrigin, &dwDummy); vim_free(oldattrs); *************** *** 6341,6347 **** { s_cursor_visible = fVisible; ! if (USE_VTP) vtp_printf("\033[?25%c", fVisible ? 'h' : 'l'); # ifdef MCH_CURSOR_SHAPE --- 6343,6349 ---- { s_cursor_visible = fVisible; ! if (vtp_working) vtp_printf("\033[?25%c", fVisible ? 'h' : 'l'); # ifdef MCH_CURSOR_SHAPE *************** *** 6413,6419 **** } } ! if (!USE_VTP) { FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cells, coord, &written); --- 6415,6425 ---- } } ! if (!(vtp_working ! #ifdef FEAT_TERMGUICOLORS ! && (p_tgc || t_colors >= 256) ! #endif ! )) { FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cells, coord, &written); *************** *** 6453,6459 **** } // Cursor under VTP is always in the correct position, no need to reset. ! if (!USE_VTP) gotoxy(g_coord.X + 1, g_coord.Y + 1); return written; --- 6459,6469 ---- } // Cursor under VTP is always in the correct position, no need to reset. ! if (!(vtp_working ! #ifdef FEAT_TERMGUICOLORS ! && (p_tgc || t_colors >= 256) ! #endif ! )) gotoxy(g_coord.X + 1, g_coord.Y + 1); return written; *************** *** 6749,6760 **** normvideo(); else if (argc == 1) { ! if (USE_VTP) ! textcolor((WORD) arg1); else ! textattr((WORD) arg1); } ! else if (USE_VTP) vtp_sgr_bulks(argc, args); } else if (argc == 2 && *p == 'H') --- 6759,6774 ---- normvideo(); else if (argc == 1) { ! if (vtp_working ! # ifdef FEAT_TERMGUICOLORS ! && (p_tgc || t_colors >= 256) ! # endif ! ) ! textcolor((WORD)arg1); else ! textattr((WORD)arg1); } ! else if (vtp_working) vtp_sgr_bulks(argc, args); } else if (argc == 2 && *p == 'H') *************** *** 6893,6899 **** if (s[l] == ' ' && s[l + 1] == 'q') { // DECSCUSR (cursor style) sequences ! if (USE_VTP || USE_WT) vtp_printf("%.*s", l + 2, s); // Pass through s += l + 2; len -= l + 1; --- 6907,6913 ---- if (s[l] == ' ' && s[l + 1] == 'q') { // DECSCUSR (cursor style) sequences ! if (vtp_working) vtp_printf("%.*s", l + 2, s); // Pass through s += l + 2; len -= l + 1; *************** *** 7932,7937 **** --- 7946,7953 ---- * 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,8006 **** 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) { COLORREF bg; bg = (COLORREF)csbi.ColorTable[g_color_index_bg]; bg = (GetRValue(bg) << 16) | (GetGValue(bg) << 8) | GetBValue(bg); default_console_color_bg = bg; } - 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(); --- 7994,8020 ---- static void vtp_init(void) { # ifdef FEAT_TERMGUICOLORS ! 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; } # endif set_console_color_rgb(); *************** *** 8217,8248 **** guicolor_T fg, bg; int ctermfg, ctermbg; ! if (!USE_VTP) return; 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); ! 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); # endif } --- 8231,8265 ---- guicolor_T fg, bg; int ctermfg, ctermbg; ! if (!vtp_working) return; get_default_console_color(&ctermfg, &ctermbg, &fg, &bg); ! if (p_tgc || t_colors >= 256) { term_fg_rgb_color(fg); term_bg_rgb_color(bg); return; } ! 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); ! 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,8264 **** --- 8276,8282 ---- 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,8284 **** { ctermfg = -1; if (id > 0) ! syn_id2cterm_bg(id, &ctermfg, &ctermbg); ! guifg = ctermfg != -1 ? ctermtoxterm(ctermfg) : default_console_color_fg; ! 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) { cterm_normal_bg_gui_color = guibg = ctermbg != -1 ? ctermtoxterm(ctermbg) : INVALCOLOR; --- 8285,8311 ---- { ctermfg = -1; if (id > 0) ! 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; ! } } if (guibg == INVALCOLOR) { ctermbg = -1; if (id > 0) ! syn_id2cterm_bg(id, &dummynull, &ctermbg); ! if (vtp_working) { cterm_normal_bg_gui_color = guibg = ctermbg != -1 ? ctermtoxterm(ctermbg) : INVALCOLOR; *************** *** 8308,8318 **** reset_console_color_rgb(void) { # ifdef FEAT_TERMGUICOLORS - CONSOLE_SCREEN_BUFFER_INFOEX csbi; ! if (USE_WT) return; csbi.cbSize = sizeof(csbi); GetConsoleScreenBufferInfoEx(g_hConOut, &csbi); --- 8335,8346 ---- reset_console_color_rgb(void) { # ifdef FEAT_TERMGUICOLORS ! if (vtp_working) return; + CONSOLE_SCREEN_BUFFER_INFOEX csbi; + csbi.cbSize = sizeof(csbi); GetConsoleScreenBufferInfoEx(g_hConOut, &csbi); *************** *** 8332,8337 **** --- 8360,8368 ---- restore_console_color_rgb(void) { # ifdef FEAT_TERMGUICOLORS + if (vtp_working) + return; + CONSOLE_SCREEN_BUFFER_INFOEX csbi; csbi.cbSize = sizeof(csbi); *************** *** 8349,8355 **** void control_console_color_rgb(void) { ! if (USE_VTP) set_console_color_rgb(); else reset_console_color_rgb(); --- 8380,8386 ---- void control_console_color_rgb(void) { ! if (vtp_working) set_console_color_rgb(); else reset_console_color_rgb(); *** ../vim-9.0.0849/src/term.c 2022-11-02 13:30:37.542314565 +0000 --- src/term.c 2022-11-09 23:39:22.135337195 +0000 *************** *** 2987,2993 **** vim_snprintf(buf, MAX_COLOR_STR_LEN, (char *)s, RED(rgb), GREEN(rgb), BLUE(rgb)); #ifdef FEAT_VTP ! if (use_wt()) { out_flush(); buf[1] = '['; --- 2987,2993 ---- vim_snprintf(buf, MAX_COLOR_STR_LEN, (char *)s, RED(rgb), GREEN(rgb), BLUE(rgb)); #ifdef FEAT_VTP ! if (has_vtp_working()) { out_flush(); buf[1] = '['; *************** *** 3001,3007 **** void term_fg_rgb_color(guicolor_T rgb) { ! term_rgb_color(T_8F, rgb); } void --- 3001,3008 ---- void term_fg_rgb_color(guicolor_T rgb) { ! if (rgb != INVALCOLOR) ! term_rgb_color(T_8F, rgb); } void *** ../vim-9.0.0849/src/version.c 2022-11-09 23:29:10.611134995 +0000 --- src/version.c 2022-11-09 23:42:21.763567238 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 850, /**/ -- hundred-and-one symptoms of being an internet addict: 38. You wake up at 3 a.m. to go to the bathroom and stop and check your e-mail on the way back to bed. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///