summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-06-13 23:59:52 +0200
committerBram Moolenaar <Bram@vim.org>2019-06-13 23:59:52 +0200
commitb53fb31a1e27a806396e38592055cfb3ebf43cf9 (patch)
tree57888f517cf09fe3680bdcf9803fe75d929be3fd
parentb0f94c1ff34d27d33aa9f96204985ea29c2eb0a1 (diff)
downloadvim-git-b53fb31a1e27a806396e38592055cfb3ebf43cf9.tar.gz
patch 8.1.1525: cannot move a popup window with the mousev8.1.1525
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.
-rw-r--r--runtime/doc/popup.txt13
-rw-r--r--src/popupwin.c65
-rw-r--r--src/proto/popupwin.pro3
-rw-r--r--src/proto/window.pro1
-rw-r--r--src/structs.h1
-rw-r--r--src/ui.c43
-rw-r--r--src/version.c2
-rw-r--r--src/window.c2
8 files changed, 117 insertions, 13 deletions
diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt
index 7e56d35b9..7da0d1689 100644
--- a/runtime/doc/popup.txt
+++ b/runtime/doc/popup.txt
@@ -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.
diff --git a/src/popupwin.c b/src/popupwin.c
index 5e444aee0..f773958be 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -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.
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index 03d3729ed..eeabafa9a 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -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);
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 1424c3de5..94b9f083a 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -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);
diff --git a/src/structs.h b/src/structs.h
index da5ed2e53..04e21a106 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -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
diff --git a/src/ui.c b/src/ui.c
index 62d8ae7d3..08b3011c0 100644
--- a/src/ui.c
+++ b/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
- * 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);
diff --git a/src/version.c b/src/version.c
index 9835fcc7e..058dbc702 100644
--- a/src/version.c
+++ b/src/version.c
@@ -778,6 +778,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1525,
+/**/
1524,
/**/
1523,
diff --git a/src/window.c b/src/window.c
index c15a86111..436912934 100644
--- a/src/window.c
+++ b/src/window.c
@@ -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