summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-06-12 20:22:27 +0200
committerBram Moolenaar <Bram@vim.org>2019-06-12 20:22:27 +0200
commit451d4b5b7c7262631cd1f5057c75d6f5f5772fb1 (patch)
treedeb24fe64258461378994e9255c68f6179f11e31
parent06e2c81f6d213d197aa60019b33a263cd5176d68 (diff)
downloadvim-git-451d4b5b7c7262631cd1f5057c75d6f5f5772fb1.tar.gz
patch 8.1.1520: popup windows are ignored when dealing with mouse positionv8.1.1520
Problem: Popup windows are ignored when dealing with mouse position Solution: Find the mouse position inside a popup window. Allow for modeless selection.
-rw-r--r--src/beval.c5
-rw-r--r--src/edit.c2
-rw-r--r--src/evalfunc.c12
-rw-r--r--src/gui.c4
-rw-r--r--src/normal.c2
-rw-r--r--src/popupwin.c22
-rw-r--r--src/proto/popupwin.pro2
-rw-r--r--src/proto/ui.pro2
-rw-r--r--src/screen.c15
-rw-r--r--src/structs.h7
-rw-r--r--src/ui.c72
-rw-r--r--src/version.c2
12 files changed, 120 insertions, 27 deletions
diff --git a/src/beval.c b/src/beval.c
index d51a3f5d8..e89b1fe50 100644
--- a/src/beval.c
+++ b/src/beval.c
@@ -49,7 +49,7 @@ get_beval_info(
col = X_2_COL(beval->x);
}
#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)
{
/* 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".
+ * Hide the balloon when both are NULL.
*/
void
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
# ifdef FEAT_BEVAL_GUI
if (gui.in_use)
- /* GUI can't handle a list */
+ // GUI can't handle a list
gui_mch_post_balloon(beval, mesg);
# endif
}
diff --git a/src/edit.c b/src/edit.c
index ad25252e7..4de17aa18 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -5267,7 +5267,7 @@ ins_mousescroll(int dir)
col = mouse_col;
/* find the window at the pointer coordinates */
- wp = mouse_find_win(&row, &col);
+ wp = mouse_find_win(&row, &col, FAIL_POPUP);
if (wp == NULL)
return;
curwin = wp;
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 48b848d01..134280f6d 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -5154,12 +5154,18 @@ f_getchar(typval_T *argvars, typval_T *rettv)
{
/* Find the window at the mouse coordinates and compute the
* text position. */
- win = mouse_find_win(&row, &col);
+ win = mouse_find_win(&row, &col, FIND_POPUP);
if (win == NULL)
return;
(void)mouse_comp_pos(win, &row, &col, &lnum);
- for (wp = firstwin; wp != win; wp = wp->w_next)
- ++winnr;
+# ifdef FEAT_TEXT_PROP
+ 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_WINID, win->w_id);
set_vim_var_nr(VV_MOUSE_LNUM, lnum);
diff --git a/src/gui.c b/src/gui.c
index c4df7d9a5..a4673f026 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -4926,7 +4926,7 @@ xy2win(int x, int y)
col = X_2_COL(x);
if (row < 0 || col < 0) /* before first window */
return NULL;
- wp = mouse_find_win(&row, &col);
+ wp = mouse_find_win(&row, &col, FALSE);
if (wp == NULL)
return NULL;
#ifdef FEAT_MOUSESHAPE
@@ -5382,7 +5382,7 @@ gui_wingoto_xy(int x, int y)
if (row >= 0 && col >= 0)
{
- wp = mouse_find_win(&row, &col);
+ wp = mouse_find_win(&row, &col, FAIL_POPUP);
if (wp != NULL && wp != curwin)
win_goto(wp);
}
diff --git a/src/normal.c b/src/normal.c
index 834a6436d..834b2319c 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4521,7 +4521,7 @@ nv_mousescroll(cmdarg_T *cap)
col = mouse_col;
/* find the window at the pointer coordinates */
- wp = mouse_find_win(&row, &col);
+ wp = mouse_find_win(&row, &col, FAIL_POPUP);
if (wp == NULL)
return;
curwin = wp;
diff --git a/src/popupwin.c b/src/popupwin.c
index 3781c6fe2..adfa46229 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -424,6 +424,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.
*/
void
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index 2a377a748..a27444679 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -1,4 +1,6 @@
/* popupwin.c */
+int popup_height(win_T *wp);
+int popup_width(win_T *wp);
void popup_adjust_position(win_T *wp);
void f_popup_clear(typval_T *argvars, typval_T *rettv);
void f_popup_create(typval_T *argvars, typval_T *rettv);
diff --git a/src/proto/ui.pro b/src/proto/ui.pro
index 26cfd4715..e920029af 100644
--- a/src/proto/ui.pro
+++ b/src/proto/ui.pro
@@ -65,7 +65,7 @@ int clip_x11_owner_exists(VimClipboard *cbd);
void yank_cut_buffer0(Display *dpy, VimClipboard *cbd);
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);
-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 vcol2col(win_T *wp, linenr_T lnum, int vcol);
void ui_focus_change(int in_focus);
diff --git a/src/screen.c b/src/screen.c
index 644829ead..7248ca221 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1072,8 +1072,6 @@ may_update_popup_mask(int type)
popup_reset_handled();
while ((wp = find_next_popup(TRUE)) != NULL)
{
- int height_extra, width_extra;
-
popup_visible = TRUE;
// 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))
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;
- line < wp->w_winrow + wp->w_height + height_extra
+ line < wp->w_winrow + popup_height(wp)
&& line < screen_Rows; ++line)
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)
mask[line * screen_Columns + col] = wp->w_zindex;
}
@@ -1123,7 +1114,7 @@ may_update_popup_mask(int type)
int col_cp = col;
// 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 (line_cp >= wp->w_height)
diff --git a/src/structs.h b/src/structs.h
index 8ec2cb185..8e6d93f30 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3626,3 +3626,10 @@ typedef enum {
CDSCOPE_TABPAGE, // :tcd
CDSCOPE_WINDOW // :lcd
} 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;
diff --git a/src/ui.c b/src/ui.c
index 4a684d236..62d8ae7d3 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -1455,12 +1455,19 @@ clip_invert_rectangle(
int width,
int invert)
{
+#ifdef FEAT_TEXT_PROP
+ // this goes on top of all popup windows
+ screen_zindex = 32000;
+#endif
#ifdef FEAT_GUI
if (gui.in_use)
gui_mch_invert_rectangle(row, col, height, width);
else
#endif
screen_draw_rectangle(row, col, height, width, invert);
+#ifdef FEAT_TEXT_PROP
+ screen_zindex = 0;
+#endif
}
/*
@@ -2833,6 +2840,9 @@ jump_to_mouse(
#ifdef FEAT_MENU
static int in_winbar = FALSE;
#endif
+#ifdef FEAT_TEXT_PROP
+ static int in_popup_win = FALSE;
+#endif
static int prev_row = -1;
static int prev_col = -1;
static win_T *dragwin = NULL; /* window being dragged */
@@ -2879,7 +2889,7 @@ retnomove:
* as a second click in the WinBar. */
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)
return IN_UNKNOWN;
winbar_click(wp, col);
@@ -2893,10 +2903,15 @@ retnomove:
redraw_curbuf_later(INVERTED); /* delete the inversion */
}
#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)
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
return IN_BUFFER;
}
@@ -2925,11 +2940,26 @@ retnomove:
return IN_UNKNOWN;
/* 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)
return IN_UNKNOWN;
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
if (row == -1)
{
@@ -3096,6 +3126,11 @@ retnomove:
if (cmdwin_type != 0 && row < curwin->w_winrow)
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
row -= W_WINROW(curwin);
col -= curwin->w_wincol;
@@ -3348,14 +3383,41 @@ mouse_comp_pos(
/*
* Find the window at screen position "*rowp" and "*colp". The positions are
* 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.
*/
win_T *
-mouse_find_win(int *rowp, int *colp)
+mouse_find_win(int *rowp, int *colp, mouse_find_T popup UNUSED)
{
frame_T *fp;
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;
*rowp -= firstwin->w_winrow;
for (;;)
@@ -3412,7 +3474,7 @@ get_fpos_of_mouse(pos_T *mpos)
return IN_UNKNOWN;
/* 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)
return IN_UNKNOWN;
/*
diff --git a/src/version.c b/src/version.c
index 5c41f4fbb..8f3d0864f 100644
--- 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 */
/**/
+ 1520,
+/**/
1519,
/**/
1518,