]> granicus.if.org Git - vim/commitdiff
patch 8.1.1963: popup window filter may be called recursively v8.1.1963
authorBram Moolenaar <Bram@vim.org>
Sun, 1 Sep 2019 21:27:05 +0000 (23:27 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 1 Sep 2019 21:27:05 +0000 (23:27 +0200)
Problem:    Popup window filter may be called recursively when using a Normal
            mode command.
Solution:   Prevent recursiveness. (closes #4887)  Also restore KeyTyped.

src/popupwin.c
src/testdir/test_popupwin.vim
src/version.c

index 7145291814bec5859b5494be6dfdd7bfe2a78ef8..abf40e8c066c1e2263acf7344db47211e2e7dc60 100644 (file)
@@ -2764,8 +2764,14 @@ invoke_popup_filter(win_T *wp, int c)
     int
 popup_do_filter(int c)
 {
+    static int recursive = FALSE;
     int                res = FALSE;
     win_T      *wp;
+    int                save_KeyTyped = KeyTyped;
+
+    if (recursive)
+       return FALSE;
+    recursive = TRUE;
 
     popup_reset_handled();
 
@@ -2776,13 +2782,15 @@ popup_do_filter(int c)
 
        wp = mouse_find_win(&row, &col, FIND_POPUP);
        if (wp != NULL && popup_close_if_on_X(wp, row, col))
-           return TRUE;
+           res = TRUE;
     }
 
     while (!res && (wp = find_next_popup(FALSE)) != NULL)
        if (wp->w_filter_cb.cb_name != NULL)
            res = invoke_popup_filter(wp, c);
 
+    recursive = FALSE;
+    KeyTyped = save_KeyTyped;
     return res;
 }
 
index f0959e76706d1ed57c64dc2cafaf7565ccc3cef6..8f2b5dcd17003537c02c8a2ab82f63bfe2af83db 100644 (file)
@@ -1919,6 +1919,31 @@ func Test_popupwin_with_buffer()
   call delete('XsomeFile')
 endfunc
 
+func Test_popupwin_with_buffer_and_filter()
+  new Xwithfilter
+  call setline(1, range(100))
+  let bufnr = bufnr()
+  hide
+
+  func BufferFilter(win, key)
+    if a:key == 'G'
+      " recursive use of "G" does not cause problems.
+      call win_execute(a:win, 'normal! G')
+      return 1
+    endif
+    return 0
+  endfunc
+
+  let winid = popup_create(bufnr, #{maxheight: 5, filter: 'BufferFilter'})
+  call assert_equal(1, popup_getpos(winid).firstline)
+  redraw
+  call feedkeys("G", 'xt')
+  call assert_equal(99, popup_getpos(winid).firstline)
+
+  call popup_close(winid)
+  exe 'bwipe! ' .. bufnr
+endfunc
+
 func Test_popupwin_width()
   let winid = popup_create(repeat(['short', 'long long long line', 'medium width'], 50), #{
        \ maxwidth: 40,
index 7fd13b802f00f66702981db28f35d403739c1b87..fe8b34ae651a42d09db6fe4bbdb6b95b66c8469c 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1963,
 /**/
     1962,
 /**/