]> granicus.if.org Git - vim/commitdiff
patch 8.1.1520: popup windows are ignored when dealing with mouse position v8.1.1520
authorBram Moolenaar <Bram@vim.org>
Wed, 12 Jun 2019 18:22:27 +0000 (20:22 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 12 Jun 2019 18:22:27 +0000 (20:22 +0200)
Problem:    Popup windows are ignored when dealing with mouse position
Solution:   Find the mouse position inside a popup window.  Allow for modeless
            selection.

12 files changed:
src/beval.c
src/edit.c
src/evalfunc.c
src/gui.c
src/normal.c
src/popupwin.c
src/proto/popupwin.pro
src/proto/ui.pro
src/screen.c
src/structs.h
src/ui.c
src/version.c

index d51a3f5d8469703fa6fdb262d076a5f8741cfaf9..e89b1fe50b57cc08f246968df1e5aeb6b26273ad 100644 (file)
@@ -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
 }
index ad25252e7ec6df52f785326793ef4630d3ef79c1..4de17aa180139f5816efb459da75b2b18557f3a1 100644 (file)
@@ -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;
index 48b848d01283592063a1f7b6c0c06e8bf9f22905..134280f6de9ebf4a7398361d23ae92bfe895ed26 100644 (file)
@@ -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);
index c4df7d9a57b0729979555b49ea8200aab7d9e410..a4673f02664712425960247464af61ed6f0d7b17 100644 (file)
--- 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);
     }
index 834a6436da7b67172b26b4fdee2a7a83a72a37e7..834b2319cbe7d97c0b5a9848164a7d2ac944773e 100644 (file)
@@ -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;
index 3781c6fe2d58e1219f3678315c397b10ba0d7a05..adfa462299a5ae0177a9711c2f49e9c77303e297 100644 (file)
@@ -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.
  */
index 2a377a748f5fa40ba8ab66019b6224d90fe65ea3..a27444679ee28135d5d0d4778df26a504fc83dd7 100644 (file)
@@ -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);
index 26cfd4715ac6adb29f13db61815d46ef96b6f51f..e920029afa7609113b9638be9558487223d837e3 100644 (file)
@@ -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);
index 644829ead29f7360c481b3c151689bf4e3f5e3c1..7248ca221c4ffb8857bfc9a151a0d4c854b74b47 100644 (file)
@@ -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)
index 8ec2cb1857790645121e868f003be2d6b1873023..8e6d93f30e22738a3f6f9a44a60456c7fca295af 100644 (file)
@@ -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;
index 4a684d2361fb059f7ca00706209504804d156cb7..62d8ae7d3ef456bb5457dba1b1ed4d08a5acdf76 100644 (file)
--- 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
 }
 
 /*
@@ -2832,6 +2839,9 @@ jump_to_mouse(
     static int on_sep_line = 0;        /* on separator right of window */
 #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;
@@ -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,9 +2903,14 @@ 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;
     /*
index 5c41f4fbb027dabb0734ecc4aee95487f576b21c..8f3d0864fddf073af737b7ad4eb63eb6d251cd8e 100644 (file)
@@ -777,6 +777,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1520,
 /**/
     1519,
 /**/