Skip to content
Permalink
Browse files

patch 8.1.1799: cannot avoid mapping for a popup window

Problem:    Cannot avoid mapping for a popup window.
Solution:   Add the "mapping" property, default TRUE.
  • Loading branch information...
brammool committed Aug 3, 2019
1 parent eda35f7 commit 749fa0af85232be1d44b77a09161f71cdbace62c
Showing with 69 additions and 5 deletions.
  1. +25 −4 runtime/doc/popup.txt
  2. +3 −0 src/getchar.c
  3. +30 −1 src/popupwin.c
  4. +1 −0 src/proto/popupwin.pro
  5. +7 −0 src/testdir/test_popupwin.vim
  6. +2 −0 src/version.c
  7. +1 −0 src/vim.h
@@ -246,6 +246,7 @@ popup_dialog({what}, {options}) *popup_dialog()*
\ drag: 1,
\ border: [],
\ padding: [],
\ mapping: 0,
\})
< Use {options} to change the properties. E.g. add a 'filter'
option with value 'popup_filter_yesno'. Example: >
@@ -369,12 +370,20 @@ popup_menu({what}, {options}) *popup_menu()*
\ cursorline: 1,
\ padding: [0,1,0,1],
\ filter: 'popup_filter_menu',
\ mapping: 0,
\ })
< The current line is highlighted with a match using
"PopupSelected", or "PmenuSel" if that is not defined.

Use {options} to change the properties. Should at least set
"callback" to a function that handles the selected item.
Example: >
func ColorSelected(id, result)
" use a:result
endfunc
call popup_menu(['red', 'green', 'blue'], #{
\ callback: 'ColorSelected',
\ })


popup_move({id}, {options}) *popup_move()*
@@ -433,16 +442,17 @@ popup_setoptions({id}, {options}) *popup_setoptions()*
borderhighlight
callback
close
drag
resize
cursorline
drag
filter
firstline
flip
highlight
mapping
mask
moved
padding
resize
scrollbar
scrollbarhighlight
thumbhighlight
@@ -615,6 +625,9 @@ The second argument of |popup_create()| is a dictionary with options:
Default is zero, except for |popup_menu()|.
filter A callback that can filter typed characters, see
|popup-filter|.
mapping Allow for key mapping. When FALSE and the popup is
visible and has a filter callback key mapping is
disabled. Default value is TRUE.
callback A callback that is called when the popup closes, e.g.
when using |popup_filter_menu()|, see |popup-callback|.

@@ -671,8 +684,11 @@ key as a string, e.g.: >
endif
return 0
endfunc

Currently the key is what results after any mapping. This may change...
< *popup-mapping*
Normally the key is what results after any mapping, since the keys pass on as
normal input if the filter does not use it. If the filter consumes all the
keys, set the "mapping" property to zero so that mappings do not get in the
way. This is default for |popup_menu()| and |popup_dialog()|.

Some common key actions:
x close the popup (see note below)
@@ -703,6 +719,11 @@ the second argument of `popup_close()`.
If the popup is force-closed, e.g. because the cursor moved or CTRL-C was
pressed, the number -1 is passed to the callback.

Example: >
func SelectedColor(id, result)
echo 'choice made: ' .. a:result
endfunc


POPUP SCROLLBAR *popup-scrollbar*

@@ -1574,6 +1574,9 @@ vgetc(void)
if (mod_mask
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
|| im_is_preediting()
#endif
#if defined(FEAT_TEXT_PROP)
|| popup_no_mapping()
#endif
)
{
@@ -800,6 +800,15 @@ apply_general_options(win_T *wp, dict_T *dict)
set_callback(&wp->w_filter_cb, &callback);
}
}
di = dict_find(dict, (char_u *)"mapping", -1);
if (di != NULL)
{
nr = dict_get_number(dict, (char_u *)"mapping");
if (nr)
wp->w_popup_flags |= POPF_MAPPING;
else
wp->w_popup_flags &= ~POPF_MAPPING;
}

di = dict_find(dict, (char_u *)"callback", -1);
if (di != NULL)
@@ -1413,7 +1422,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
if (rettv != NULL)
rettv->vval.v_number = wp->w_id;
wp->w_popup_pos = POPPOS_TOPLEFT;
wp->w_popup_flags = POPF_IS_POPUP;
wp->w_popup_flags = POPF_IS_POPUP | POPF_MAPPING;

if (buf != NULL)
{
@@ -1561,6 +1570,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
wp->w_popup_pos = POPPOS_CENTER;
wp->w_zindex = POPUPWIN_DIALOG_ZINDEX;
wp->w_popup_flags |= POPF_DRAG;
wp->w_popup_flags &= ~POPF_MAPPING;
for (i = 0; i < 4; ++i)
{
wp->w_popup_border[i] = 1;
@@ -2501,6 +2511,25 @@ popup_do_filter(int c)
return res;
}

/*
* Return TRUE if there is a popup visible with a filter callback and the
* "mapping" property off.
*/
int
popup_no_mapping(void)
{
int round;
win_T *wp;

for (round = 1; round <= 2; ++round)
for (wp = round == 1 ? first_popupwin : curtab->tp_first_popupwin;
wp != NULL; wp = wp->w_next)
if (wp->w_filter_cb.cb_name != NULL
&& (wp->w_popup_flags & (POPF_HIDDEN | POPF_MAPPING)) == 0)
return TRUE;
return FALSE;
}

/*
* Called when the cursor moved: check if any popup needs to be closed if the
* cursor moved far enough.
@@ -38,6 +38,7 @@ int error_if_popup_window(void);
void popup_reset_handled(void);
win_T *find_next_popup(int lowest);
int popup_do_filter(int c);
int popup_no_mapping(void);
void popup_check_cursor_pos(void);
void may_update_popup_mask(int type);
void update_popups(void (*win_update)(win_T *wp));
@@ -657,6 +657,7 @@ func Test_popup_invalid_arguments()
call assert_fails('call popup_create("text", #{mask: ["asdf"]})', 'E475:')
call popup_clear()
call assert_fails('call popup_create("text", #{mask: test_null_list()})', 'E475:')
call assert_fails('call popup_create("text", #{mapping: []})', 'E745:')
call popup_clear()
endfunc

@@ -1203,6 +1204,8 @@ func Test_popup_menu()
let s:cb_winid = a:id
let s:cb_res = a:res
endfunc
" mapping won't be used in popup
map j k

let winid = ShowMenu(" ", 1)
let winid = ShowMenu("j \<CR>", 2)
@@ -1215,6 +1218,7 @@ func Test_popup_menu()
let winid = ShowMenu("\<C-C>", -1)

delfunc QuitCallback
unmap j
endfunc

func Test_popup_menu_screenshot()
@@ -2194,6 +2198,9 @@ func Test_previewpopup()
call term_sendkeys(buf, "/another\<CR>\<C-W>}")
call VerifyScreenDump(buf, 'Test_popupwin_previewpopup_4', {})

call term_sendkeys(buf, ":cd ..\<CR>:\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_previewpopup_5', {})

call StopVimInTerminal(buf)
call delete('Xtags')
call delete('Xtagfile')
@@ -773,6 +773,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1799,
/**/
1798,
/**/
@@ -621,6 +621,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define POPF_ON_CMDLINE 0x10 // popup overlaps command line
#define POPF_DRAG 0x20 // popup can be moved by dragging
#define POPF_RESIZE 0x40 // popup can be resized by dragging
#define POPF_MAPPING 0x80 // mapping keys

#ifdef FEAT_TEXT_PROP
# define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0)

0 comments on commit 749fa0a

Please sign in to comment.
You can’t perform that action at this time.