# HG changeset patch # User Bram Moolenaar # Date 1566668703 -7200 # Node ID bdddd215bf094a874bc2e7e18f30988646988ae6 # Parent 6b66c868f9aa011918efc97fb1fabf974d3c2658 patch 8.1.1920: cannot always close a popup when filter consumes all events Commit: https://github.com/vim/vim/commit/f63962378dc32c7253e4825b4b0f414a81c1dd3e Author: Bram Moolenaar Date: Sat Aug 24 19:36:00 2019 +0200 patch 8.1.1920: cannot always close a popup when filter consumes all events Problem: Cannot close a popup by the X when a filter consumes all events. Solution: Check for a click on the close button before invoking filters. (closes #4858) diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -222,14 +222,22 @@ popup_on_border(win_T *wp, int row, int } /* - * Return TRUE if "row"/"col" is on the "X" button of the popup. + * Return TRUE and close the popup if "row"/"col" is on the "X" button of the + * popup and w_popup_close is POPCLOSE_BUTTON. * The values are relative to the top-left corner. - * Caller should check w_popup_close is POPCLOSE_BUTTON. + * Caller should check the left mouse button was clicked. + * Return TRUE if the popup was closed. */ int -popup_on_X_button(win_T *wp, int row, int col) +popup_close_if_on_X(win_T *wp, int row, int col) { - return row == 0 && col == popup_width(wp) - 1; + if (wp->w_popup_close == POPCLOSE_BUTTON + && row == 0 && col == popup_width(wp) - 1) + { + popup_close_for_mouse_click(wp); + return TRUE; + } + return FALSE; } // Values set when dragging a popup window starts. @@ -2635,6 +2643,16 @@ popup_do_filter(int c) popup_reset_handled(); + if (c == K_LEFTMOUSE) + { + int row = mouse_row; + int col = mouse_col; + + wp = mouse_find_win(&row, &col, FIND_POPUP); + if (wp != NULL && popup_close_if_on_X(wp, row, col)) + return TRUE; + } + while (!res && (wp = find_next_popup(FALSE)) != NULL) if (wp->w_filter_cb.cb_name != NULL) res = invoke_popup_filter(wp, c); diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro --- a/src/proto/popupwin.pro +++ b/src/proto/popupwin.pro @@ -1,6 +1,6 @@ /* popupwin.c */ int popup_on_border(win_T *wp, int row, int col); -int popup_on_X_button(win_T *wp, int row, int col); +int popup_close_if_on_X(win_T *wp, int row, int col); void popup_start_drag(win_T *wp, int row, int col); void popup_drag(win_T *wp); void popup_set_firstline(win_T *wp); diff --git a/src/testdir/dumps/Test_popupwin_close_04.dump b/src/testdir/dumps/Test_popupwin_close_04.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_close_04.dump @@ -0,0 +1,10 @@ +>1+0&#ffffff0| @37|╔+0#0000001#ffd7ff255|═@5|X| +0#0000000#ffffff0@27 +|2| @37|║+0#0000001#ffd7ff255|b|a|r|f|o@1|║| +0#0000000#ffffff0@27 +|3| @37|╚+0#0000001#ffd7ff255|═@5|╝| +0#0000000#ffffff0@27 +|4| @73 +|5| |n+0#0000001#ffd7ff255|o| |b|o|r|d|e|r| |h|e|r|X| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255@12|X| +0#0000000#ffffff0@38 +|6| @20| +0#0000001#ffd7ff255|o|n|l|y| |p|a|d@1|i|n|g| | +0#0000000#ffffff0@38 +|7| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@38 +|8| @73 +|9| @73 +|:|c|a|l@1| |C|r|e|a|t|e|W|i|t|h|M|e|n|u|F|i|l|t|e|r|(|)| @28|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_close_05.dump b/src/testdir/dumps/Test_popupwin_close_05.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_close_05.dump @@ -0,0 +1,10 @@ +>1+0&#ffffff0| @73 +|2| @73 +|3| @73 +|4| @73 +|5| |n+0#0000001#ffd7ff255|o| |b|o|r|d|e|r| |h|e|r|X| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255@12|X| +0#0000000#ffffff0@38 +|6| @20| +0#0000001#ffd7ff255|o|n|l|y| |p|a|d@1|i|n|g| | +0#0000000#ffffff0@38 +|7| @20| +0#0000001#ffd7ff255@13| +0#0000000#ffffff0@38 +|8| @73 +|9| @73 +|:|c|a|l@1| |C|r|e|a|t|e|W|i|t|h|M|e|n|u|F|i|l|t|e|r|(|)| @28|1|,|1| @10|T|o|p| diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -420,6 +420,15 @@ func Test_popup_close_with_mouse() call feedkeys("\\\", "xt") endfunc map :call test_setmouse(3, 17) + func CreateWithMenuFilter() + let winid = popup_create('barfoo', #{ + \ close: 'button', + \ filter: 'popup_filter_menu', + \ border: [], + \ line: 1, + \ col: 40, + \ }) + endfunc END call writefile(lines, 'XtestPopupClose') let buf = RunVimInTerminal('-S XtestPopupClose', #{rows: 10}) @@ -431,6 +440,14 @@ func Test_popup_close_with_mouse() call term_sendkeys(buf, ":call CloseWithClick()\") call VerifyScreenDump(buf, 'Test_popupwin_close_03', {}) + call term_sendkeys(buf, ":call CreateWithMenuFilter()\") + call VerifyScreenDump(buf, 'Test_popupwin_close_04', {}) + + " We have to send the actual mouse code, feedkeys() would be caught the + " filter. + call term_sendkeys(buf, "\[<0;47;1M") + call VerifyScreenDump(buf, 'Test_popupwin_close_05', {}) + " clean up call StopVimInTerminal(buf) call delete('XtestPopupClose') diff --git a/src/ui.c b/src/ui.c --- a/src/ui.c +++ b/src/ui.c @@ -3070,7 +3070,8 @@ retnomove: if (row < 0 || col < 0) // check if it makes sense return IN_UNKNOWN; - // find the window where the row is in + // find the window where the row is in and adjust "row" and "col" to be + // relative to top-left of the window wp = mouse_find_win(&row, &col, FIND_POPUP); if (wp == NULL) return IN_UNKNOWN; @@ -3083,11 +3084,8 @@ retnomove: { on_sep_line = 0; in_popup_win = TRUE; - if (wp->w_popup_close == POPCLOSE_BUTTON - && which_button == MOUSE_LEFT - && popup_on_X_button(wp, row, col)) + if (which_button == MOUSE_LEFT && popup_close_if_on_X(wp, row, col)) { - popup_close_for_mouse_click(wp); return IN_UNKNOWN; } else if ((wp->w_popup_flags & (POPF_DRAG | POPF_RESIZE)) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1920, +/**/ 1919, /**/ 1918,