]> granicus.if.org Git - vim/commitdiff
patch 8.1.1920: cannot always close a popup when filter consumes all events v8.1.1920
authorBram Moolenaar <Bram@vim.org>
Sat, 24 Aug 2019 17:36:00 +0000 (19:36 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 24 Aug 2019 17:36:00 +0000 (19:36 +0200)
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)

src/popupwin.c
src/proto/popupwin.pro
src/testdir/dumps/Test_popupwin_close_04.dump [new file with mode: 0644]
src/testdir/dumps/Test_popupwin_close_05.dump [new file with mode: 0644]
src/testdir/test_popupwin.vim
src/ui.c
src/version.c

index e8abf6dc38f0afb0a55d360bb72536de422a3bda..7aef2735842499c77be12e7abc0d352735a454d0 100644 (file)
@@ -222,14 +222,22 @@ popup_on_border(win_T *wp, int row, int col)
 }
 
 /*
- * 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);
index 0507114224d23249e9f989996f62df763b3c1ced..dab117e744feee9652ab86e655bfc12695df33aa 100644 (file)
@@ -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 (file)
index 0000000..91d7f09
--- /dev/null
@@ -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 (file)
index 0000000..75ce052
--- /dev/null
@@ -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| 
index abae5dbef659063b3227769d54666cf30d66005a..94718578746b62f9b0f6cb1bf14dd5c27d120b37 100644 (file)
@@ -420,6 +420,15 @@ func Test_popup_close_with_mouse()
          call feedkeys("\<F4>\<LeftMouse>\<LeftRelease>", "xt")
        endfunc
        map <silent> <F4> :call test_setmouse(3, 17)<CR>
+       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()\<CR>")
   call VerifyScreenDump(buf, 'Test_popupwin_close_03', {})
 
+  call term_sendkeys(buf, ":call CreateWithMenuFilter()\<CR>")
+  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, "\<Esc>[<0;47;1M")
+  call VerifyScreenDump(buf, 'Test_popupwin_close_05', {})
+
   " clean up
   call StopVimInTerminal(buf)
   call delete('XtestPopupClose')
index 7095eda02e8f77192614d3b4c77268ad5e920002..a0723592e23eb237c01ec425f42f44aff4cad81e 100644 (file)
--- 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))
index 9e5a7b225f805548af58b7aa0c18424b5912dc81..9d4e89b482136658970bcaaa16d4cba2f7e8d44b 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1920,
 /**/
     1919,
 /**/