Patch 8.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.
Files:      src/ui.c, src/proto/ui.pro, src/popupwin.c,
            src/proto/popupwin.pro, src/screen.c, src/beval.c, src/edit.c,
            src/evalfunc.c, src/gui.c, src/normal.c, src/structs.h


*** ../vim-8.1.1519/src/ui.c    2019-06-10 21:23:52.363724122 +0200
--- src/ui.c    2019-06-12 20:12:02.012662311 +0200
***************
*** 1455,1466 ****
--- 1455,1473 ----
      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,2838 ****
--- 2840,2848 ----
  #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,2885 ****
             * as a second click in the WinBar. */
            if ((mod_mask & MOD_MASK_MULTI_CLICK) && !(flags & MOUSE_RELEASED))
            {
!               wp = mouse_find_win(&row, &col);
                if (wp == NULL)
                    return IN_UNKNOWN;
                winbar_click(wp, col);
--- 2889,2895 ----
             * as a second click in the WinBar. */
            if ((mod_mask & MOD_MASK_MULTI_CLICK) && !(flags & MOUSE_RELEASED))
            {
!               wp = mouse_find_win(&row, &col, FAIL_POPUP);
                if (wp == NULL)
                    return IN_UNKNOWN;
                winbar_click(wp, col);
***************
*** 2893,2902 ****
            redraw_curbuf_later(INVERTED);      /* delete the inversion */
        }
  #if defined(FEAT_CMDWIN) && defined(FEAT_CLIPBOARD)
!       /* Continue a modeless selection in another window. */
        if (cmdwin_type != 0 && row < curwin->w_winrow)
            return IN_OTHER_WIN;
  #endif
        return IN_BUFFER;
      }
  
--- 2903,2917 ----
            redraw_curbuf_later(INVERTED);      /* delete the inversion */
        }
  #if defined(FEAT_CMDWIN) && defined(FEAT_CLIPBOARD)
!       // 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,2935 ****
            return IN_UNKNOWN;
  
        /* find the window where the row is in */
!       wp = mouse_find_win(&row, &col);
        if (wp == NULL)
            return IN_UNKNOWN;
        dragwin = NULL;
  
  #ifdef FEAT_MENU
        if (row == -1)
        {
--- 2940,2965 ----
            return IN_UNKNOWN;
  
        /* find the window where the row is in */
!       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,3101 ****
--- 3126,3136 ----
        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,3361 ****
  /*
   * Find the window at screen position "*rowp" and "*colp".  The positions are
   * updated to become relative to the top-left of the window.
   * Returns NULL when something is wrong.
   */
      win_T *
! mouse_find_win(int *rowp, int *colp)
  {
      frame_T   *fp;
      win_T     *wp;
  
      fp = topframe;
      *rowp -= firstwin->w_winrow;
      for (;;)
--- 3383,3423 ----
  /*
   * 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_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,3418 ****
        return IN_UNKNOWN;
  
      /* find the window where the row is in */
!     wp = mouse_find_win(&row, &col);
      if (wp == NULL)
        return IN_UNKNOWN;
      /*
--- 3474,3480 ----
        return IN_UNKNOWN;
  
      /* find the window where the row is in */
!     wp = mouse_find_win(&row, &col, FAIL_POPUP);
      if (wp == NULL)
        return IN_UNKNOWN;
      /*
*** ../vim-8.1.1519/src/proto/ui.pro    2019-04-06 17:33:20.651486473 +0200
--- src/proto/ui.pro    2019-06-11 23:04:54.472786057 +0200
***************
*** 65,71 ****
  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);
  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);
--- 65,71 ----
  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, 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);
*** ../vim-8.1.1519/src/popupwin.c      2019-06-10 21:23:52.363724122 +0200
--- src/popupwin.c      2019-06-11 22:43:53.684350966 +0200
***************
*** 424,429 ****
--- 424,451 ----
  }
  
  /*
+  * 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
*** ../vim-8.1.1519/src/proto/popupwin.pro      2019-06-10 13:10:45.370588270 
+0200
--- src/proto/popupwin.pro      2019-06-11 22:43:58.480344057 +0200
***************
*** 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);
*** ../vim-8.1.1519/src/screen.c        2019-06-11 21:56:15.518267135 +0200
--- src/screen.c        2019-06-11 22:58:35.578063821 +0200
***************
*** 1072,1079 ****
      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.
--- 1072,1077 ----
***************
*** 1081,1098 ****
                || 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 < screen_Rows; ++line)
            for (col = wp->w_wincol;
!                col < wp->w_wincol + wp->w_width + width_extra
                                                && col < screen_Columns; ++col)
                mask[line * screen_Columns + col] = wp->w_zindex;
      }
--- 1079,1089 ----
                || wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
            popup_adjust_position(wp);
  
        for (line = wp->w_winrow;
!               line < wp->w_winrow + popup_height(wp)
                                                 && line < screen_Rows; ++line)
            for (col = wp->w_wincol;
!                col < wp->w_wincol + popup_width(wp)
                                                && col < screen_Columns; ++col)
                mask[line * screen_Columns + col] = wp->w_zindex;
      }
***************
*** 1123,1129 ****
                        int             col_cp = col;
  
                        // find the window where the row is in
!                       wp = mouse_find_win(&line_cp, &col_cp);
                        if (wp != NULL)
                        {
                            if (line_cp >= wp->w_height)
--- 1114,1120 ----
                        int             col_cp = col;
  
                        // find the window where the row is in
!                       wp = mouse_find_win(&line_cp, &col_cp, IGNORE_POPUP);
                        if (wp != NULL)
                        {
                            if (line_cp >= wp->w_height)
*** ../vim-8.1.1519/src/beval.c 2019-04-27 22:06:33.348200718 +0200
--- src/beval.c 2019-06-11 23:01:34.621469784 +0200
***************
*** 49,55 ****
        col = X_2_COL(beval->x);
      }
  #endif
!     wp = mouse_find_win(&row, &col);
      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
--- 49,55 ----
        col = X_2_COL(beval->x);
      }
  #endif
!     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,146 ****
--- 141,147 ----
  
  /*
   * 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,159 ****
  # endif
  # ifdef FEAT_BEVAL_GUI
      if (gui.in_use)
!       /* GUI can't handle a list */
        gui_mch_post_balloon(beval, mesg);
  # endif
  }
--- 154,160 ----
  # endif
  # ifdef FEAT_BEVAL_GUI
      if (gui.in_use)
!       // GUI can't handle a list
        gui_mch_post_balloon(beval, mesg);
  # endif
  }
