diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-08-01 21:11:05 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-08-01 21:11:05 +0200 |
commit | 9bcb70c18a740bf9d97a1420df5964618f218a89 (patch) | |
tree | d30e627ced878e523bf4ed499396123a526a21ef | |
parent | 13b11eddcaf5176fb1127c8bc8f4b4f46bd05488 (diff) | |
download | vim-git-9bcb70c18a740bf9d97a1420df5964618f218a89.tar.gz |
patch 8.1.1787: cannot resize a popup windowv8.1.1787
Problem: Cannot resize a popup window.
Solution: Allow for resizing by dragging the lower right corncer.
-rw-r--r-- | runtime/doc/popup.txt | 6 | ||||
-rw-r--r-- | src/popupwin.c | 88 | ||||
-rw-r--r-- | src/structs.h | 1 | ||||
-rw-r--r-- | src/testdir/dumps/Test_popupwin_drag_01.dump | 2 | ||||
-rw-r--r-- | src/testdir/dumps/Test_popupwin_drag_02.dump | 2 | ||||
-rw-r--r-- | src/testdir/dumps/Test_popupwin_drag_03.dump | 10 | ||||
-rw-r--r-- | src/testdir/dumps/Test_popupwin_previewpopup_1.dump | 2 | ||||
-rw-r--r-- | src/testdir/dumps/Test_popupwin_previewpopup_2.dump | 2 | ||||
-rw-r--r-- | src/testdir/dumps/Test_popupwin_previewpopup_3.dump | 2 | ||||
-rw-r--r-- | src/testdir/dumps/Test_popupwin_previewpopup_4.dump | 2 | ||||
-rw-r--r-- | src/testdir/test_popupwin.vim | 9 | ||||
-rw-r--r-- | src/ui.c | 5 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 12 |
14 files changed, 121 insertions, 24 deletions
diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt index 0552951a7..b58ade69d 100644 --- a/runtime/doc/popup.txt +++ b/runtime/doc/popup.txt @@ -1,4 +1,4 @@ -*popup.txt* For Vim version 8.1. Last change: 2019 Jul 28 +*popup.txt* For Vim version 8.1. Last change: 2019 Aug 01 VIM REFERENCE MANUAL by Bram Moolenaar @@ -434,6 +434,7 @@ popup_setoptions({id}, {options}) *popup_setoptions()* callback close drag + resize cursorline filter firstline @@ -542,6 +543,9 @@ The second argument of |popup_create()| is a dictionary with options: popup does not have a border. As soon as dragging starts and "pos" is "center" it is changed to "topleft". + resize TRUE to allow the popup to be resized with the mouse + by grabbing at at the bottom right cornder. Has no + effect if the popup does not have a border. close When "button" an X is displayed in the top-right, on top of any border, padding or text. When clicked on the X the popup will close. Any callback is invoked diff --git a/src/popupwin.c b/src/popupwin.c index ed01693d5..9a39693d0 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -235,13 +235,14 @@ static int drag_start_row; static int drag_start_col; static int drag_start_wantline; static int drag_start_wantcol; +static int drag_on_resize_handle; /* * Mouse down on border of popup window: start dragging it. * Uses mouse_col and mouse_row. */ void -popup_start_drag(win_T *wp) +popup_start_drag(win_T *wp, int row, int col) { drag_start_row = mouse_row; drag_start_col = mouse_col; @@ -258,10 +259,26 @@ popup_start_drag(win_T *wp) // Stop centering the popup if (wp->w_popup_pos == POPPOS_CENTER) wp->w_popup_pos = POPPOS_TOPLEFT; + + drag_on_resize_handle = wp->w_popup_border[1] > 0 + && wp->w_popup_border[2] > 0 + && row == popup_height(wp) - 1 + && col == popup_width(wp) - 1; + + if (wp->w_popup_pos != POPPOS_TOPLEFT && drag_on_resize_handle) + { + if (wp->w_popup_pos == POPPOS_TOPRIGHT + || wp->w_popup_pos == POPPOS_BOTRIGHT) + wp->w_wantcol = wp->w_wincol + 1; + if (wp->w_popup_pos == POPPOS_BOTLEFT) + wp->w_wantline = wp->w_winrow + 1; + wp->w_popup_pos = POPPOS_TOPLEFT; + } } /* - * Mouse moved while dragging a popup window: adjust the window popup position. + * Mouse moved while dragging a popup window: adjust the window popup position + * or resize. */ void popup_drag(win_T *wp) @@ -270,6 +287,39 @@ popup_drag(win_T *wp) if (!win_valid_popup(wp)) return; + if ((wp->w_popup_flags & POPF_RESIZE) && drag_on_resize_handle) + { + int width_inc = mouse_col - drag_start_col; + int height_inc = mouse_row - drag_start_row; + + if (width_inc != 0) + { + int width = wp->w_width + width_inc; + + if (width < 1) + width = 1; + wp->w_minwidth = width; + wp->w_maxwidth = width; + drag_start_col = mouse_col; + } + + if (height_inc != 0) + { + int height = wp->w_height + height_inc; + + if (height < 1) + height = 1; + wp->w_minheight = height; + wp->w_maxheight = height; + drag_start_row = mouse_row; + } + + popup_adjust_position(wp); + return; + } + + if (!(wp->w_popup_flags & POPF_DRAG)) + return; wp->w_wantline = drag_start_wantline + (mouse_row - drag_start_row); if (wp->w_wantline < 1) wp->w_wantline = 1; @@ -550,7 +600,23 @@ apply_general_options(win_T *wp, dict_T *dict) di = dict_find(dict, (char_u *)"drag", -1); if (di != NULL) - wp->w_popup_drag = dict_get_number(dict, (char_u *)"drag"); + { + nr = dict_get_number(dict, (char_u *)"drag"); + if (nr) + wp->w_popup_flags |= POPF_DRAG; + else + wp->w_popup_flags &= ~POPF_DRAG; + } + + di = dict_find(dict, (char_u *)"resize", -1); + if (di != NULL) + { + nr = dict_get_number(dict, (char_u *)"resize"); + if (nr) + wp->w_popup_flags |= POPF_RESIZE; + else + wp->w_popup_flags &= ~POPF_RESIZE; + } di = dict_find(dict, (char_u *)"close", -1); if (di != NULL) @@ -1477,7 +1543,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) wp->w_wantcol = 10; wp->w_zindex = POPUPWIN_NOTIFICATION_ZINDEX; wp->w_minwidth = 20; - wp->w_popup_drag = 1; + wp->w_popup_flags |= POPF_DRAG; wp->w_popup_close = POPCLOSE_CLICK; for (i = 0; i < 4; ++i) wp->w_popup_border[i] = 1; @@ -1494,7 +1560,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) { wp->w_popup_pos = POPPOS_CENTER; wp->w_zindex = POPUPWIN_DIALOG_ZINDEX; - wp->w_popup_drag = 1; + wp->w_popup_flags |= POPF_DRAG; for (i = 0; i < 4; ++i) { wp->w_popup_border[i] = 1; @@ -1519,7 +1585,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) if (type == TYPE_PREVIEW) { - wp->w_popup_drag = 1; + wp->w_popup_flags |= POPF_DRAG | POPF_RESIZE; wp->w_popup_close = POPCLOSE_BUTTON; for (i = 0; i < 4; ++i) wp->w_popup_border[i] = 1; @@ -1707,7 +1773,7 @@ filter_handle_drag(win_T *wp, int c, typval_T *rettv) int row = mouse_row; int col = mouse_col; - if (wp->w_popup_drag + if ((wp->w_popup_flags & POPF_DRAG) && is_mouse_key(c) && (wp == popup_dragwin || wp == mouse_find_win(&row, &col, FIND_POPUP))) @@ -2244,7 +2310,8 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv) dict_add_number(dict, "fixed", wp->w_popup_fixed); dict_add_string(dict, "title", wp->w_popup_title); dict_add_number(dict, "wrap", wp->w_p_wrap); - dict_add_number(dict, "drag", wp->w_popup_drag); + dict_add_number(dict, "drag", (wp->w_popup_flags & POPF_DRAG) != 0); + dict_add_number(dict, "resize", (wp->w_popup_flags & POPF_RESIZE) != 0); dict_add_number(dict, "cursorline", (wp->w_popup_flags & POPF_CURSORLINE) != 0); dict_add_string(dict, "highlight", wp->w_p_wcr); @@ -2811,7 +2878,8 @@ update_popups(void (*win_update)(win_T *wp)) border_char[1] = border_char[3] = 0x2551; border_char[4] = 0x2554; border_char[5] = 0x2557; - border_char[6] = 0x255d; + border_char[6] = (wp->w_popup_flags & POPF_RESIZE) + ? 0x21f2 : 0x255d; border_char[7] = 0x255a; } else @@ -2820,6 +2888,8 @@ update_popups(void (*win_update)(win_T *wp)) border_char[1] = border_char[3] = '|'; for (i = 4; i < 8; ++i) border_char[i] = '+'; + if (wp->w_popup_flags & POPF_RESIZE) + border_char[6] = '@'; } for (i = 0; i < 8; ++i) if (wp->w_border_char[i] != 0) diff --git a/src/structs.h b/src/structs.h index 21b5f693b..7a21d270a 100644 --- a/src/structs.h +++ b/src/structs.h @@ -3017,7 +3017,6 @@ struct window_S int w_popup_mouse_row; // close popup if mouse moves away int w_popup_mouse_mincol; // close popup if mouse moves away int w_popup_mouse_maxcol; // close popup if mouse moves away - int w_popup_drag; // allow moving the popup with the mouse popclose_T w_popup_close; // allow closing the popup with the mouse list_T *w_popup_mask; // list of lists for "mask" diff --git a/src/testdir/dumps/Test_popupwin_drag_01.dump b/src/testdir/dumps/Test_popupwin_drag_01.dump index c8867e3ff..64afe8275 100644 --- a/src/testdir/dumps/Test_popupwin_drag_01.dump +++ b/src/testdir/dumps/Test_popupwin_drag_01.dump @@ -7,4 +7,4 @@ |7| @31|║+0#0000001#ffd7ff255|1@3| @1|║| +0#0000000#ffffff0@33 |8| @31|║+0#0000001#ffd7ff255|2@5|║| +0#0000000#ffffff0@33 |9| @31|║+0#0000001#ffd7ff255|3@4| |║| +0#0000000#ffffff0@33 -@33|╚+0#0000001#ffd7ff255|═@5|╝| +0#0000000#ffffff0@15|1|,|1| @10|T|o|p| +@33|╚+0#0000001#ffd7ff255|═@5|⇲| +0#0000000#ffffff0@15|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_drag_02.dump b/src/testdir/dumps/Test_popupwin_drag_02.dump index f03ecb847..2597e1d06 100644 --- a/src/testdir/dumps/Test_popupwin_drag_02.dump +++ b/src/testdir/dumps/Test_popupwin_drag_02.dump @@ -3,7 +3,7 @@ |3| @31|║+0#0000001#ffd7ff255|1@3| @1|║| +0#0000000#ffffff0@33 |4| @31|║+0#0000001#ffd7ff255|2@5|║| +0#0000000#ffffff0@33 |5| @31|║+0#0000001#ffd7ff255|3@4| |║| +0#0000000#ffffff0@33 -|6| @31|╚+0#0000001#ffd7ff255|═@5|╝| +0#0000000#ffffff0@33 +|6| @31|╚+0#0000001#ffd7ff255|═@5|⇲| +0#0000000#ffffff0@33 |7| @73 |8| @73 |9| @73 diff --git a/src/testdir/dumps/Test_popupwin_drag_03.dump b/src/testdir/dumps/Test_popupwin_drag_03.dump new file mode 100644 index 000000000..b6b363a5f --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_drag_03.dump @@ -0,0 +1,10 @@ +>1+0&#ffffff0| @73 +|2| @31|╔+0#0000001#ffd7ff255|═@9|╗| +0#0000000#ffffff0@29 +|3| @31|║+0#0000001#ffd7ff255|1@3| @5|║| +0#0000000#ffffff0@29 +|4| @31|║+0#0000001#ffd7ff255|2@5| @3|║| +0#0000000#ffffff0@29 +|5| @31|║+0#0000001#ffd7ff255|3@4| @4|║| +0#0000000#ffffff0@29 +|6| @31|║+0#0000001#ffd7ff255| +0#4040ff13&@9|║+0#0000001&| +0#0000000#ffffff0@29 +|7| @31|╚+0#0000001#ffd7ff255|═@9|⇲| +0#0000000#ffffff0@29 +|8| @73 +|9| @73 +|:|c|a|l@1| |R|e|s|i|z|e|(|)| @42|1|,|1| @10|T|o|p| diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_1.dump b/src/testdir/dumps/Test_popupwin_previewpopup_1.dump index 06ac4cbfa..1b8729233 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_1.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_1.dump @@ -4,7 +4,7 @@ |f|o|u|r| |║+0#0000001#ffd7ff255|t|h|e|w|o|r|d| |i|s| |h|e|r|e| @24| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26 |f|i|v|e| |║+0#0000001#ffd7ff255|2@1| @37| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26 |s|i|x| @1|║+0#0000001#ffd7ff255|2|3| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@26 -|s|e|v|e|n|╚+0#0000001#ffd7ff255|═@40|╝| +0#0000000#ffffff0@26 +|s|e|v|e|n|╚+0#0000001#ffd7ff255|═@40|⇲| +0#0000000#ffffff0@26 |f|i|n|d| >t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @52 |n|i|n|e| @70 |t|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @54 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_2.dump b/src/testdir/dumps/Test_popupwin_previewpopup_2.dump index aa53bb340..131eabe81 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_2.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_2.dump @@ -6,7 +6,7 @@ |s|i|x| @4|║+0#0000001#ffd7ff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@23 |s|e|v|e|n| @2|║+0#0000001#ffd7ff255|2|9| @37| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@23 |f|i|n|d| |t|h|e|║+0#0000001#ffd7ff255|3|0| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@23 -|n|i|n|e| @3|╚+0#0000001#ffd7ff255|═@40|╝| +0#0000000#ffffff0@23 +|n|i|n|e| @3|╚+0#0000001#ffd7ff255|═@40|⇲| +0#0000000#ffffff0@23 |t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54 |v|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| |a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_3.dump b/src/testdir/dumps/Test_popupwin_previewpopup_3.dump index c4ae417cf..46a3a6183 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_3.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_3.dump @@ -6,7 +6,7 @@ |s|i|x| @10|║+0#0000001#ffd7ff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@17 |s|e|v|e|n| @8|║+0#0000001#ffd7ff255|2|9| @37| +0#0000000#0000001|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@17 |f|i|n|d| |t|h|e|w|o|r|d| |s|║+0#0000001#ffd7ff255|3|0| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@17 -|n|i|n|e| @9|╚+0#0000001#ffd7ff255|═@40|╝| +0#0000000#ffffff0@17 +|n|i|n|e| @9|╚+0#0000001#ffd7ff255|═@40|⇲| +0#0000000#ffffff0@17 |t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54 |v|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| |a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_4.dump b/src/testdir/dumps/Test_popupwin_previewpopup_4.dump index fc635073c..de67fa39a 100644 --- a/src/testdir/dumps/Test_popupwin_previewpopup_4.dump +++ b/src/testdir/dumps/Test_popupwin_previewpopup_4.dump @@ -7,7 +7,7 @@ |s+0#0000000#ffffff0|e|v|e|n| @26|║+0#0000001#ffd7ff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 |f+0#0000000#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0#0000001#ffd7ff255|2|9| @37| +0#0000000#0000001|║+0#0000001#ffd7ff255 |n+0#0000000#ffffff0|i|n|e| @27|║+0#0000001#ffd7ff255|3|0| @37| +0#0000000#a8a8a8255|║+0#0000001#ffd7ff255 -|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0#0000001#ffd7ff255|═@40|╝ +|t+0#0000000#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0#0000001#ffd7ff255|═@40|⇲ |v+0#0000000#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29 |~+0#4040ff13&| @73 |~| @73 diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index 6033be68a..d4b98aee7 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -354,6 +354,7 @@ func Test_popup_drag() call setline(1, range(1, 20)) let winid = popup_create(['1111', '222222', '33333'], #{ \ drag: 1, + \ resize: 1, \ border: [], \ line: &lines - 4, \ }) @@ -362,6 +363,11 @@ func Test_popup_drag() endfunc map <silent> <F3> :call test_setmouse(&lines - 4, &columns / 2)<CR> map <silent> <F4> :call test_setmouse(&lines - 8, &columns / 2)<CR> + func Resize() + call feedkeys("\<F5>\<LeftMouse>\<F6>\<LeftDrag>\<LeftRelease>", "xt") + endfunc + map <silent> <F5> :call test_setmouse(6, 41)<CR> + map <silent> <F6> :call test_setmouse(7, 45)<CR> END call writefile(lines, 'XtestPopupDrag') let buf = RunVimInTerminal('-S XtestPopupDrag', #{rows: 10}) @@ -370,6 +376,9 @@ func Test_popup_drag() call term_sendkeys(buf, ":call Dragit()\<CR>") call VerifyScreenDump(buf, 'Test_popupwin_drag_02', {}) + call term_sendkeys(buf, ":call Resize()\<CR>") + call VerifyScreenDump(buf, 'Test_popupwin_drag_03', {}) + " clean up call StopVimInTerminal(buf) call delete('XtestPopupDrag') @@ -3067,10 +3067,11 @@ retnomove: popup_close_for_mouse_click(wp); return IN_UNKNOWN; } - else if (wp->w_popup_drag && popup_on_border(wp, row, col)) + else if ((wp->w_popup_flags & (POPF_DRAG | POPF_RESIZE)) + && popup_on_border(wp, row, col)) { popup_dragwin = wp; - popup_start_drag(wp); + popup_start_drag(wp, row, col); return IN_UNKNOWN; } // Only close on release, otherwise it's not possible to drag or do diff --git a/src/version.c b/src/version.c index 0e30df7cd..8ec7b411e 100644 --- a/src/version.c +++ b/src/version.c @@ -774,6 +774,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1787, +/**/ 1786, /**/ 1785, @@ -614,11 +614,13 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring); #define VALID_TOPLINE 0x80 // w_topline is valid (for cursor position) // Values for w_popup_flags. -#define POPF_IS_POPUP 1 // this is a popup window -#define POPF_HIDDEN 2 // popup is not displayed -#define POPF_HANDLED 4 // popup was just redrawn or filtered -#define POPF_CURSORLINE 8 // popup is highlighting at the cursorline -#define POPF_ON_CMDLINE 16 // popup overlaps command line +#define POPF_IS_POPUP 0x01 // this is a popup window +#define POPF_HIDDEN 0x02 // popup is not displayed +#define POPF_HANDLED 0x04 // popup was just redrawn or filtered +#define POPF_CURSORLINE 0x08 // popup is highlighting at the cursorline +#define POPF_ON_CMDLINE 0x10 // popup overlaps command line +#define POPF_DRAG 0x20 // popup can be moved by dragging +#define POPF_RESIZE 0x40 // popup can be resized by dragging #ifdef FEAT_TEXT_PROP # define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0) |