summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLemonBoy <thatlemon@gmail.com>2022-05-07 12:25:40 +0100
committerBram Moolenaar <Bram@vim.org>2022-05-07 12:25:40 +0100
commitc27747e6ddcbda7d1d3b39867898f746dc4db471 (patch)
tree0ba88dccf18f52a745e746de249f8a7de752b060 /src
parent8e4b76da1d7e987d43ca960dfbc372d1c617466f (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.c65
-rw-r--r--src/mouse.c56
-rw-r--r--src/proto/mouse.pro2
-rw-r--r--src/testdir/test_gui.vim2
-rw-r--r--src/testing.c5
-rw-r--r--src/version.c2
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,