To: vim_dev@googlegroups.com Subject: Patch 8.2.1732 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1732 Problem: Stuck when win_execute() for a popup causes an error. Solution: Disable the filter callback on error. (issue #6999) Files: src/popupwin.c, src/testdir/term_util.vim, src/testdir/test_popupwin.vim, src/testdir/dumps/Test_popupwin_win_execute.dump *** ../vim-8.2.1731/src/popupwin.c 2020-09-22 21:55:16.214978662 +0200 --- src/popupwin.c 2020-09-23 17:38:42.009979646 +0200 *************** *** 2250,2256 **** --- 2250,2262 ---- // Just in case a check higher up is missing. if (wp == curwin && ERROR_IF_POPUP_WINDOW) + { + // To avoid getting stuck when win_execute() does something that causes + // an error, stop calling the filter callback. + free_callback(&wp->w_filter_cb); + return; + } CHECK_CURBUF; if (wp->w_close_cb.cb_name != NULL) *************** *** 3128,3134 **** /* * Invoke the filter callback for window "wp" with typed character "c". * Uses the global "mod_mask" for modifiers. ! * Returns the return value of the filter. * Careful: The filter may make "wp" invalid! */ static int --- 3134,3141 ---- /* * Invoke the filter callback for window "wp" with typed character "c". * Uses the global "mod_mask" for modifiers. ! * Returns the return value of the filter or -1 for CTRL-C in the current ! * window. * Careful: The filter may make "wp" invalid! */ static int *************** *** 3145,3156 **** if (c == Ctrl_C) { int save_got_int = got_int; // Reset got_int to avoid the callback isn't called. got_int = FALSE; popup_close_with_retval(wp, -1); got_int |= save_got_int; ! return 1; } argv[0].v_type = VAR_NUMBER; --- 3152,3169 ---- if (c == Ctrl_C) { int save_got_int = got_int; + int was_curwin = wp == curwin; // Reset got_int to avoid the callback isn't called. got_int = FALSE; popup_close_with_retval(wp, -1); got_int |= save_got_int; ! ! // If the popup is the current window it probably fails to close. Then ! // do not consume the key. ! if (was_curwin && wp == curwin) ! return -1; ! return TRUE; } argv[0].v_type = VAR_NUMBER; *************** *** 3238,3244 **** popup_reset_handled(POPUP_HANDLED_2); state = get_real_state(); ! while (!res && (wp = find_next_popup(FALSE, POPUP_HANDLED_2)) != NULL) if (wp->w_filter_cb.cb_name != NULL && (wp->w_filter_mode & state) != 0) res = invoke_popup_filter(wp, c); --- 3251,3258 ---- popup_reset_handled(POPUP_HANDLED_2); state = get_real_state(); ! while (res == FALSE ! && (wp = find_next_popup(FALSE, POPUP_HANDLED_2)) != NULL) if (wp->w_filter_cb.cb_name != NULL && (wp->w_filter_mode & state) != 0) res = invoke_popup_filter(wp, c); *************** *** 3254,3260 **** } recursive = FALSE; KeyTyped = save_KeyTyped; ! return res; } /* --- 3268,3276 ---- } recursive = FALSE; KeyTyped = save_KeyTyped; ! ! // When interrupted return FALSE to avoid looping. ! return res == -1 ? FALSE : res; } /* *** ../vim-8.2.1731/src/testdir/term_util.vim 2020-09-04 18:34:06.116621660 +0200 --- src/testdir/term_util.vim 2020-09-23 17:24:48.487975151 +0200 *************** *** 5,10 **** --- 5,12 ---- finish endif + source shared.vim + " For most tests we need to be able to run terminal Vim with 256 colors. On " MS-Windows the console only has 16 colors and the GUI can't run in a " terminal. *************** *** 51,56 **** --- 53,59 ---- " "rows" - height of the terminal window (max. 20) " "cols" - width of the terminal window (max. 78) " "statusoff" - number of lines the status is offset from default + " "wait_for_ruler" - if zero then don't wait for ruler to show func RunVimInTerminal(arguments, options) " If Vim doesn't exit a swap file remains, causing other tests to fail. " Remove it here. *** ../vim-8.2.1731/src/testdir/test_popupwin.vim 2020-09-23 12:28:46.425898006 +0200 --- src/testdir/test_popupwin.vim 2020-09-23 17:32:19.458926088 +0200 *************** *** 1556,1561 **** --- 1556,1585 ---- call delete('XtestPopupNormal') endfunc + " this tests that we don't get stuck with an error in "win_execute()" + func Test_popup_filter_win_execute() + CheckScreendump + + let lines =<< trim END + let g:winid = popup_create('some text', {'filter': 'invalidfilter'}) + call timer_start(0, {-> win_execute(g:winid, 'invalidCommand')}) + END + call writefile(lines, 'XtestPopupWinExecute') + let buf = RunVimInTerminal('-S XtestPopupWinExecute', #{rows: 10, wait_for_ruler: 0}) + + call WaitFor({-> term_getline(buf, 9) =~ 'Not an editor command: invalidCommand'}) + call term_sendkeys(buf, "\") + call WaitFor({-> term_getline(buf, 9) =~ 'Unknown function: invalidfilter'}) + call term_sendkeys(buf, "\") + call WaitFor({-> term_getline(buf, 9) =~ 'Not allowed in a popup window'}) + call term_sendkeys(buf, "\") + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_popupwin_win_execute', {}) + + call StopVimInTerminal(buf) + call delete('XtestPopupWinExecute') + endfunc + func ShowDialog(key, result) let s:cb_res = 999 let winid = popup_dialog('do you want to quit (Yes/no)?', #{ *** ../vim-8.2.1731/src/testdir/dumps/Test_popupwin_win_execute.dump 2020-09-23 17:39:44.745821773 +0200 --- src/testdir/dumps/Test_popupwin_win_execute.dump 2020-09-23 17:14:25.289356651 +0200 *************** *** 0 **** --- 1,10 ---- + > +0&#ffffff0@74 + |~+0#4040ff13&| @73 + |~| @73 + |~| @73 + |~| @31| +0#0000000&@8| +0#4040ff13&@32 + |~| @73 + |~| @73 + |~| @73 + |~| @73 + | +0#0000000&@56|0|,|0|-|1| @8|A|l@1| *** ../vim-8.2.1731/src/version.c 2020-09-23 15:56:47.132579290 +0200 --- src/version.c 2020-09-23 17:39:24.841871919 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 1732, /**/ -- Are leaders born or made? And if they're made, can we return them under warranty? (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///