# HG changeset patch # User Bram Moolenaar # Date 1562958904 -7200 # Node ID d82b0cfb1e827e8e2160d5d9087fab1264ec0868 # Parent 21b9633e27d1b0e691fcc54a656b96f92f3100f9 patch 8.1.1673: cannot easily find the popup window at a certain position commit https://github.com/vim/vim/commit/b4f0628fc5892e1bb9f0f780af782ff47ef277ed Author: Bram Moolenaar Date: Fri Jul 12 21:07:54 2019 +0200 patch 8.1.1673: cannot easily find the popup window at a certain position Problem: Cannot easily find the popup window at a certain position. Solution: Add popup_locate(). diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt --- a/runtime/doc/popup.txt +++ b/runtime/doc/popup.txt @@ -170,6 +170,7 @@ Filter functions: Other: |popup_getoptions()| get current options for a popup |popup_getpos()| get actual position and size of a popup + |popup_locate()| find popup window at a screen position DETAILS *popup-function-details* @@ -343,6 +344,13 @@ popup_hide({id}) *popup_hide()* exists but is not a popup window an error is given. *E993* +popup_locate({row}, {col}) *popup_locate()* + Return the |window-ID| of the popup at screen positoin {row} + and {col}. If there are multiple popups the one with the + highest zindex is returned. If there are no popups at this + position then zero is returned. + + popup_menu({what}, {options}) *popup_menu()* Show the {what} near the cursor, handle selecting one of the items with cursorkeys, and close it an item is selected with diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -781,6 +781,7 @@ static struct fst {"popup_getoptions", 1, 1, f_popup_getoptions}, {"popup_getpos", 1, 1, f_popup_getpos}, {"popup_hide", 1, 1, f_popup_hide}, + {"popup_locate", 2, 2, f_popup_locate}, {"popup_menu", 2, 2, f_popup_menu}, {"popup_move", 2, 2, f_popup_move}, {"popup_notification", 2, 2, f_popup_notification}, diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -1890,6 +1890,20 @@ f_popup_getpos(typval_T *argvars, typval win_valid(wp) && (wp->w_popup_flags & POPF_HIDDEN) == 0); } } +/* + * popup_locate({row}, {col}) + */ + void +f_popup_locate(typval_T *argvars, typval_T *rettv) +{ + int row = tv_get_number(&argvars[0]) - 1; + int col = tv_get_number(&argvars[1]) - 1; + win_T *wp; + + wp = mouse_find_win(&row, &col, FIND_POPUP); + if (WIN_IS_POPUP(wp)) + rettv->vval.v_number = wp->w_id; +} /* * For popup_getoptions(): add a "border" or "padding" entry to "dict". diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro --- a/src/proto/popupwin.pro +++ b/src/proto/popupwin.pro @@ -29,6 +29,7 @@ void close_all_popups(void); void f_popup_move(typval_T *argvars, typval_T *rettv); void f_popup_setoptions(typval_T *argvars, typval_T *rettv); void f_popup_getpos(typval_T *argvars, typval_T *rettv); +void f_popup_locate(typval_T *argvars, typval_T *rettv); void f_popup_getoptions(typval_T *argvars, typval_T *rettv); int error_if_popup_window(void); void popup_reset_handled(void); 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 @@ -713,7 +713,7 @@ func Test_popup_time() topleft vnew call setline(1, 'hello') - call popup_create('world', { + let winid = popup_create('world', { \ 'line': 1, \ 'col': 1, \ 'minwidth': 20, @@ -723,6 +723,11 @@ func Test_popup_time() let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '') call assert_equal('world', line) + call assert_equal(winid, popup_locate(1, 1)) + call assert_equal(winid, popup_locate(1, 20)) + call assert_equal(0, popup_locate(1, 21)) + call assert_equal(0, popup_locate(2, 1)) + sleep 700m redraw let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '') diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -778,6 +778,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1673, +/**/ 1672, /**/ 1671,