0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.1.1525: cannot move a popup window with the mouse

Problem:    Cannot move a popup window with the mouse.
Solution:   Add the "drag" property and make it possible to drag a popup
            window by its border.
This commit is contained in:
Bram Moolenaar
2019-06-13 23:59:52 +02:00
parent b0f94c1ff3
commit b53fb31a1e
8 changed files with 117 additions and 13 deletions

View File

@@ -95,7 +95,7 @@ IMPLEMENTATION:
- For the "moved" property also include mouse movement?
- When selecting text in the popup with modeless selection, do not select
outside of the popup and don't select the border or padding.
- Allow the user to drag the popup window when the "dragging" property is set.
- Add test for dragging the popup window.
- Make redrawing more efficient and avoid flicker:
- put popup menu also put in popup_mask?
- Invoke filter with character before mapping?
@@ -277,7 +277,7 @@ popup_menu({text}, {options}) *popup_menu()*
popup_move({id}, {options}) *popup_move()*
Move popup {id} to the position speficied with {options}.
Move popup {id} to the position specified with {options}.
{options} may contain the items from |popup_create()| that
specify the popup position: "line", "col", "pos", "maxheight",
"minheight", "maxwidth" and "minwidth".
@@ -293,6 +293,7 @@ popup_notification({text}, {options}) *popup_notification()*
\ 'time': 3000,
\ 'tab': -1,
\ 'zindex': 200,
\ 'drag': 1,
\ 'highlight': 'WarningMsg',
\ 'border': [],
\ 'padding': [0,1,0,1],
@@ -409,9 +410,13 @@ The second argument of |popup_create()| is a dictionary with options:
{only -1 and 0 are implemented}
title Text to be displayed above the first item in the
popup, on top of any border. If there is no top
border on line of padding is added to put the title on.
border one line of padding is added to put the title
on.
{not implemented yet}
wrap TRUE to make the lines wrap (default TRUE).
drag TRUE to allow the popup to be dragged with the mouse
by grabbing at at the border. Has no effect if the
popup does not have a border.
highlight Highlight group name to use for the text, stored in
the 'wincolor' option.
padding List with numbers, defining the padding
@@ -442,7 +447,7 @@ The second argument of |popup_create()| is a dictionary with options:
By default a double line is used all around when
'encoding' is "utf-8", otherwise ASCII characters are
used.
zindex Priority for the popup, default 50. Mininum value is
zindex Priority for the popup, default 50. Minimum value is
1, maximum value is 32000.
time Time in milliseconds after which the popup will close.
When omitted |popup_close()| must be used.

View File

@@ -164,6 +164,68 @@ set_moved_columns(win_T *wp, int flags)
}
}
/*
* Return TRUE if "row"/"col" is on the border of the popup.
* The values are relative to the top-left corner.
*/
int
popup_on_border(win_T *wp, int row, int col)
{
return (row == 0 && wp->w_popup_border[0] > 0)
|| (row == popup_height(wp) - 1 && wp->w_popup_border[2] > 0)
|| (col == 0 && wp->w_popup_border[3] > 0)
|| (col == popup_width(wp) - 1 && wp->w_popup_border[1] > 0);
}
// Values set when dragging a popup window starts.
static int drag_start_row;
static int drag_start_col;
static int drag_start_wantline;
static int drag_start_wantcol;
/*
* Mouse down on border of popup window: start dragging it.
* Uses mouse_col and mouse_row.
*/
void
popup_start_drag(win_T *wp)
{
drag_start_row = mouse_row;
drag_start_col = mouse_col;
// TODO: handle using different corner
if (wp->w_wantline == 0)
drag_start_wantline = wp->w_winrow + 1;
else
drag_start_wantline = wp->w_wantline;
if (wp->w_wantcol == 0)
drag_start_wantcol = wp->w_wincol + 1;
else
drag_start_wantcol = wp->w_wantcol;
}
/*
* Mouse moved while dragging a popup window: adjust the window popup position.
*/
void
popup_drag(win_T *wp)
{
// The popup may be closed before dragging stops.
if (!win_valid_popup(wp))
return;
wp->w_wantline = drag_start_wantline + (mouse_row - drag_start_row);
if (wp->w_wantline < 1)
wp->w_wantline = 1;
if (wp->w_wantline > Rows)
wp->w_wantline = Rows;
wp->w_wantcol = drag_start_wantcol + (mouse_col - drag_start_col);
if (wp->w_wantcol < 1)
wp->w_wantcol = 1;
if (wp->w_wantcol > Columns)
wp->w_wantcol = Columns;
popup_adjust_position(wp);
}
#if defined(FEAT_TIMERS)
static void
@@ -237,6 +299,8 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
wp->w_p_wrap = nr != 0;
}
wp->w_popup_drag = dict_get_number(dict, (char_u *)"drag");
di = dict_find(dict, (char_u *)"callback", -1);
if (di != NULL)
{
@@ -798,6 +862,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
wp->w_popup_padding[3] = 1;
set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
(char_u *)"WarningMsg", OPT_FREE|OPT_LOCAL, 0);
wp->w_popup_drag = 1;
}
// Deal with options.

