mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.4902: mouse wheel scrolling is inconsistent
Problem: Mouse wheel scrolling is inconsistent. Solution: Use the MS-Winows system setting. (closes #10368)
This commit is contained in:
@@ -237,31 +237,34 @@ it works depends on your system. It might also work in an xterm
|
||||
|xterm-mouse-wheel|. By default only vertical scroll wheels are supported,
|
||||
but some GUIs also support horizontal scroll wheels.
|
||||
|
||||
For the Win32 GUI the scroll action is hard coded. It works just like
|
||||
dragging the scrollbar of the current window. How many lines are scrolled
|
||||
depends on your mouse driver. If the scroll action causes input focus
|
||||
problems, see |intellimouse-wheel-problems|.
|
||||
On MS-Windows, if the scroll action causes input focus -problems, see
|
||||
|intellimouse-wheel-problems|.
|
||||
|
||||
For the X11 GUIs (Motif and GTK) scrolling the wheel generates key
|
||||
For Win32 and the X11 GUIs (Motif and GTK) scrolling the wheel generates key
|
||||
presses <ScrollWheelUp>, <ScrollWheelDown>, <ScrollWheelLeft> and
|
||||
<ScrollWheelRight>. For example, if you push the scroll wheel upwards a
|
||||
<ScrollWheelUp> key press is generated causing the window to scroll upwards
|
||||
(while the text is actually moving downwards). The default action for these
|
||||
keys are:
|
||||
<ScrollWheelUp> scroll three lines up *<ScrollWheelUp>*
|
||||
<ScrollWheelUp> scroll N lines up *<ScrollWheelUp>*
|
||||
<S-ScrollWheelUp> scroll one page up *<S-ScrollWheelUp>*
|
||||
<C-ScrollWheelUp> scroll one page up *<C-ScrollWheelUp>*
|
||||
<ScrollWheelDown> scroll three lines down *<ScrollWheelDown>*
|
||||
<ScrollWheelDown> scroll N lines down *<ScrollWheelDown>*
|
||||
<S-ScrollWheelDown> scroll one page down *<S-ScrollWheelDown>*
|
||||
<C-ScrollWheelDown> scroll one page down *<C-ScrollWheelDown>*
|
||||
<ScrollWheelLeft> scroll six columns left *<ScrollWheelLeft>*
|
||||
<ScrollWheelLeft> scroll N columns left *<ScrollWheelLeft>*
|
||||
<S-ScrollWheelLeft> scroll one page left *<S-ScrollWheelLeft>*
|
||||
<C-ScrollWheelLeft> scroll one page left *<C-ScrollWheelLeft>*
|
||||
<ScrollWheelRight> scroll six columns right *<ScrollWheelRight>*
|
||||
<ScrollWheelRight> scroll N columns right *<ScrollWheelRight>*
|
||||
<S-ScrollWheelRight> scroll one page right *<S-ScrollWheelRight>*
|
||||
<C-ScrollWheelRight> scroll one page right *<C-ScrollWheelRight>*
|
||||
This should work in all modes, except when editing the command line.
|
||||
|
||||
The value of N depends on the system. By default Vim scrolls three lines when
|
||||
moving vertically, and six columns when moving horizontally. On MS-Windows
|
||||
the amount of lines and columns for each scroll action is taken from the
|
||||
system-wide settings.
|
||||
|
||||
Note that horizontal scrolling only works if 'nowrap' is set. Also, unless
|
||||
the "h" flag in 'guioptions' is set, the cursor moves to the longest visible
|
||||
line if the cursor line is about to be scrolled off the screen (similarly to
|
||||
|
@@ -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,19 +4121,33 @@ gui_mswin_get_menu_height(
|
||||
/*
|
||||
* Setup for the Intellimouse
|
||||
*/
|
||||
static long
|
||||
mouse_vertical_scroll_step(void)
|
||||
{
|
||||
UINT val;
|
||||
if (SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &val, 0))
|
||||
return (val != WHEEL_PAGESCROLL) ? (long)val : -1;
|
||||
return 3; // Safe default;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// Reasonable default values.
|
||||
mouse_scroll_lines = 3;
|
||||
mouse_scroll_chars = 3;
|
||||
|
||||
// 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);
|
||||
// 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.
|
||||
* Treat a mouse wheel event as if it were a scroll request.
|
||||
@@ -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();
|
||||
|
56
src/mouse.c
56
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;
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -746,6 +746,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
4902,
|
||||
/**/
|
||||
4901,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user