changeset 28700:7fc67f9d84a7 v8.2.4874

patch 8.2.4874: Win32 GUI: horizontal scroll wheel not handled properly Commit: https://github.com/vim/vim/commit/365d8f76b57e2cb4097e641719882a85b3470358 Author: LemonBoy <thatlemon@gmail.com> Date: Thu May 5 19:23:07 2022 +0100 patch 8.2.4874: Win32 GUI: horizontal scroll wheel not handled properly Problem: Win32 GUI: horizontal scroll wheel not handled properly. Solution: Also handle WM_MOUSEHWHEEL. (closes https://github.com/vim/vim/issues/10309)
author Bram Moolenaar <Bram@vim.org>
date Thu, 05 May 2022 20:30:03 +0200
parents 32582071f130
children a4b92f0c0002
files src/gui_w32.c src/version.c
diffstat 2 files changed, 87 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -219,7 +219,15 @@ gui_mch_set_rendering_options(char_u *s)
 #define DLG_NONBUTTON_CONTROL	5000	// First ID of non-button controls
 
 #ifndef WM_DPICHANGED
-# define WM_DPICHANGED		0x02E0
+# define WM_DPICHANGED			0x02E0
+#endif
+
+#ifndef WM_MOUSEHWHEEL
+# define WM_MOUSEHWHEEL			0x020E
+#endif
+
+#ifndef SPI_GETWHEELSCROLLCHARS
+# define SPI_GETWHEELSCROLLCHARS	0x006C
 #endif
 
 #ifdef PROTO
@@ -3992,6 +4000,7 @@ static int dialog_default_button = -1;
 
 // Intellimouse support
 static int mouse_scroll_lines = 0;
+static int mouse_scroll_chars = 0;
 
 #ifdef FEAT_TOOLBAR
 static void initialise_toolbar(void);
@@ -4111,11 +4120,13 @@ gui_mswin_get_menu_height(
     static void
 init_mouse_wheel(void)
 {
-    mouse_scroll_lines = 3;	// reasonable default
+    // 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_GETWHEELSCROLLLINES, 0, &mouse_scroll_lines, 0);
+    SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &mouse_scroll_chars, 0);
 }
 
 
@@ -4124,15 +4135,15 @@ init_mouse_wheel(void)
  * Treat a mouse wheel event as if it were a scroll request.
  */
     static void
-_OnMouseWheel(
-    HWND hwnd,
-    short zDelta)
-{
-    int i;
-    int size;
-    HWND hwndCtl;
-    win_T *wp;
-
+_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();
 
@@ -4148,8 +4159,16 @@ init_mouse_wheel(void)
 	mouse_row = wp->w_winrow;
 	mouse_col = wp->w_wincol;
 	CLEAR_FIELD(cap);
-	cap.arg = zDelta < 0 ? MSCR_UP : MSCR_DOWN;
-	cap.cmdchar = zDelta < 0 ? K_MOUSEUP : K_MOUSEDOWN;
+	if (horizontal)
+	{
+	    cap.arg = zDelta < 0 ? MSCR_LEFT : MSCR_RIGHT;
+	    cap.cmdchar = zDelta < 0 ? K_MOUSELEFT : K_MOUSERIGHT;
+	}
+	else
+	{
+	    cap.arg = zDelta < 0 ? MSCR_UP : MSCR_DOWN;
+	    cap.cmdchar = zDelta < 0 ? K_MOUSEUP : K_MOUSEDOWN;
+	}
 	clear_oparg(&oa);
 	cap.oap = &oa;
 	nv_mousescroll(&cap);
@@ -4163,23 +4182,40 @@ init_mouse_wheel(void)
     if (wp == NULL || !p_scf)
 	wp = curwin;
 
-    if (wp->w_scrollbars[SBAR_RIGHT].id != 0)
-	hwndCtl = wp->w_scrollbars[SBAR_RIGHT].id;
-    else if (wp->w_scrollbars[SBAR_LEFT].id != 0)
-	hwndCtl = wp->w_scrollbars[SBAR_LEFT].id;
+    // 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
-	return;
-    size = wp->w_height;
+    {
+	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();
+
+    if ((kbd_modifiers & MOD_MASK_SHIFT) != 0)
+	modifiers |= MOUSE_SHIFT;
+    if ((kbd_modifiers & MOD_MASK_CTRL) != 0)
+	modifiers |= MOUSE_CTRL;
+    if ((kbd_modifiers & MOD_MASK_ALT) != 0)
+	modifiers |= MOUSE_ALT;
 
     mch_disable_flush();
-    if (mouse_scroll_lines > 0
-	    && mouse_scroll_lines < (size > 2 ? size - 2 : 1))
-    {
-	for (i = mouse_scroll_lines; i > 0; --i)
-	    _OnScroll(hwnd, hwndCtl, zDelta >= 0 ? SB_LINEUP : SB_LINEDOWN, 0);
-    }
-    else
-	_OnScroll(hwnd, hwndCtl, zDelta >= 0 ? SB_PAGEUP : SB_PAGEDOWN, 0);
+    for (i = amount; i > 0; --i)
+	gui_send_mouse_event(button, GET_X_LPARAM(param), GET_Y_LPARAM(param),
+		FALSE, kbd_modifiers);
     mch_enable_flush();
     gui_may_flush();
 }
@@ -4255,13 +4291,24 @@ set_tabline_font(void)
  * Invoked when a setting was changed.
  */
     static LRESULT CALLBACK
-_OnSettingChange(UINT n)
-{
-    if (n == SPI_SETWHEELSCROLLLINES)
-	SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
-		&mouse_scroll_lines, 0);
-    if (n == SPI_SETNONCLIENTMETRICS)
-	set_tabline_font();
+_OnSettingChange(UINT param)
+{
+    switch (param)
+    {
+	case SPI_SETWHEELSCROLLLINES:
+	    SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
+		    &mouse_scroll_lines, 0);
+	    break;
+	case SPI_GETWHEELSCROLLCHARS:
+	    SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0,
+		    &mouse_scroll_chars, 0);
+	    break;
+	case SPI_SETNONCLIENTMETRICS:
+	    set_tabline_font();
+	    break;
+	default:
+	    break;
+    }
     return 0;
 }
 
@@ -4723,7 +4770,8 @@ destroy_sizing_tip(void)
 	return _DuringSizing((UINT)wParam, (LPRECT)lParam);
 
     case WM_MOUSEWHEEL:
-	_OnMouseWheel(hwnd, HIWORD(wParam));
+    case WM_MOUSEHWHEEL:
+	_OnMouseWheel(hwnd, HIWORD(wParam), lParam, uMsg == WM_MOUSEHWHEEL);
 	return 0L;
 
 	// Notification for change in SystemParametersInfo()
--- 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 */
 /**/
+    4874,
+/**/
     4873,
 /**/
     4872,