View File

@@ -1,4 +1,7 @@
/* popupwin.c */
int popup_on_border(win_T *wp, int row, int col);
void popup_start_drag(win_T *wp);
void popup_drag(win_T *wp);
int popup_height(win_T *wp);
int popup_width(win_T *wp);
void popup_adjust_position(win_T *wp);

View File

@@ -3,6 +3,7 @@ void do_window(int nchar, long Prenum, int xchar);
void get_wincmd_addr_type(char_u *arg, exarg_T *eap);
int win_split(int size, int flags);
int win_split_ins(int size, int flags, win_T *new_wp, int dir);
int win_valid_popup(win_T *win);
int win_valid(win_T *win);
int win_valid_any_tab(win_T *win);
int win_count(void);

View File

@@ -2909,6 +2909,7 @@ struct window_S
linenr_T w_popup_lnum; // close popup if cursor not on this line
colnr_T w_popup_mincol; // close popup if cursor before this col
colnr_T w_popup_maxcol; // close popup if cursor after this col
int w_popup_drag; // allow moving the popup with the mouse
# if defined(FEAT_TIMERS)
timer_T *w_popup_timer; // timer for closing popup window

View File

@@ -1002,7 +1002,7 @@ static void clip_update_modeless_selection(VimClipboard *, int, int,
/*
* Start, continue or end a modeless selection. Used when editing the
* command-line and in the cmdline window.
* command-line, in the cmdline window and when the mouse is in a popup window.
*/
void
clip_modeless(int button, int is_click, int is_drag)
@@ -2841,7 +2841,8 @@ jump_to_mouse(
static int in_winbar = FALSE;
#endif
#ifdef FEAT_TEXT_PROP
static int in_popup_win = FALSE;
static int in_popup_win = FALSE;
static win_T *popup_dragwin = NULL;
#endif
static int prev_row = -1;
static int prev_col = -1;
@@ -2869,6 +2870,9 @@ jump_to_mouse(
flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE);
dragwin = NULL;
did_drag = FALSE;
#ifdef FEAT_TEXT_PROP
popup_dragwin = NULL;
#endif
}
if ((flags & MOUSE_DID_MOVE)
@@ -2910,7 +2914,15 @@ retnomove:
#ifdef FEAT_TEXT_PROP
// Continue a modeless selection in a popup window.
if (in_popup_win)
{
if (popup_dragwin != NULL)
{
// dragging a popup window
popup_drag(popup_dragwin);
return IN_UNKNOWN;
}
return IN_OTHER_WIN;
}
#endif
return IN_BUFFER;
}
@@ -2936,29 +2948,36 @@ retnomove:
if (!(flags & MOUSE_FOCUS))
{
if (row < 0 || col < 0) /* check if it makes sense */
if (row < 0 || col < 0) // check if it makes sense
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, 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.
// Click in a popup window may start dragging or modeless selection,
// but not much else.
if (bt_popup(wp->w_buffer))
{
on_sep_line = 0;
in_popup_win = TRUE;
if (wp->w_popup_drag && popup_on_border(wp, row, col))
{
popup_dragwin = wp;
popup_start_drag(wp);
return IN_UNKNOWN;
}
# ifdef FEAT_CLIPBOARD
return IN_OTHER_WIN;
# else
return IN_UNKNOWN;
# endif
}
in_popup_win = FALSE;
in_popup_win = FALSE;
popup_dragwin = NULL;
#endif
#ifdef FEAT_MENU
if (row == -1)
@@ -3127,9 +3146,17 @@ retnomove:
return IN_OTHER_WIN;
#endif
#ifdef FEAT_TEXT_PROP
// Continue a modeless selection in a popup window.
if (in_popup_win)
{
if (popup_dragwin != NULL)
{
// dragging a popup window
popup_drag(popup_dragwin);
return IN_UNKNOWN;
}
// continue a modeless selection in a popup window
return IN_OTHER_WIN;
}
#endif
row -= W_WINROW(curwin);

View File

@@ -777,6 +777,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1525,
/**/
1524,
/**/

View File

@@ -1371,7 +1371,7 @@ win_init_some(win_T *newp, win_T *oldp)
/*
* Return TRUE if "win" is a global popup or a popup in the current tab page.
*/
static int
int
win_valid_popup(win_T *win UNUSED)
{
#ifdef FEAT_TEXT_PROP