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 -- [email protected] -- 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 [email protected].
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.