*** ../vim-8.1.1519/src/edit.c  2019-06-02 18:40:02.637508840 +0200
--- src/edit.c  2019-06-11 23:01:39.569453098 +0200
***************
*** 5267,5273 ****
        col = mouse_col;
  
        /* find the window at the pointer coordinates */
!       wp = mouse_find_win(&row, &col);
        if (wp == NULL)
            return;
        curwin = wp;
--- 5267,5273 ----
        col = mouse_col;
  
        /* find the window at the pointer coordinates */
!       wp = mouse_find_win(&row, &col, FAIL_POPUP);
        if (wp == NULL)
            return;
        curwin = wp;
*** ../vim-8.1.1519/src/evalfunc.c      2019-06-10 13:10:45.370588270 +0200
--- src/evalfunc.c      2019-06-11 23:01:56.433396079 +0200
***************
*** 5154,5165 ****
            {
                /* Find the window at the mouse coordinates and compute the
                 * text position. */
!               win = mouse_find_win(&row, &col);
                if (win == NULL)
                    return;
                (void)mouse_comp_pos(win, &row, &col, &lnum);
!               for (wp = firstwin; wp != win; 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);
--- 5154,5171 ----
            {
                /* Find the window at the mouse coordinates and compute the
                 * text position. */
!               win = mouse_find_win(&row, &col, FIND_POPUP);
                if (win == NULL)
                    return;
                (void)mouse_comp_pos(win, &row, &col, &lnum);
! # 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);
*** ../vim-8.1.1519/src/gui.c   2019-06-02 18:40:02.637508840 +0200
--- src/gui.c   2019-06-11 23:02:03.649371628 +0200
***************
*** 4926,4932 ****
      col = X_2_COL(x);
      if (row < 0 || col < 0)           /* before first window */
        return NULL;
!     wp = mouse_find_win(&row, &col);
      if (wp == NULL)
        return NULL;
  #ifdef FEAT_MOUSESHAPE
--- 4926,4932 ----
      col = X_2_COL(x);
      if (row < 0 || col < 0)           /* before first window */
        return NULL;
!     wp = mouse_find_win(&row, &col, FALSE);
      if (wp == NULL)
        return NULL;
  #ifdef FEAT_MOUSESHAPE
***************
*** 5382,5388 ****
  
      if (row >= 0 && col >= 0)
      {
!       wp = mouse_find_win(&row, &col);
        if (wp != NULL && wp != curwin)
            win_goto(wp);
      }
--- 5382,5388 ----
  
      if (row >= 0 && col >= 0)
      {
!       wp = mouse_find_win(&row, &col, FAIL_POPUP);
        if (wp != NULL && wp != curwin)
            win_goto(wp);
      }
*** ../vim-8.1.1519/src/normal.c        2019-06-02 19:53:40.998714309 +0200
--- src/normal.c        2019-06-11 23:02:07.993356902 +0200
***************
*** 4521,4527 ****
        col = mouse_col;
  
        /* find the window at the pointer coordinates */
!       wp = mouse_find_win(&row, &col);
        if (wp == NULL)
            return;
        curwin = wp;
--- 4521,4527 ----
        col = mouse_col;
  
        /* find the window at the pointer coordinates */
!       wp = mouse_find_win(&row, &col, FAIL_POPUP);
        if (wp == NULL)
            return;
        curwin = wp;
*** ../vim-8.1.1519/src/structs.h       2019-06-09 19:51:54.472551622 +0200
--- src/structs.h       2019-06-11 22:58:00.202178532 +0200
***************
*** 3626,3628 ****
--- 3626,3635 ----
      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;
*** ../vim-8.1.1519/src/version.c       2019-06-12 19:05:44.925966622 +0200
--- src/version.c       2019-06-12 20:19:08.214619067 +0200
***************
*** 779,780 ****
--- 779,782 ----
  {   /* Add new patch number below this line */
+ /**/
+     1520,
  /**/

-- 
Two sheep in a meadow.  One says "baaah".  The other says "exactly!".

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201906121822.x5CIMgEE012555%40masaka.moolenaar.net.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui