To: vim_dev@googlegroups.com Subject: Patch 9.0.0245 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0245 Problem: Mechanism to prevent recursive screen updating is incomplete. Solution: Add "redraw_not_allowed" and set it in build_stl_str_hl(). (issue #10952) Files: src/globals.h, src/buffer.c, src/drawscreen.c, src/proto/drawscreen.pro, src/change.c, src/digraph.c, src/ex_docmd.c, src/highlight.c, src/main.c, src/message.c, src/misc1.c, src/screen.c *** ../vim-9.0.0244/src/globals.h 2022-08-21 10:40:02.447904003 +0100 --- src/globals.h 2022-08-22 14:51:05.420395816 +0100 *************** *** 600,608 **** #endif // While redrawing the screen this flag is set. It means the screen size ! // ('lines' and 'rows') must not be changed. EXTERN int updating_screen INIT(= FALSE); #ifdef MESSAGE_QUEUE // While closing windows or buffers messages should not be handled to avoid // using invalid windows or buffers. --- 600,612 ---- #endif // While redrawing the screen this flag is set. It means the screen size ! // ('lines' and 'rows') must not be changed and prevents recursive updating. EXTERN int updating_screen INIT(= FALSE); + // While computing a statusline and the like we do not want any w_redr_type or + // must_redraw to be set. + EXTERN int redraw_not_allowed INIT(= FALSE); + #ifdef MESSAGE_QUEUE // While closing windows or buffers messages should not be handled to avoid // using invalid windows or buffers. *** ../vim-9.0.0244/src/buffer.c 2022-08-16 20:23:57.394232793 +0100 --- src/buffer.c 2022-08-22 14:48:54.284578376 +0100 *************** *** 4228,4237 **** char_u win_tmp[TMPLEN]; char_u *usefmt = fmt; stl_hlrec_T *sp; ! int save_must_redraw = must_redraw; ! int save_redr_type = curwin->w_redr_type; int save_KeyTyped = KeyTyped; if (stl_items == NULL) { stl_items = ALLOC_MULT(stl_item_T, stl_items_len); --- 4228,4242 ---- char_u win_tmp[TMPLEN]; char_u *usefmt = fmt; stl_hlrec_T *sp; ! int save_redraw_not_allowed = redraw_not_allowed; int save_KeyTyped = KeyTyped; + // When inside update_screen() we do not want redrawing a statusline, + // ruler, title, etc. to trigger another redraw, it may cause an endless + // loop. + if (updating_screen) + redraw_not_allowed = TRUE; + if (stl_items == NULL) { stl_items = ALLOC_MULT(stl_item_T, stl_items_len); *************** *** 4968,4978 **** else stl_items[curitem].stl_type = Empty; if (opt == STL_VIM_EXPR) vim_free(str); - - if (num >= 0 || (!itemisflag && str && *str)) - prevchar_isflag = FALSE; // Item not NULL, but not a flag curitem++; } *p = NUL; --- 4973,4983 ---- else stl_items[curitem].stl_type = Empty; + if (num >= 0 || (!itemisflag && str != NULL && *str != NUL)) + prevchar_isflag = FALSE; // Item not NULL, but not a flag + // if (opt == STL_VIM_EXPR) vim_free(str); curitem++; } *p = NUL; *************** *** 5125,5137 **** sp->userhl = 0; } ! // When inside update_screen we do not want redrawing a statusline, ruler, ! // title, etc. to trigger another redraw, it may cause an endless loop. ! if (updating_screen) ! { ! must_redraw = save_must_redraw; ! curwin->w_redr_type = save_redr_type; ! } // A user function may reset KeyTyped, restore it. KeyTyped = save_KeyTyped; --- 5130,5136 ---- sp->userhl = 0; } ! redraw_not_allowed = save_redraw_not_allowed; // A user function may reset KeyTyped, restore it. KeyTyped = save_KeyTyped; *** ../vim-9.0.0244/src/drawscreen.c 2022-08-14 14:16:07.983582313 +0100 --- src/drawscreen.c 2022-08-22 15:03:25.527308467 +0100 *************** *** 3154,3160 **** win_T *wp, int type) { ! if (!exiting && wp->w_redr_type < type) { wp->w_redr_type = type; if (type >= UPD_NOT_VALID) --- 3154,3160 ---- win_T *wp, int type) { ! if (!exiting && !redraw_not_allowed && wp->w_redr_type < type) { wp->w_redr_type = type; if (type >= UPD_NOT_VALID) *************** *** 3186,3192 **** FOR_ALL_WINDOWS(wp) redraw_win_later(wp, type); // This may be needed when switching tabs. ! if (must_redraw < type) must_redraw = type; } --- 3186,3202 ---- FOR_ALL_WINDOWS(wp) redraw_win_later(wp, type); // This may be needed when switching tabs. ! set_must_redraw(type); ! } ! ! /* ! * Set "must_redraw" to "type" unless it already has a higher value ! * or it is currently not allowed. ! */ ! void ! set_must_redraw(int type) ! { ! if (!redraw_not_allowed && must_redraw < type) must_redraw = type; } *** ../vim-9.0.0244/src/proto/drawscreen.pro 2022-06-27 23:15:02.000000000 +0100 --- src/proto/drawscreen.pro 2022-08-22 15:07:23.360695135 +0100 *************** *** 13,18 **** --- 13,19 ---- void redraw_win_later(win_T *wp, int type); void redraw_later_clear(void); void redraw_all_later(int type); + void set_must_redraw(int type); void redraw_curbuf_later(int type); void redraw_buf_later(buf_T *buf, int type); void redraw_buf_line_later(buf_T *buf, linenr_T lnum); *** ../vim-9.0.0244/src/change.c 2022-08-14 14:16:07.983582313 +0100 --- src/change.c 2022-08-22 15:08:43.567997816 +0100 *************** *** 559,565 **** linenr_T last = lnume + xtra - 1; // last line after the change #endif // Mark this window to be redrawn later. ! if (wp->w_redr_type < UPD_VALID) wp->w_redr_type = UPD_VALID; // Check if a change in the buffer has invalidated the cached --- 559,565 ---- linenr_T last = lnume + xtra - 1; // last line after the change #endif // Mark this window to be redrawn later. ! if (!redraw_not_allowed && wp->w_redr_type < UPD_VALID) wp->w_redr_type = UPD_VALID; // Check if a change in the buffer has invalidated the cached *************** *** 671,678 **** // Call update_screen() later, which checks out what needs to be redrawn, // since it notices b_mod_set and then uses b_mod_*. ! if (must_redraw < UPD_VALID) ! must_redraw = UPD_VALID; // when the cursor line is changed always trigger CursorMoved if (lnum <= curwin->w_cursor.lnum --- 671,677 ---- // Call update_screen() later, which checks out what needs to be redrawn, // since it notices b_mod_set and then uses b_mod_*. ! set_must_redraw(UPD_VALID); // when the cursor line is changed always trigger CursorMoved if (lnum <= curwin->w_cursor.lnum *** ../vim-9.0.0244/src/digraph.c 2022-08-14 14:16:07.983582313 +0100 --- src/digraph.c 2022-08-22 15:09:01.599851222 +0100 *************** *** 2028,2034 **** // clear screen, because some digraphs may be wrong, in which case we // messed up ScreenLines ! must_redraw = UPD_CLEAR; } static void --- 2028,2034 ---- // clear screen, because some digraphs may be wrong, in which case we // messed up ScreenLines ! set_must_redraw(UPD_CLEAR); } static void *** ../vim-9.0.0244/src/ex_docmd.c 2022-08-14 14:16:07.987582278 +0100 --- src/ex_docmd.c 2022-08-22 15:09:31.163618334 +0100 *************** *** 7116,7122 **** #ifdef FEAT_GUI hold_gui_events = 0; #endif ! must_redraw = UPD_CLEAR; pending_exmode_active = TRUE; main_loop(FALSE, TRUE); --- 7116,7122 ---- #ifdef FEAT_GUI hold_gui_events = 0; #endif ! set_must_redraw(UPD_CLEAR); pending_exmode_active = TRUE; main_loop(FALSE, TRUE); *** ../vim-9.0.0244/src/highlight.c 2022-08-14 14:16:07.991582244 +0100 --- src/highlight.c 2022-08-22 15:04:42.538358150 +0100 *************** *** 939,945 **** if (!gui.in_use && !gui.starting) #endif { ! must_redraw = UPD_CLEAR; if (termcap_active && color >= 0) term_fg_color(color); } --- 939,945 ---- if (!gui.in_use && !gui.starting) #endif { ! set_must_redraw(UPD_CLEAR); if (termcap_active && color >= 0) term_fg_color(color); } *************** *** 962,968 **** if (!gui.in_use && !gui.starting) #endif { ! must_redraw = UPD_CLEAR; if (color >= 0) { int dark = -1; --- 962,968 ---- if (!gui.in_use && !gui.starting) #endif { ! set_must_redraw(UPD_CLEAR); if (color >= 0) { int dark = -1; *************** *** 1005,1011 **** if (!gui.in_use && !gui.starting) #endif { ! must_redraw = UPD_CLEAR; if (termcap_active && color >= 0) term_ul_color(color); } --- 1005,1011 ---- if (!gui.in_use && !gui.starting) #endif { ! set_must_redraw(UPD_CLEAR); if (termcap_active && color >= 0) term_ul_color(color); } *************** *** 1919,1925 **** FALSE, TRUE, FALSE)) { gui_mch_new_colors(); ! must_redraw = UPD_CLEAR; } # ifdef FEAT_GUI_X11 if (set_group_colors((char_u *)"Menu", --- 1919,1925 ---- FALSE, TRUE, FALSE)) { gui_mch_new_colors(); ! set_must_redraw(UPD_CLEAR); } # ifdef FEAT_GUI_X11 if (set_group_colors((char_u *)"Menu", *************** *** 1929,1935 **** # ifdef FEAT_MENU gui_mch_new_menu_colors(); # endif ! must_redraw = UPD_CLEAR; } # ifdef FEAT_BEVAL_GUI if (set_group_colors((char_u *)"Tooltip", --- 1929,1935 ---- # ifdef FEAT_MENU gui_mch_new_menu_colors(); # endif ! set_must_redraw(UPD_CLEAR); } # ifdef FEAT_BEVAL_GUI if (set_group_colors((char_u *)"Tooltip", *************** *** 1939,1945 **** # ifdef FEAT_TOOLBAR gui_mch_new_tooltip_colors(); # endif ! must_redraw = UPD_CLEAR; } # endif if (set_group_colors((char_u *)"Scrollbar", --- 1939,1945 ---- # ifdef FEAT_TOOLBAR gui_mch_new_tooltip_colors(); # endif ! set_must_redraw(UPD_CLEAR); } # endif if (set_group_colors((char_u *)"Scrollbar", *************** *** 1947,1953 **** FALSE, FALSE, FALSE)) { gui_new_scrollbar_colors(); ! must_redraw = UPD_CLEAR; } # endif } --- 1947,1953 ---- FALSE, FALSE, FALSE)) { gui_new_scrollbar_colors(); ! set_must_redraw(UPD_CLEAR); } # endif } *************** *** 1973,1979 **** // color cterm_normal_fg_gui_color = HL_TABLE()[idx].sg_gui_fg; cterm_normal_bg_gui_color = HL_TABLE()[idx].sg_gui_bg; ! must_redraw = UPD_CLEAR; } } } --- 1973,1979 ---- // color cterm_normal_fg_gui_color = HL_TABLE()[idx].sg_gui_fg; cterm_normal_bg_gui_color = HL_TABLE()[idx].sg_gui_bg; ! set_must_redraw(UPD_CLEAR); } } } *************** *** 2545,2551 **** clear_hl_tables(); ! must_redraw = UPD_CLEAR; for (i = 0; i < highlight_ga.ga_len; ++i) set_hl_attr(i); --- 2545,2551 ---- clear_hl_tables(); ! set_must_redraw(UPD_CLEAR); for (i = 0; i < highlight_ga.ga_len; ++i) set_hl_attr(i); *** ../vim-9.0.0244/src/main.c 2022-08-14 14:16:07.991582244 +0100 --- src/main.c 2022-08-22 15:04:58.602173683 +0100 *************** *** 686,692 **** && !gui.in_use #endif ) ! must_redraw = UPD_CLEAR; else { screenclear(); // clear screen --- 686,692 ---- && !gui.in_use #endif ) ! set_must_redraw(UPD_CLEAR); else { screenclear(); // clear screen *** ../vim-9.0.0244/src/message.c 2022-08-19 13:17:18.098545090 +0100 --- src/message.c 2022-08-22 15:05:50.361608682 +0100 *************** *** 1143,1149 **** FILE *save_scriptout; if (redraw == TRUE) ! must_redraw = UPD_CLEAR; // If using ":silent cmd", don't wait for a return. Also don't set // need_wait_return to do it later. --- 1143,1149 ---- FILE *save_scriptout; if (redraw == TRUE) ! set_must_redraw(UPD_CLEAR); // If using ":silent cmd", don't wait for a return. Also don't set // need_wait_return to do it later. *************** *** 2490,2497 **** } #endif ++msg_scrolled; ! if (must_redraw < UPD_VALID) ! must_redraw = UPD_VALID; } /* --- 2490,2496 ---- } #endif ++msg_scrolled; ! set_must_redraw(UPD_VALID); } /* *** ../vim-9.0.0244/src/misc1.c 2022-08-14 14:16:07.995582211 +0100 --- src/misc1.c 2022-08-22 15:06:05.905447300 +0100 *************** *** 413,422 **** clear_chartabsize_arg(&cts); col = (int)cts.cts_vcol; ! /* ! * If list mode is on, then the '$' at the end of the line may take up one ! * extra column. ! */ if (wp->w_p_list && wp->w_lcs_chars.eol != NUL) col += 1; --- 413,420 ---- clear_chartabsize_arg(&cts); col = (int)cts.cts_vcol; ! // If list mode is on, then the '$' at the end of the line may take up one ! // extra column. if (wp->w_p_list && wp->w_lcs_chars.eol != NUL) col += 1; *************** *** 585,592 **** if (wp->w_buffer == buf && wp->w_status_height) { wp->w_redr_status = TRUE; ! if (must_redraw < UPD_VALID) ! must_redraw = UPD_VALID; } } --- 583,589 ---- if (wp->w_buffer == buf && wp->w_status_height) { wp->w_redr_status = TRUE; ! set_must_redraw(UPD_VALID); } } *** ../vim-9.0.0244/src/screen.c 2022-08-14 14:16:07.999582175 +0100 --- src/screen.c 2022-08-22 15:10:08.659335538 +0100 *************** *** 2906,2912 **** screen_Rows = Rows; screen_Columns = Columns; ! must_redraw = UPD_CLEAR; // need to clear the screen later if (doclear) screenclear2(); #ifdef FEAT_GUI --- 2906,2912 ---- screen_Rows = Rows; screen_Columns = Columns; ! set_must_redraw(UPD_CLEAR); // need to clear the screen later if (doclear) screenclear2(); #ifdef FEAT_GUI *** ../vim-9.0.0244/src/version.c 2022-08-22 13:14:31.896769307 +0100 --- src/version.c 2022-08-22 15:17:31.204776603 +0100 *************** *** 733,734 **** --- 733,736 ---- { /* Add new patch number below this line */ + /**/ + 245, /**/ -- ARTHUR: Charge! [They all charge with swords drawn towards the RABBIT. A tremendous twenty second fight with Peckinpahish shots and borrowing heavily also on the Kung Fu and karate-type films ensues, in which some four KNIGHTS are comprehensively killed.] ARTHUR: Run away! Run away! "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// 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 ///