@@ -1102,8 +1102,81 @@ ins_mouse(int c)
11021102}
11031103
11041104/*
1105- * Implementation for scrolling in Insert mode in direction "dir", which is one
1106- * of the MSCR_ values.
1105+ * Common mouse wheel scrolling, shared between Insert mode and NV modes.
1106+ * Default action is to scroll mouse_vert_step lines (or mouse_hor_step columns
1107+ * depending on the scroll direction) or one page when Shift or Ctrl is used.
1108+ * Direction is indicated by "cap->arg":
1109+ * K_MOUSEUP - MSCR_UP
1110+ * K_MOUSEDOWN - MSCR_DOWN
1111+ * K_MOUSELEFT - MSCR_LEFT
1112+ * K_MOUSERIGHT - MSCR_RIGHT
1113+ * "curwin" may have been changed to the window that should be scrolled and
1114+ * differ from the window that actually has focus.
1115+ */
1116+ static void
1117+ do_mousescroll (cmdarg_T * cap )
1118+ {
1119+ int shift_or_ctrl = mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL );
1120+
1121+ #ifdef FEAT_TERMINAL
1122+ if (term_use_loop ())
1123+ // This window is a terminal window, send the mouse event there.
1124+ // Set "typed" to FALSE to avoid an endless loop.
1125+ send_keys_to_term (curbuf -> b_term , cap -> cmdchar , mod_mask , FALSE);
1126+ else
1127+ #endif
1128+ if (cap -> arg == MSCR_UP || cap -> arg == MSCR_DOWN )
1129+ {
1130+ // Vertical scrolling
1131+ if (!(State & MODE_INSERT ) && (mouse_vert_step < 0 || shift_or_ctrl ))
1132+ {
1133+ // whole page up or down
1134+ onepage (cap -> arg == MSCR_UP ? FORWARD : BACKWARD , 1L );
1135+ }
1136+ else
1137+ {
1138+ if (mouse_vert_step < 0 || shift_or_ctrl )
1139+ {
1140+ // whole page up or down
1141+ cap -> count1 = (long )(curwin -> w_botline - curwin -> w_topline );
1142+ }
1143+ // Don't scroll more than half the window height.
1144+ else if (curwin -> w_height < mouse_vert_step * 2 )
1145+ {
1146+ cap -> count1 = curwin -> w_height / 2 ;
1147+ if (cap -> count1 == 0 )
1148+ cap -> count1 = 1 ;
1149+ }
1150+ else
1151+ {
1152+ cap -> count1 = mouse_vert_step ;
1153+ }
1154+ cap -> count0 = cap -> count1 ;
1155+ nv_scroll_line (cap );
1156+ }
1157+
1158+ #ifdef FEAT_PROP_POPUP
1159+ if (WIN_IS_POPUP (curwin ))
1160+ popup_set_firstline (curwin );
1161+ #endif
1162+ }
1163+ else
1164+ {
1165+ // Horizontal scrolling
1166+ long step = (mouse_hor_step < 0 || shift_or_ctrl )
1167+ ? curwin -> w_width : mouse_hor_step ;
1168+ long leftcol = curwin -> w_leftcol
1169+ + (cap -> arg == MSCR_RIGHT ? - step : step );
1170+ if (leftcol < 0 )
1171+ leftcol = 0 ;
1172+ do_mousescroll_horiz ((long_u )leftcol );
1173+ }
1174+ may_trigger_winscrolled ();
1175+ }
1176+
1177+ /*
1178+ * Insert mode implementation for scrolling in direction "dir", which is
1179+ * one of the MSCR_ values.
11071180 */
11081181 void
11091182ins_mousescroll (int dir )
@@ -1133,18 +1206,23 @@ ins_mousescroll(int dir)
11331206 siemsg ("Invalid ins_mousescroll() argument: %d" , dir );
11341207 }
11351208
1136- win_T * wp = curwin ;
1209+ win_T * old_curwin = curwin ;
11371210 if (mouse_row >= 0 && mouse_col >= 0 )
11381211 {
11391212 // Find the window at the mouse pointer coordinates.
1213+ // NOTE: Must restore "curwin" to "old_curwin" before returning!
11401214 int row = mouse_row ;
11411215 int col = mouse_col ;
1142- wp = mouse_find_win (& row , & col , FIND_POPUP );
1143- if (wp == NULL )
1216+ curwin = mouse_find_win (& row , & col , FIND_POPUP );
1217+ if (curwin == NULL )
1218+ {
1219+ curwin = old_curwin ;
11441220 return ;
1221+ }
1222+ curbuf = curwin -> w_buffer ;
11451223 }
11461224
1147- if (wp == curwin )
1225+ if (curwin == old_curwin )
11481226 {
11491227 // Don't scroll the current window if the popup menu is visible.
11501228 if (pum_visible ())
@@ -1153,17 +1231,23 @@ ins_mousescroll(int dir)
11531231 undisplay_dollar ();
11541232 }
11551233
1156- linenr_T orig_topline = wp -> w_topline ;
1157- colnr_T orig_leftcol = wp -> w_leftcol ;
1234+ linenr_T orig_topline = curwin -> w_topline ;
1235+ colnr_T orig_leftcol = curwin -> w_leftcol ;
11581236 pos_T orig_cursor = curwin -> w_cursor ;
11591237
1160- // The scrolling works almost the same way as in Normal mode.
1161- nv_mousescroll (& cap );
1238+ // Call the common mouse scroll function shared with other modes.
1239+ do_mousescroll (& cap );
1240+
1241+ int did_scroll = (orig_topline != curwin -> w_topline
1242+ || orig_leftcol != curwin -> w_leftcol );
1243+
1244+ curwin -> w_redr_status = TRUE;
1245+ curwin = old_curwin ;
1246+ curbuf = curwin -> w_buffer ;
11621247
11631248 // If the window actually scrolled and the popup menu may overlay the
11641249 // window, need to redraw it.
1165- if ((orig_topline != wp -> w_topline || orig_leftcol != wp -> w_leftcol )
1166- && pum_visible ())
1250+ if (did_scroll && pum_visible ())
11671251 {
11681252 // TODO: Would be more efficient to only redraw the windows that are
11691253 // overlapped by the popup menu.
@@ -2094,14 +2178,8 @@ do_mousescroll_horiz(long_u leftcol)
20942178}
20952179
20962180/*
2097- * Mouse scroll wheel: Default action is to scroll mouse_vert_step lines (or
2098- * mouse_hor_step, depending on the scroll direction), or one page when Shift
2099- * or Ctrl is used.
2100- * Direction is indicated by "cap->arg":
2101- * K_MOUSEUP - MSCR_UP
2102- * K_MOUSEDOWN - MSCR_DOWN
2103- * K_MOUSELEFT - MSCR_LEFT
2104- * K_MOUSERIGHT - MSCR_RIGHT
2181+ * Normal and Visual modes implementation for scrolling in direction
2182+ * "cap->arg", which is one of the MSCR_ values.
21052183 */
21062184 void
21072185nv_mousescroll (cmdarg_T * cap )
@@ -2111,85 +2189,35 @@ nv_mousescroll(cmdarg_T *cap)
21112189 if (mouse_row >= 0 && mouse_col >= 0 )
21122190 {
21132191 // Find the window at the mouse pointer coordinates.
2192+ // NOTE: Must restore "curwin" to "old_curwin" before returning!
21142193 int row = mouse_row ;
21152194 int col = mouse_col ;
2116- win_T * wp = mouse_find_win (& row , & col , FIND_POPUP );
2117- if (wp == NULL )
2195+ curwin = mouse_find_win (& row , & col , FIND_POPUP );
2196+ if (curwin == NULL )
2197+ {
2198+ curwin = old_curwin ;
21182199 return ;
2200+ }
2201+
21192202#ifdef FEAT_PROP_POPUP
2120- if (WIN_IS_POPUP (wp ) && !wp -> w_has_scrollbar )
2203+ if (WIN_IS_POPUP (curwin ) && !curwin -> w_has_scrollbar )
2204+ {
21212205 // cannot scroll this popup window
2206+ curwin = old_curwin ;
21222207 return ;
2208+ }
21232209#endif
2124- // NOTE: Must restore "curwin" to "old_curwin" before returning!
2125- curwin = wp ;
21262210 curbuf = curwin -> w_buffer ;
21272211 }
21282212
2129- int shift_or_ctrl = mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL );
2130-
2131- #ifdef FEAT_TERMINAL
2132- if (term_use_loop ())
2133- // This window is a terminal window, send the mouse event there.
2134- // Set "typed" to FALSE to avoid an endless loop.
2135- send_keys_to_term (curbuf -> b_term , cap -> cmdchar , mod_mask , FALSE);
2136- else
2137- #endif
2138- if (cap -> arg == MSCR_UP || cap -> arg == MSCR_DOWN )
2139- {
2140- // Vertical scrolling
2141- if (!(State & MODE_INSERT ) && (mouse_vert_step < 0 || shift_or_ctrl ))
2142- {
2143- // whole page up or down
2144- onepage (cap -> arg == MSCR_UP ? FORWARD : BACKWARD , 1L );
2145- }
2146- else
2147- {
2148- if (mouse_vert_step < 0 || shift_or_ctrl )
2149- {
2150- // whole page up or down
2151- cap -> count1 = (long )(curwin -> w_botline - curwin -> w_topline );
2152- }
2153- // Don't scroll more than half the window height.
2154- else if (curwin -> w_height < mouse_vert_step * 2 )
2155- {
2156- cap -> count1 = curwin -> w_height / 2 ;
2157- if (cap -> count1 == 0 )
2158- cap -> count1 = 1 ;
2159- }
2160- else
2161- {
2162- cap -> count1 = mouse_vert_step ;
2163- }
2164- cap -> count0 = cap -> count1 ;
2165- nv_scroll_line (cap );
2166- }
2167-
2168- #ifdef FEAT_PROP_POPUP
2169- if (WIN_IS_POPUP (curwin ))
2170- popup_set_firstline (curwin );
2171- #endif
2172- }
2173- else
2174- {
2175- // Horizontal scrolling
2176- long step = (mouse_hor_step < 0 || shift_or_ctrl )
2177- ? curwin -> w_width : mouse_hor_step ;
2178- long leftcol = curwin -> w_leftcol
2179- + (cap -> arg == MSCR_RIGHT ? - step : step );
2180- if (leftcol < 0 )
2181- leftcol = 0 ;
2182- do_mousescroll_horiz ((long_u )leftcol );
2183- }
2213+ // Call the common mouse scroll function shared with other modes.
2214+ do_mousescroll (cap );
21842215
21852216#ifdef FEAT_SYN_HL
21862217 if (curwin != old_curwin && curwin -> w_p_cul )
21872218 redraw_for_cursorline (curwin );
21882219#endif
2189- may_trigger_winscrolled ();
2190-
21912220 curwin -> w_redr_status = TRUE;
2192-
21932221 curwin = old_curwin ;
21942222 curbuf = curwin -> w_buffer ;
21952223}
0 commit comments