diff options
author | LemonBoy <thatlemon@gmail.com> | 2022-05-07 12:25:40 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-05-07 12:25:40 +0100 |
commit | c27747e6ddcbda7d1d3b39867898f746dc4db471 (patch) | |
tree | 0ba88dccf18f52a745e746de249f8a7de752b060 /src | |
parent | 8e4b76da1d7e987d43ca960dfbc372d1c617466f (diff) |
patch 8.2.4902: mouse wheel scrolling is inconsistentv8.2.4902
Problem: Mouse wheel scrolling is inconsistent.
Solution: Use the MS-Winows system setting. (closes #10368)
Diffstat (limited to 'src')
-rw-r--r-- | src/gui_w32.c | 65 | ||||
-rw-r--r-- | src/mouse.c | 56 | ||||
-rw-r--r-- | src/proto/mouse.pro | 2 | ||||
-rw-r--r-- | src/testdir/test_gui.vim | 2 | ||||
-rw-r--r-- | src/testing.c | 5 | ||||
-rw-r--r-- | src/version.c | 2 |
6 files changed, 83 insertions, 49 deletions
diff --git a/src/gui_w32.c b/src/gui_w32.c index c6a8b6d6e7..7bca9e7aca 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -230,6 +230,10 @@ gui_mch_set_rendering_options(char_u *s) # define SPI_GETWHEELSCROLLCHARS 0x006C #endif +#ifndef SPI_SETWHEELSCROLLCHARS +# define SPI_SETWHEELSCROLLCHARS 0x006D +#endif + #ifdef PROTO /* * Define a few things for generating prototypes. This is just to avoid @@ -4117,18 +4121,32 @@ gui_mswin_get_menu_height( /* * Setup for the Intellimouse */ - static void -init_mouse_wheel(void) + static long +mouse_vertical_scroll_step(void) { - // Reasonable default values. - mouse_scroll_lines = 3; - mouse_scroll_chars = 3; + UINT val; + if (SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &val, 0)) + return (val != WHEEL_PAGESCROLL) ? (long)val : -1; + return 3; // Safe default; +} - // if NT 4.0+ (or Win98) get scroll lines directly from system - SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &mouse_scroll_lines, 0); - SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &mouse_scroll_chars, 0); + static long +mouse_horizontal_scroll_step(void) +{ + UINT val; + if (SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &val, 0)) + return (long)val; + return 3; // Safe default; } + static void +init_mouse_wheel(void) +{ + // Get the default values for the horizontal and vertical scroll steps from + // the system. + mouse_set_vert_scroll_step(mouse_vertical_scroll_step()); + mouse_set_hor_scroll_step(mouse_horizontal_scroll_step()); +} /* * Intellimouse wheel handler. @@ -4137,16 +4155,10 @@ init_mouse_wheel(void) static void _OnMouseWheel(HWND hwnd, short zDelta, LPARAM param, int horizontal) { - int i; - int amount; int button; win_T *wp; int modifiers, kbd_modifiers; - // Initializes mouse_scroll_chars too. - if (mouse_scroll_lines == 0) - init_mouse_wheel(); - wp = gui_mouse_window(FIND_POPUP); #ifdef FEAT_PROP_POPUP @@ -4185,23 +4197,9 @@ _OnMouseWheel(HWND hwnd, short zDelta, LPARAM param, int horizontal) // Translate the scroll event into an event that Vim can process so that // the user has a chance to map the scrollwheel buttons. if (horizontal) - { button = zDelta >= 0 ? MOUSE_6 : MOUSE_7; - if (mouse_scroll_chars > 0 - && mouse_scroll_chars < MAX(wp->w_width - 2, 1)) - amount = mouse_scroll_chars; - else - amount = MAX(wp->w_width - 2, 1); - } else - { button = zDelta >= 0 ? MOUSE_4 : MOUSE_5; - if (mouse_scroll_lines > 0 - && mouse_scroll_lines < MAX(wp->w_height - 2, 1)) - amount = mouse_scroll_lines; - else - amount = MAX(wp->w_height - 2, 1); - } kbd_modifiers = get_active_modifiers(); @@ -4213,8 +4211,7 @@ _OnMouseWheel(HWND hwnd, short zDelta, LPARAM param, int horizontal) modifiers |= MOUSE_ALT; mch_disable_flush(); - for (i = amount; i > 0; --i) - gui_send_mouse_event(button, GET_X_LPARAM(param), GET_Y_LPARAM(param), + gui_send_mouse_event(button, GET_X_LPARAM(param), GET_Y_LPARAM(param), FALSE, kbd_modifiers); mch_enable_flush(); gui_may_flush(); @@ -4296,12 +4293,10 @@ _OnSettingChange(UINT param) switch (param) { case SPI_SETWHEELSCROLLLINES: - SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, - &mouse_scroll_lines, 0); + mouse_set_vert_scroll_step(mouse_vertical_scroll_step()); break; - case SPI_GETWHEELSCROLLCHARS: - SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, - &mouse_scroll_chars, 0); + case SPI_SETWHEELSCROLLCHARS: + mouse_set_hor_scroll_step(mouse_horizontal_scroll_step()); break; case SPI_SETNONCLIENTMETRICS: set_tabline_font(); diff --git a/src/mouse.c b/src/mouse.c index a0c5156052..57b0f1405b 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -13,6 +13,25 @@ #include "vim.h" +/* + * Horiziontal and vertical steps used when scrolling. + * When negative scroll by a whole page. + */ +static long mouse_hor_step = 6; +static long mouse_vert_step = 3; + + void +mouse_set_vert_scroll_step(long step) +{ + mouse_vert_step = step; +} + + void +mouse_set_hor_scroll_step(long step) +{ + mouse_hor_step = step; +} + #ifdef CHECK_DOUBLE_CLICK /* * Return the duration from t1 to t2 in milliseconds. @@ -1101,13 +1120,16 @@ ins_mousescroll(int dir) // Don't scroll the window in which completion is being done. if (!pum_visible() || curwin != old_curwin) { + long step; + if (dir == MSCR_DOWN || dir == MSCR_UP) { - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) - scroll_redraw(dir, - (long)(curwin->w_botline - curwin->w_topline)); + if (mouse_vert_step < 0 + || mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + step = (long)(curwin->w_botline - curwin->w_topline); else - scroll_redraw(dir, 3L); + step = mouse_vert_step; + scroll_redraw(dir, step); # ifdef FEAT_PROP_POPUP if (WIN_IS_POPUP(curwin)) popup_set_firstline(curwin); @@ -1116,10 +1138,13 @@ ins_mousescroll(int dir) #ifdef FEAT_GUI else { - int val, step = 6; + int val; - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + if (mouse_hor_step < 0 + || mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) step = curwin->w_width; + else + step = mouse_hor_step; val = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : step); if (val < 0) val = 0; @@ -2005,8 +2030,9 @@ retnomove: } /* - * Mouse scroll wheel: Default action is to scroll three lines, or one page - * when Shift or Ctrl is used. + * Mouse scroll wheel: Default action is to scroll mouse_vert_step lines (or + * mouse_hor_step, depending on the scroll direction), or one page when Shift or + * Ctrl is used. * K_MOUSEUP (cap->arg == 1) or K_MOUSEDOWN (cap->arg == 0) or * K_MOUSELEFT (cap->arg == -1) or K_MOUSERIGHT (cap->arg == -2) */ @@ -2033,7 +2059,6 @@ nv_mousescroll(cmdarg_T *cap) curwin = wp; curbuf = curwin->w_buffer; } - if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { # ifdef FEAT_TERMINAL @@ -2043,21 +2068,21 @@ nv_mousescroll(cmdarg_T *cap) send_keys_to_term(curbuf->b_term, cap->cmdchar, mod_mask, FALSE); else # endif - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + if (mouse_vert_step < 0 || mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { (void)onepage(cap->arg ? FORWARD : BACKWARD, 1L); } else { // Don't scroll more than half the window height. - if (curwin->w_height < 6) + if (curwin->w_height < mouse_vert_step * 2) { cap->count1 = curwin->w_height / 2; if (cap->count1 == 0) cap->count1 = 1; } else - cap->count1 = 3; + cap->count1 = mouse_vert_step; cap->count0 = cap->count1; nv_scroll_line(cap); } @@ -2072,10 +2097,13 @@ nv_mousescroll(cmdarg_T *cap) // Horizontal scroll - only allowed when 'wrap' is disabled if (!curwin->w_p_wrap) { - int val, step = 6; + int val, step; - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + if (mouse_hor_step < 0 + || mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) step = curwin->w_width; + else + step = mouse_hor_step; val = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step); if (val < 0) val = 0; diff --git a/src/proto/mouse.pro b/src/proto/mouse.pro index 37a2f07cb6..249e7f2408 100644 --- a/src/proto/mouse.pro +++ b/src/proto/mouse.pro @@ -1,4 +1,6 @@ /* mouse.c */ +void mouse_set_vert_scroll_step(long step); +void mouse_set_hor_scroll_step(long step); int do_mouse(oparg_T *oap, int c, int dir, long count, int fixindent); void ins_mouse(int c); void ins_mousescroll(int dir); diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim index 993954b5a1..bc3c698055 100644 --- a/src/testdir/test_gui.vim +++ b/src/testdir/test_gui.vim @@ -997,6 +997,7 @@ func Test_gui_mouse_event() call assert_equal(['one two abc three', 'four five posix'], getline(1, '$')) %d _ + set scrolloff=0 call setline(1, range(1, 100)) " scroll up let args = #{button: 0x200, row: 2, col: 1, multiclick: 0, modifiers: 0} @@ -1012,6 +1013,7 @@ func Test_gui_mouse_event() call test_gui_event('mouse', args) call feedkeys("H", 'Lx!') call assert_equal(4, line('.')) + set scrolloff& %d _ set nowrap diff --git a/src/testing.c b/src/testing.c index 3340123021..572dcdcffe 100644 --- a/src/testing.c +++ b/src/testing.c @@ -1393,6 +1393,11 @@ test_gui_mouse_event(dict_T *args) repeated_click = (int)dict_get_number(args, (char_u *)"multiclick"); mods = (int)dict_get_number(args, (char_u *)"modifiers"); + // Reset the scroll values to known values. + // XXX: Remove this when/if the scroll step is made configurable. + mouse_set_hor_scroll_step(6); + mouse_set_vert_scroll_step(3); + gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1), repeated_click, mods); } diff --git a/src/version.c b/src/version.c index 647011ae13..5ee96b6178 100644 --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4902, +/**/ 4901, /**/ 4900, |