forked from aniani/vim
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:
@@ -95,7 +95,7 @@ IMPLEMENTATION:
|
|||||||
- For the "moved" property also include mouse movement?
|
- For the "moved" property also include mouse movement?
|
||||||
- When selecting text in the popup with modeless selection, do not select
|
- When selecting text in the popup with modeless selection, do not select
|
||||||
outside of the popup and don't select the border or padding.
|
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:
|
- Make redrawing more efficient and avoid flicker:
|
||||||
- put popup menu also put in popup_mask?
|
- put popup menu also put in popup_mask?
|
||||||
- Invoke filter with character before mapping?
|
- Invoke filter with character before mapping?
|
||||||
@@ -277,7 +277,7 @@ popup_menu({text}, {options}) *popup_menu()*
|
|||||||
|
|
||||||
|
|
||||||
popup_move({id}, {options}) *popup_move()*
|
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
|
{options} may contain the items from |popup_create()| that
|
||||||
specify the popup position: "line", "col", "pos", "maxheight",
|
specify the popup position: "line", "col", "pos", "maxheight",
|
||||||
"minheight", "maxwidth" and "minwidth".
|
"minheight", "maxwidth" and "minwidth".
|
||||||
@@ -293,6 +293,7 @@ popup_notification({text}, {options}) *popup_notification()*
|
|||||||
\ 'time': 3000,
|
\ 'time': 3000,
|
||||||
\ 'tab': -1,
|
\ 'tab': -1,
|
||||||
\ 'zindex': 200,
|
\ 'zindex': 200,
|
||||||
|
\ 'drag': 1,
|
||||||
\ 'highlight': 'WarningMsg',
|
\ 'highlight': 'WarningMsg',
|
||||||
\ 'border': [],
|
\ 'border': [],
|
||||||
\ 'padding': [0,1,0,1],
|
\ '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}
|
{only -1 and 0 are implemented}
|
||||||
title Text to be displayed above the first item in the
|
title Text to be displayed above the first item in the
|
||||||
popup, on top of any border. If there is no top
|
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}
|
{not implemented yet}
|
||||||
wrap TRUE to make the lines wrap (default TRUE).
|
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
|
highlight Highlight group name to use for the text, stored in
|
||||||
the 'wincolor' option.
|
the 'wincolor' option.
|
||||||
padding List with numbers, defining the padding
|
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
|
By default a double line is used all around when
|
||||||
'encoding' is "utf-8", otherwise ASCII characters are
|
'encoding' is "utf-8", otherwise ASCII characters are
|
||||||
used.
|
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.
|
1, maximum value is 32000.
|
||||||
time Time in milliseconds after which the popup will close.
|
time Time in milliseconds after which the popup will close.
|
||||||
When omitted |popup_close()| must be used.
|
When omitted |popup_close()| must be used.
|
||||||
|
@@ -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)
|
#if defined(FEAT_TIMERS)
|
||||||
static void
|
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_p_wrap = nr != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wp->w_popup_drag = dict_get_number(dict, (char_u *)"drag");
|
||||||
|
|
||||||
di = dict_find(dict, (char_u *)"callback", -1);
|
di = dict_find(dict, (char_u *)"callback", -1);
|
||||||
if (di != NULL)
|
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;
|
wp->w_popup_padding[3] = 1;
|
||||||
set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
|
set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
|
||||||
(char_u *)"WarningMsg", OPT_FREE|OPT_LOCAL, 0);
|
(char_u *)"WarningMsg", OPT_FREE|OPT_LOCAL, 0);
|
||||||
|
wp->w_popup_drag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deal with options.
|
// Deal with options.
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
/* popupwin.c */
|
/* 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_height(win_T *wp);
|
||||||
int popup_width(win_T *wp);
|
int popup_width(win_T *wp);
|
||||||
void popup_adjust_position(win_T *wp);
|
void popup_adjust_position(win_T *wp);
|
||||||
|
@@ -3,6 +3,7 @@ void do_window(int nchar, long Prenum, int xchar);
|
|||||||
void get_wincmd_addr_type(char_u *arg, exarg_T *eap);
|
void get_wincmd_addr_type(char_u *arg, exarg_T *eap);
|
||||||
int win_split(int size, int flags);
|
int win_split(int size, int flags);
|
||||||
int win_split_ins(int size, int flags, win_T *new_wp, int dir);
|
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(win_T *win);
|
||||||
int win_valid_any_tab(win_T *win);
|
int win_valid_any_tab(win_T *win);
|
||||||
int win_count(void);
|
int win_count(void);
|
||||||
|
@@ -2909,6 +2909,7 @@ struct window_S
|
|||||||
linenr_T w_popup_lnum; // close popup if cursor not on this line
|
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_mincol; // close popup if cursor before this col
|
||||||
colnr_T w_popup_maxcol; // close popup if cursor after 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)
|
# if defined(FEAT_TIMERS)
|
||||||
timer_T *w_popup_timer; // timer for closing popup window
|
timer_T *w_popup_timer; // timer for closing popup window
|
||||||
|
39
src/ui.c
39
src/ui.c
@@ -1002,7 +1002,7 @@ static void clip_update_modeless_selection(VimClipboard *, int, int,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Start, continue or end a modeless selection. Used when editing the
|
* 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
|
void
|
||||||
clip_modeless(int button, int is_click, int is_drag)
|
clip_modeless(int button, int is_click, int is_drag)
|
||||||
@@ -2842,6 +2842,7 @@ jump_to_mouse(
|
|||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
static int in_popup_win = FALSE;
|
static int in_popup_win = FALSE;
|
||||||
|
static win_T *popup_dragwin = NULL;
|
||||||
#endif
|
#endif
|
||||||
static int prev_row = -1;
|
static int prev_row = -1;
|
||||||
static int prev_col = -1;
|
static int prev_col = -1;
|
||||||
@@ -2869,6 +2870,9 @@ jump_to_mouse(
|
|||||||
flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE);
|
flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE);
|
||||||
dragwin = NULL;
|
dragwin = NULL;
|
||||||
did_drag = FALSE;
|
did_drag = FALSE;
|
||||||
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
popup_dragwin = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & MOUSE_DID_MOVE)
|
if ((flags & MOUSE_DID_MOVE)
|
||||||
@@ -2910,7 +2914,15 @@ retnomove:
|
|||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
// Continue a modeless selection in a popup window.
|
// Continue a modeless selection in a popup window.
|
||||||
if (in_popup_win)
|
if (in_popup_win)
|
||||||
|
{
|
||||||
|
if (popup_dragwin != NULL)
|
||||||
|
{
|
||||||
|
// dragging a popup window
|
||||||
|
popup_drag(popup_dragwin);
|
||||||
|
return IN_UNKNOWN;
|
||||||
|
}
|
||||||
return IN_OTHER_WIN;
|
return IN_OTHER_WIN;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return IN_BUFFER;
|
return IN_BUFFER;
|
||||||
}
|
}
|
||||||
@@ -2936,22 +2948,28 @@ retnomove:
|
|||||||
|
|
||||||
if (!(flags & MOUSE_FOCUS))
|
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;
|
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);
|
wp = mouse_find_win(&row, &col, FIND_POPUP);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return IN_UNKNOWN;
|
return IN_UNKNOWN;
|
||||||
dragwin = NULL;
|
dragwin = NULL;
|
||||||
|
|
||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
// Click in a popup window may start modeless selection, but not much
|
// Click in a popup window may start dragging or modeless selection,
|
||||||
// else.
|
// but not much else.
|
||||||
if (bt_popup(wp->w_buffer))
|
if (bt_popup(wp->w_buffer))
|
||||||
{
|
{
|
||||||
on_sep_line = 0;
|
on_sep_line = 0;
|
||||||
in_popup_win = TRUE;
|
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
|
# ifdef FEAT_CLIPBOARD
|
||||||
return IN_OTHER_WIN;
|
return IN_OTHER_WIN;
|
||||||
# else
|
# else
|
||||||
@@ -2959,6 +2977,7 @@ retnomove:
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
in_popup_win = FALSE;
|
in_popup_win = FALSE;
|
||||||
|
popup_dragwin = NULL;
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_MENU
|
#ifdef FEAT_MENU
|
||||||
if (row == -1)
|
if (row == -1)
|
||||||
@@ -3127,9 +3146,17 @@ retnomove:
|
|||||||
return IN_OTHER_WIN;
|
return IN_OTHER_WIN;
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
// Continue a modeless selection in a popup window.
|
|
||||||
if (in_popup_win)
|
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;
|
return IN_OTHER_WIN;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
row -= W_WINROW(curwin);
|
row -= W_WINROW(curwin);
|
||||||
|
@@ -777,6 +777,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1525,
|
||||||
/**/
|
/**/
|
||||||
1524,
|
1524,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -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.
|
* 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)
|
win_valid_popup(win_T *win UNUSED)
|
||||||
{
|
{
|
||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
|
Reference in New Issue
Block a user