forked from aniani/vim
patch 8.1.1520: popup windows are ignored when dealing with mouse position
Problem: Popup windows are ignored when dealing with mouse position
Solution: Find the mouse position inside a popup window. Allow for modeless
selection.
This commit is contained in:
@@ -49,7 +49,7 @@ get_beval_info(
|
|||||||
col = X_2_COL(beval->x);
|
col = X_2_COL(beval->x);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
wp = mouse_find_win(&row, &col);
|
wp = mouse_find_win(&row, &col, FAIL_POPUP);
|
||||||
if (wp != NULL && row >= 0 && row < wp->w_height && col < wp->w_width)
|
if (wp != NULL && row >= 0 && row < wp->w_height && col < wp->w_width)
|
||||||
{
|
{
|
||||||
/* Found a window and the cursor is in the text. Now find the line
|
/* Found a window and the cursor is in the text. Now find the line
|
||||||
@@ -141,6 +141,7 @@ get_beval_info(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Show a balloon with "mesg" or "list".
|
* Show a balloon with "mesg" or "list".
|
||||||
|
* Hide the balloon when both are NULL.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
post_balloon(BalloonEval *beval UNUSED, char_u *mesg, list_T *list UNUSED)
|
post_balloon(BalloonEval *beval UNUSED, char_u *mesg, list_T *list UNUSED)
|
||||||
@@ -153,7 +154,7 @@ post_balloon(BalloonEval *beval UNUSED, char_u *mesg, list_T *list UNUSED)
|
|||||||
# endif
|
# endif
|
||||||
# ifdef FEAT_BEVAL_GUI
|
# ifdef FEAT_BEVAL_GUI
|
||||||
if (gui.in_use)
|
if (gui.in_use)
|
||||||
/* GUI can't handle a list */
|
// GUI can't handle a list
|
||||||
gui_mch_post_balloon(beval, mesg);
|
gui_mch_post_balloon(beval, mesg);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5267,7 +5267,7 @@ ins_mousescroll(int dir)
|
|||||||
col = mouse_col;
|
col = mouse_col;
|
||||||
|
|
||||||
/* find the window at the pointer coordinates */
|
/* find the window at the pointer coordinates */
|
||||||
wp = mouse_find_win(&row, &col);
|
wp = mouse_find_win(&row, &col, FAIL_POPUP);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return;
|
return;
|
||||||
curwin = wp;
|
curwin = wp;
|
||||||
|
|||||||
@@ -5154,12 +5154,18 @@ f_getchar(typval_T *argvars, typval_T *rettv)
|
|||||||
{
|
{
|
||||||
/* Find the window at the mouse coordinates and compute the
|
/* Find the window at the mouse coordinates and compute the
|
||||||
* text position. */
|
* text position. */
|
||||||
win = mouse_find_win(&row, &col);
|
win = mouse_find_win(&row, &col, FIND_POPUP);
|
||||||
if (win == NULL)
|
if (win == NULL)
|
||||||
return;
|
return;
|
||||||
(void)mouse_comp_pos(win, &row, &col, &lnum);
|
(void)mouse_comp_pos(win, &row, &col, &lnum);
|
||||||
for (wp = firstwin; wp != win; wp = wp->w_next)
|
# ifdef FEAT_TEXT_PROP
|
||||||
++winnr;
|
if (bt_popup(win->w_buffer))
|
||||||
|
winnr = 0;
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
for (wp = firstwin; wp != win && wp != NULL;
|
||||||
|
wp = wp->w_next)
|
||||||
|
++winnr;
|
||||||
set_vim_var_nr(VV_MOUSE_WIN, winnr);
|
set_vim_var_nr(VV_MOUSE_WIN, winnr);
|
||||||
set_vim_var_nr(VV_MOUSE_WINID, win->w_id);
|
set_vim_var_nr(VV_MOUSE_WINID, win->w_id);
|
||||||
set_vim_var_nr(VV_MOUSE_LNUM, lnum);
|
set_vim_var_nr(VV_MOUSE_LNUM, lnum);
|
||||||
|
|||||||
@@ -4926,7 +4926,7 @@ xy2win(int x, int y)
|
|||||||
col = X_2_COL(x);
|
col = X_2_COL(x);
|
||||||
if (row < 0 || col < 0) /* before first window */
|
if (row < 0 || col < 0) /* before first window */
|
||||||
return NULL;
|
return NULL;
|
||||||
wp = mouse_find_win(&row, &col);
|
wp = mouse_find_win(&row, &col, FALSE);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef FEAT_MOUSESHAPE
|
#ifdef FEAT_MOUSESHAPE
|
||||||
@@ -5382,7 +5382,7 @@ gui_wingoto_xy(int x, int y)
|
|||||||
|
|
||||||
if (row >= 0 && col >= 0)
|
if (row >= 0 && col >= 0)
|
||||||
{
|
{
|
||||||
wp = mouse_find_win(&row, &col);
|
wp = mouse_find_win(&row, &col, FAIL_POPUP);
|
||||||
if (wp != NULL && wp != curwin)
|
if (wp != NULL && wp != curwin)
|
||||||
win_goto(wp);
|
win_goto(wp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4521,7 +4521,7 @@ nv_mousescroll(cmdarg_T *cap)
|
|||||||
col = mouse_col;
|
col = mouse_col;
|
||||||
|
|
||||||
/* find the window at the pointer coordinates */
|
/* find the window at the pointer coordinates */
|
||||||
wp = mouse_find_win(&row, &col);
|
wp = mouse_find_win(&row, &col, FAIL_POPUP);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return;
|
return;
|
||||||
curwin = wp;
|
curwin = wp;
|
||||||
|
|||||||
@@ -423,6 +423,28 @@ add_popup_dicts(buf_T *buf, list_T *l)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the height of popup window "wp", including border and padding.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
popup_height(win_T *wp)
|
||||||
|
{
|
||||||
|
return wp->w_height
|
||||||
|
+ wp->w_popup_padding[0] + wp->w_popup_border[0]
|
||||||
|
+ wp->w_popup_padding[2] + wp->w_popup_border[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the width of popup window "wp", including border and padding.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
popup_width(win_T *wp)
|
||||||
|
{
|
||||||
|
return wp->w_width
|
||||||
|
+ wp->w_popup_padding[3] + wp->w_popup_border[3]
|
||||||
|
+ wp->w_popup_padding[1] + wp->w_popup_border[1];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adjust the position and size of the popup to fit on the screen.
|
* Adjust the position and size of the popup to fit on the screen.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/* popupwin.c */
|
/* popupwin.c */
|
||||||
|
int popup_height(win_T *wp);
|
||||||
|
int popup_width(win_T *wp);
|
||||||
void popup_adjust_position(win_T *wp);
|
void popup_adjust_position(win_T *wp);
|
||||||
void f_popup_clear(typval_T *argvars, typval_T *rettv);
|
void f_popup_clear(typval_T *argvars, typval_T *rettv);
|
||||||
void f_popup_create(typval_T *argvars, typval_T *rettv);
|
void f_popup_create(typval_T *argvars, typval_T *rettv);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ int clip_x11_owner_exists(VimClipboard *cbd);
|
|||||||
void yank_cut_buffer0(Display *dpy, VimClipboard *cbd);
|
void yank_cut_buffer0(Display *dpy, VimClipboard *cbd);
|
||||||
int jump_to_mouse(int flags, int *inclusive, int which_button);
|
int jump_to_mouse(int flags, int *inclusive, int which_button);
|
||||||
int mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump);
|
int mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump);
|
||||||
win_T *mouse_find_win(int *rowp, int *colp);
|
win_T *mouse_find_win(int *rowp, int *colp, mouse_find_T popup);
|
||||||
int get_fpos_of_mouse(pos_T *mpos);
|
int get_fpos_of_mouse(pos_T *mpos);
|
||||||
int vcol2col(win_T *wp, linenr_T lnum, int vcol);
|
int vcol2col(win_T *wp, linenr_T lnum, int vcol);
|
||||||
void ui_focus_change(int in_focus);
|
void ui_focus_change(int in_focus);
|
||||||
|
|||||||
15
src/screen.c
15
src/screen.c
@@ -1072,8 +1072,6 @@ may_update_popup_mask(int type)
|
|||||||
popup_reset_handled();
|
popup_reset_handled();
|
||||||
while ((wp = find_next_popup(TRUE)) != NULL)
|
while ((wp = find_next_popup(TRUE)) != NULL)
|
||||||
{
|
{
|
||||||
int height_extra, width_extra;
|
|
||||||
|
|
||||||
popup_visible = TRUE;
|
popup_visible = TRUE;
|
||||||
|
|
||||||
// Recompute the position if the text changed.
|
// Recompute the position if the text changed.
|
||||||
@@ -1081,18 +1079,11 @@ may_update_popup_mask(int type)
|
|||||||
|| wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
|
|| wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
|
||||||
popup_adjust_position(wp);
|
popup_adjust_position(wp);
|
||||||
|
|
||||||
// the width and height are for the inside, add the padding and
|
|
||||||
// border
|
|
||||||
height_extra = wp->w_popup_padding[0] + wp->w_popup_border[0]
|
|
||||||
+ wp->w_popup_padding[2] + wp->w_popup_border[2];
|
|
||||||
width_extra = wp->w_popup_padding[3] + wp->w_popup_border[3]
|
|
||||||
+ wp->w_popup_padding[1] + wp->w_popup_border[1];
|
|
||||||
|
|
||||||
for (line = wp->w_winrow;
|
for (line = wp->w_winrow;
|
||||||
line < wp->w_winrow + wp->w_height + height_extra
|
line < wp->w_winrow + popup_height(wp)
|
||||||
&& line < screen_Rows; ++line)
|
&& line < screen_Rows; ++line)
|
||||||
for (col = wp->w_wincol;
|
for (col = wp->w_wincol;
|
||||||
col < wp->w_wincol + wp->w_width + width_extra
|
col < wp->w_wincol + popup_width(wp)
|
||||||
&& col < screen_Columns; ++col)
|
&& col < screen_Columns; ++col)
|
||||||
mask[line * screen_Columns + col] = wp->w_zindex;
|
mask[line * screen_Columns + col] = wp->w_zindex;
|
||||||
}
|
}
|
||||||
@@ -1123,7 +1114,7 @@ may_update_popup_mask(int type)
|
|||||||
int col_cp = col;
|
int col_cp = col;
|
||||||
|
|
||||||
// find the window where the row is in
|
// find the window where the row is in
|
||||||
wp = mouse_find_win(&line_cp, &col_cp);
|
wp = mouse_find_win(&line_cp, &col_cp, IGNORE_POPUP);
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
{
|
{
|
||||||
if (line_cp >= wp->w_height)
|
if (line_cp >= wp->w_height)
|
||||||
|
|||||||
@@ -3626,3 +3626,10 @@ typedef enum {
|
|||||||
CDSCOPE_TABPAGE, // :tcd
|
CDSCOPE_TABPAGE, // :tcd
|
||||||
CDSCOPE_WINDOW // :lcd
|
CDSCOPE_WINDOW // :lcd
|
||||||
} cdscope_T;
|
} cdscope_T;
|
||||||
|
|
||||||
|
// argument for mouse_find_win()
|
||||||
|
typedef enum {
|
||||||
|
IGNORE_POPUP, // only check non-popup windows
|
||||||
|
FIND_POPUP, // also find popup windows
|
||||||
|
FAIL_POPUP // return NULL if mouse on popup window
|
||||||
|
} mouse_find_T;
|
||||||
|
|||||||
72
src/ui.c
72
src/ui.c
@@ -1455,12 +1455,19 @@ clip_invert_rectangle(
|
|||||||
int width,
|
int width,
|
||||||
int invert)
|
int invert)
|
||||||
{
|
{
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// this goes on top of all popup windows
|
||||||
|
screen_zindex = 32000;
|
||||||
|
#endif
|
||||||
#ifdef FEAT_GUI
|
#ifdef FEAT_GUI
|
||||||
if (gui.in_use)
|
if (gui.in_use)
|
||||||
gui_mch_invert_rectangle(row, col, height, width);
|
gui_mch_invert_rectangle(row, col, height, width);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
screen_draw_rectangle(row, col, height, width, invert);
|
screen_draw_rectangle(row, col, height, width, invert);
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
screen_zindex = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2832,6 +2839,9 @@ jump_to_mouse(
|
|||||||
static int on_sep_line = 0; /* on separator right of window */
|
static int on_sep_line = 0; /* on separator right of window */
|
||||||
#ifdef FEAT_MENU
|
#ifdef FEAT_MENU
|
||||||
static int in_winbar = FALSE;
|
static int in_winbar = FALSE;
|
||||||
|
#endif
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
static int in_popup_win = FALSE;
|
||||||
#endif
|
#endif
|
||||||
static int prev_row = -1;
|
static int prev_row = -1;
|
||||||
static int prev_col = -1;
|
static int prev_col = -1;
|
||||||
@@ -2879,7 +2889,7 @@ retnomove:
|
|||||||
* as a second click in the WinBar. */
|
* as a second click in the WinBar. */
|
||||||
if ((mod_mask & MOD_MASK_MULTI_CLICK) && !(flags & MOUSE_RELEASED))
|
if ((mod_mask & MOD_MASK_MULTI_CLICK) && !(flags & MOUSE_RELEASED))
|
||||||
{
|
{
|
||||||
wp = mouse_find_win(&row, &col);
|
wp = mouse_find_win(&row, &col, FAIL_POPUP);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return IN_UNKNOWN;
|
return IN_UNKNOWN;
|
||||||
winbar_click(wp, col);
|
winbar_click(wp, col);
|
||||||
@@ -2893,9 +2903,14 @@ retnomove:
|
|||||||
redraw_curbuf_later(INVERTED); /* delete the inversion */
|
redraw_curbuf_later(INVERTED); /* delete the inversion */
|
||||||
}
|
}
|
||||||
#if defined(FEAT_CMDWIN) && defined(FEAT_CLIPBOARD)
|
#if defined(FEAT_CMDWIN) && defined(FEAT_CLIPBOARD)
|
||||||
/* Continue a modeless selection in another window. */
|
// Continue a modeless selection in another window.
|
||||||
if (cmdwin_type != 0 && row < curwin->w_winrow)
|
if (cmdwin_type != 0 && row < curwin->w_winrow)
|
||||||
return IN_OTHER_WIN;
|
return IN_OTHER_WIN;
|
||||||
|
#endif
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// Continue a modeless selection in a popup window.
|
||||||
|
if (in_popup_win)
|
||||||
|
return IN_OTHER_WIN;
|
||||||
#endif
|
#endif
|
||||||
return IN_BUFFER;
|
return IN_BUFFER;
|
||||||
}
|
}
|
||||||
@@ -2925,11 +2940,26 @@ retnomove:
|
|||||||
return IN_UNKNOWN;
|
return IN_UNKNOWN;
|
||||||
|
|
||||||
/* find the window where the row is in */
|
/* find the window where the row is in */
|
||||||
wp = mouse_find_win(&row, &col);
|
wp = mouse_find_win(&row, &col, FIND_POPUP);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return IN_UNKNOWN;
|
return IN_UNKNOWN;
|
||||||
dragwin = NULL;
|
dragwin = NULL;
|
||||||
|
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// Click in a popup window may start modeless selection, but not much
|
||||||
|
// else.
|
||||||
|
if (bt_popup(wp->w_buffer))
|
||||||
|
{
|
||||||
|
on_sep_line = 0;
|
||||||
|
in_popup_win = TRUE;
|
||||||
|
# ifdef FEAT_CLIPBOARD
|
||||||
|
return IN_OTHER_WIN;
|
||||||
|
# else
|
||||||
|
return IN_UNKNOWN;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
in_popup_win = FALSE;
|
||||||
|
#endif
|
||||||
#ifdef FEAT_MENU
|
#ifdef FEAT_MENU
|
||||||
if (row == -1)
|
if (row == -1)
|
||||||
{
|
{
|
||||||
@@ -3096,6 +3126,11 @@ retnomove:
|
|||||||
if (cmdwin_type != 0 && row < curwin->w_winrow)
|
if (cmdwin_type != 0 && row < curwin->w_winrow)
|
||||||
return IN_OTHER_WIN;
|
return IN_OTHER_WIN;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
// Continue a modeless selection in a popup window.
|
||||||
|
if (in_popup_win)
|
||||||
|
return IN_OTHER_WIN;
|
||||||
|
#endif
|
||||||
|
|
||||||
row -= W_WINROW(curwin);
|
row -= W_WINROW(curwin);
|
||||||
col -= curwin->w_wincol;
|
col -= curwin->w_wincol;
|
||||||
@@ -3348,14 +3383,41 @@ mouse_comp_pos(
|
|||||||
/*
|
/*
|
||||||
* Find the window at screen position "*rowp" and "*colp". The positions are
|
* Find the window at screen position "*rowp" and "*colp". The positions are
|
||||||
* updated to become relative to the top-left of the window.
|
* updated to become relative to the top-left of the window.
|
||||||
|
* When "popup" is FAIL_POPUP and the position is in a popup window then NULL
|
||||||
|
* is returned. When "popup" is IGNORE_POPUP then do not even check popup
|
||||||
|
* windows.
|
||||||
* Returns NULL when something is wrong.
|
* Returns NULL when something is wrong.
|
||||||
*/
|
*/
|
||||||
win_T *
|
win_T *
|
||||||
mouse_find_win(int *rowp, int *colp)
|
mouse_find_win(int *rowp, int *colp, mouse_find_T popup UNUSED)
|
||||||
{
|
{
|
||||||
frame_T *fp;
|
frame_T *fp;
|
||||||
win_T *wp;
|
win_T *wp;
|
||||||
|
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
win_T *pwp = NULL;
|
||||||
|
|
||||||
|
if (popup != IGNORE_POPUP)
|
||||||
|
{
|
||||||
|
popup_reset_handled();
|
||||||
|
while ((wp = find_next_popup(TRUE)) != NULL)
|
||||||
|
{
|
||||||
|
if (*rowp >= wp->w_winrow && *rowp < wp->w_winrow + popup_height(wp)
|
||||||
|
&& *colp >= wp->w_wincol
|
||||||
|
&& *colp < wp->w_wincol + popup_width(wp))
|
||||||
|
pwp = wp;
|
||||||
|
}
|
||||||
|
if (pwp != NULL)
|
||||||
|
{
|
||||||
|
if (popup == FAIL_POPUP)
|
||||||
|
return NULL;
|
||||||
|
*rowp -= pwp->w_winrow;
|
||||||
|
*colp -= pwp->w_wincol;
|
||||||
|
return pwp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
fp = topframe;
|
fp = topframe;
|
||||||
*rowp -= firstwin->w_winrow;
|
*rowp -= firstwin->w_winrow;
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -3412,7 +3474,7 @@ get_fpos_of_mouse(pos_T *mpos)
|
|||||||
return IN_UNKNOWN;
|
return IN_UNKNOWN;
|
||||||
|
|
||||||
/* find the window where the row is in */
|
/* find the window where the row is in */
|
||||||
wp = mouse_find_win(&row, &col);
|
wp = mouse_find_win(&row, &col, FAIL_POPUP);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return IN_UNKNOWN;
|
return IN_UNKNOWN;
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -777,6 +777,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1520,
|
||||||
/**/
|
/**/
|
||||||
1519,
|
1519,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user