mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 8.1.1645: cannot use a popup window for a balloon
Problem: Cannot use a popup window for a balloon. Solution: Add popup_beval(). Add the "mousemoved" property. Add the screenpos() function.
This commit is contained in:
190
src/popupwin.c
190
src/popupwin.c
@@ -167,6 +167,35 @@ set_moved_columns(win_T *wp, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Used when popup options contain "mousemoved": set default moved values.
|
||||
*/
|
||||
static void
|
||||
set_mousemoved_values(win_T *wp)
|
||||
{
|
||||
wp->w_popup_mouse_row = mouse_row;
|
||||
wp->w_popup_mouse_mincol = mouse_col;
|
||||
wp->w_popup_mouse_maxcol = mouse_col;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used when popup options contain "moved" with "word" or "WORD".
|
||||
*/
|
||||
static void
|
||||
set_mousemoved_columns(win_T *wp, int flags)
|
||||
{
|
||||
char_u *text;
|
||||
int col;
|
||||
|
||||
if (find_word_under_cursor(mouse_row, mouse_col, TRUE, flags,
|
||||
NULL, NULL, &text, &col) == OK)
|
||||
{
|
||||
wp->w_popup_mouse_mincol = col;
|
||||
wp->w_popup_mouse_maxcol = col + STRLEN(text) - 1;
|
||||
vim_free(text);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if "row"/"col" is on the border of the popup.
|
||||
* The values are relative to the top-left corner.
|
||||
@@ -335,6 +364,53 @@ apply_move_options(win_T *wp, dict_T *d)
|
||||
get_pos_options(wp, d);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_moved_argument(win_T *wp, dictitem_T *di, int mousemoved)
|
||||
{
|
||||
if (di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
|
||||
{
|
||||
char_u *s = di->di_tv.vval.v_string;
|
||||
int flags = 0;
|
||||
|
||||
if (STRCMP(s, "word") == 0)
|
||||
flags = FIND_IDENT | FIND_STRING;
|
||||
else if (STRCMP(s, "WORD") == 0)
|
||||
flags = FIND_STRING;
|
||||
else if (STRCMP(s, "expr") == 0)
|
||||
flags = FIND_IDENT | FIND_STRING | FIND_EVAL;
|
||||
else if (STRCMP(s, "any") != 0)
|
||||
semsg(_(e_invarg2), s);
|
||||
if (flags != 0)
|
||||
{
|
||||
if (mousemoved)
|
||||
set_mousemoved_columns(wp, flags);
|
||||
else
|
||||
set_moved_columns(wp, flags);
|
||||
}
|
||||
}
|
||||
else if (di->di_tv.v_type == VAR_LIST
|
||||
&& di->di_tv.vval.v_list != NULL
|
||||
&& di->di_tv.vval.v_list->lv_len == 2)
|
||||
{
|
||||
list_T *l = di->di_tv.vval.v_list;
|
||||
int mincol = tv_get_number(&l->lv_first->li_tv);
|
||||
int maxcol = tv_get_number(&l->lv_first->li_next->li_tv);
|
||||
|
||||
if (mousemoved)
|
||||
{
|
||||
wp->w_popup_mouse_mincol = mincol;
|
||||
wp->w_popup_mouse_maxcol = maxcol;
|
||||
}
|
||||
else
|
||||
{
|
||||
wp->w_popup_mincol = mincol;
|
||||
wp->w_popup_maxcol = maxcol;
|
||||
}
|
||||
}
|
||||
else
|
||||
semsg(_(e_invarg2), tv_get_string(&di->di_tv));
|
||||
}
|
||||
|
||||
static void
|
||||
check_highlight(dict_T *dict, char *name, char_u **pval)
|
||||
{
|
||||
@@ -541,31 +617,14 @@ apply_general_options(win_T *wp, dict_T *dict)
|
||||
if (di != NULL)
|
||||
{
|
||||
set_moved_values(wp);
|
||||
if (di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
|
||||
{
|
||||
char_u *s = di->di_tv.vval.v_string;
|
||||
int flags = 0;
|
||||
handle_moved_argument(wp, di, FALSE);
|
||||
}
|
||||
|
||||
if (STRCMP(s, "word") == 0)
|
||||
flags = FIND_IDENT | FIND_STRING;
|
||||
else if (STRCMP(s, "WORD") == 0)
|
||||
flags = FIND_STRING;
|
||||
else if (STRCMP(s, "any") != 0)
|
||||
semsg(_(e_invarg2), s);
|
||||
if (flags != 0)
|
||||
set_moved_columns(wp, flags);
|
||||
}
|
||||
else if (di->di_tv.v_type == VAR_LIST
|
||||
&& di->di_tv.vval.v_list != NULL
|
||||
&& di->di_tv.vval.v_list->lv_len == 2)
|
||||
{
|
||||
list_T *l = di->di_tv.vval.v_list;
|
||||
|
||||
wp->w_popup_mincol = tv_get_number(&l->lv_first->li_tv);
|
||||
wp->w_popup_maxcol = tv_get_number(&l->lv_first->li_next->li_tv);
|
||||
}
|
||||
else
|
||||
semsg(_(e_invarg2), tv_get_string(&di->di_tv));
|
||||
di = dict_find(dict, (char_u *)"mousemoved", -1);
|
||||
if (di != NULL)
|
||||
{
|
||||
set_mousemoved_values(wp);
|
||||
handle_moved_argument(wp, di, TRUE);
|
||||
}
|
||||
|
||||
di = dict_find(dict, (char_u *)"filter", -1);
|
||||
@@ -956,6 +1015,7 @@ typedef enum
|
||||
{
|
||||
TYPE_NORMAL,
|
||||
TYPE_ATCURSOR,
|
||||
TYPE_BEVAL,
|
||||
TYPE_NOTIFICATION,
|
||||
TYPE_DIALOG,
|
||||
TYPE_MENU
|
||||
@@ -1137,17 +1197,33 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
|
||||
{
|
||||
wp->w_popup_pos = POPPOS_BOTLEFT;
|
||||
setcursor_mayforce(TRUE);
|
||||
wp->w_wantline = screen_screenrow();
|
||||
wp->w_wantline = curwin->w_winrow + curwin->w_wrow;
|
||||
if (wp->w_wantline == 0) // cursor in first line
|
||||
{
|
||||
wp->w_wantline = 2;
|
||||
wp->w_popup_pos = POPPOS_TOPLEFT;
|
||||
}
|
||||
wp->w_wantcol = screen_screencol() + 1;
|
||||
wp->w_wantcol = curwin->w_wincol + curwin->w_wcol + 1;
|
||||
set_moved_values(wp);
|
||||
set_moved_columns(wp, FIND_STRING);
|
||||
}
|
||||
|
||||
if (type == TYPE_BEVAL)
|
||||
{
|
||||
wp->w_popup_pos = POPPOS_BOTLEFT;
|
||||
|
||||
// by default use the mouse position
|
||||
wp->w_wantline = mouse_row;
|
||||
if (wp->w_wantline <= 0) // mouse on first line
|
||||
{
|
||||
wp->w_wantline = 2;
|
||||
wp->w_popup_pos = POPPOS_TOPLEFT;
|
||||
}
|
||||
wp->w_wantcol = mouse_col + 1;
|
||||
set_mousemoved_values(wp);
|
||||
set_mousemoved_columns(wp, FIND_IDENT + FIND_STRING + FIND_EVAL);
|
||||
}
|
||||
|
||||
// set default values
|
||||
wp->w_zindex = POPUPWIN_DEFAULT_ZINDEX;
|
||||
wp->w_popup_close = POPCLOSE_NONE;
|
||||
@@ -1275,6 +1351,15 @@ f_popup_atcursor(typval_T *argvars, typval_T *rettv)
|
||||
popup_create(argvars, rettv, TYPE_ATCURSOR);
|
||||
}
|
||||
|
||||
/*
|
||||
* popup_beval({text}, {options})
|
||||
*/
|
||||
void
|
||||
f_popup_beval(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
popup_create(argvars, rettv, TYPE_BEVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke the close callback for window "wp" with value "result".
|
||||
* Careful: The callback may make "wp" invalid!
|
||||
@@ -1334,6 +1419,48 @@ popup_close_for_mouse_click(win_T *wp)
|
||||
popup_close_and_callback(wp, &res);
|
||||
}
|
||||
|
||||
static void
|
||||
check_mouse_moved(win_T *wp, win_T *mouse_wp)
|
||||
{
|
||||
// Close the popup when all if these are true:
|
||||
// - the mouse is not on this popup
|
||||
// - "mousemoved" was used
|
||||
// - the mouse is no longer on the same screen row or the mouse column is
|
||||
// outside of the relevant text
|
||||
if (wp != mouse_wp
|
||||
&& wp->w_popup_mouse_row != 0
|
||||
&& (wp->w_popup_mouse_row != mouse_row
|
||||
|| mouse_col < wp->w_popup_mouse_mincol
|
||||
|| mouse_col > wp->w_popup_mouse_maxcol))
|
||||
{
|
||||
typval_T res;
|
||||
|
||||
res.v_type = VAR_NUMBER;
|
||||
res.vval.v_number = -2;
|
||||
popup_close_and_callback(wp, &res);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when the mouse moved: may close a popup with "mousemoved".
|
||||
*/
|
||||
void
|
||||
popup_handle_mouse_moved(void)
|
||||
{
|
||||
win_T *wp;
|
||||
win_T *mouse_wp;
|
||||
int row = mouse_row;
|
||||
int col = mouse_col;
|
||||
|
||||
// find the window where the mouse is in
|
||||
mouse_wp = mouse_find_win(&row, &col, FIND_POPUP);
|
||||
|
||||
for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
|
||||
check_mouse_moved(wp, mouse_wp);
|
||||
for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
|
||||
check_mouse_moved(wp, mouse_wp);
|
||||
}
|
||||
|
||||
/*
|
||||
* In a filter: check if the typed key is a mouse event that is used for
|
||||
* dragging the popup.
|
||||
@@ -1821,7 +1948,7 @@ get_borderchars(dict_T *dict, win_T *wp)
|
||||
}
|
||||
|
||||
/*
|
||||
* For popup_getoptions(): add a "moved" entry to "dict".
|
||||
* For popup_getoptions(): add a "moved" and "mousemoved" entry to "dict".
|
||||
*/
|
||||
static void
|
||||
get_moved_list(dict_T *dict, win_T *wp)
|
||||
@@ -1832,9 +1959,18 @@ get_moved_list(dict_T *dict, win_T *wp)
|
||||
if (list != NULL)
|
||||
{
|
||||
dict_add_list(dict, "moved", list);
|
||||
list_append_number(list, wp->w_popup_lnum);
|
||||
list_append_number(list, wp->w_popup_mincol);
|
||||
list_append_number(list, wp->w_popup_maxcol);
|
||||
}
|
||||
list = list_alloc();
|
||||
if (list != NULL)
|
||||
{
|
||||
dict_add_list(dict, "mousemoved", list);
|
||||
list_append_number(list, wp->w_popup_mouse_row);
|
||||
list_append_number(list, wp->w_popup_mouse_mincol);
|
||||
list_append_number(list, wp->w_popup_mouse_maxcol);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user