@@ -2843,44 +2843,76 @@ trigger_winclosed(win_T *win)
28432843}
28442844
28452845/*
2846- * Trigger WinScrolled for "curwin" if needed.
2846+ * Make a snapshot of all the window scroll positions and sizes of the current
2847+ * tab page.
2848+ */
2849+ static void
2850+ snapshot_windows_scroll_size (void )
2851+ {
2852+ win_T * wp ;
2853+ FOR_ALL_WINDOWS (wp )
2854+ {
2855+ wp -> w_last_topline = wp -> w_topline ;
2856+ wp -> w_last_leftcol = wp -> w_leftcol ;
2857+ wp -> w_last_skipcol = wp -> w_skipcol ;
2858+ wp -> w_last_width = wp -> w_width ;
2859+ wp -> w_last_height = wp -> w_height ;
2860+ }
2861+ }
2862+
2863+ static int did_initial_scroll_size_snapshot = FALSE;
2864+
2865+ void
2866+ may_make_initial_scroll_size_snapshot (void )
2867+ {
2868+ if (!did_initial_scroll_size_snapshot )
2869+ {
2870+ did_initial_scroll_size_snapshot = TRUE;
2871+ snapshot_windows_scroll_size ();
2872+ }
2873+ }
2874+
2875+ /*
2876+ * Trigger WinScrolled if any window scrolled or changed size.
28472877 */
28482878 void
28492879may_trigger_winscrolled (void )
28502880{
28512881 static int recursive = FALSE;
28522882
2853- if (recursive || !has_winscrolled ())
2883+ if (recursive
2884+ || !has_winscrolled ()
2885+ || !did_initial_scroll_size_snapshot )
28542886 return ;
28552887
2856- win_T * wp = curwin ;
2857- if (wp -> w_last_topline != wp -> w_topline
2858- || wp -> w_last_leftcol != wp -> w_leftcol
2859- || wp -> w_last_skipcol != wp -> w_skipcol
2860- || wp -> w_last_width != wp -> w_width
2861- || wp -> w_last_height != wp -> w_height )
2862- {
2863- // "curwin" may be different from the actual current window, make sure
2864- // it can be restored.
2865- window_layout_lock ();
2866-
2867- recursive = TRUE;
2868- char_u winid [NUMBUFLEN ];
2869- vim_snprintf ((char * )winid , sizeof (winid ), "%d" , wp -> w_id );
2870- apply_autocmds (EVENT_WINSCROLLED , winid , winid , FALSE, wp -> w_buffer );
2871- recursive = FALSE;
2872- window_layout_unlock ();
2873-
2874- // an autocmd may close the window, "wp" may be invalid now
2875- if (win_valid_any_tab (wp ))
2888+ win_T * wp ;
2889+ FOR_ALL_WINDOWS (wp )
2890+ if (wp -> w_last_topline != wp -> w_topline
2891+ || wp -> w_last_leftcol != wp -> w_leftcol
2892+ || wp -> w_last_skipcol != wp -> w_skipcol
2893+ || wp -> w_last_width != wp -> w_width
2894+ || wp -> w_last_height != wp -> w_height )
28762895 {
2877- wp -> w_last_topline = wp -> w_topline ;
2878- wp -> w_last_leftcol = wp -> w_leftcol ;
2879- wp -> w_last_skipcol = wp -> w_skipcol ;
2880- wp -> w_last_width = wp -> w_width ;
2881- wp -> w_last_height = wp -> w_height ;
2896+ // WinScrolled is triggered only once, even when multiple windows
2897+ // scrolled or changed size. Store the current values before
2898+ // triggering the event, if a scroll or resize happens as a side
2899+ // effect then WinScrolled is triggered again later.
2900+ snapshot_windows_scroll_size ();
2901+
2902+ // "curwin" may be different from the actual current window, make
2903+ // sure it can be restored.
2904+ window_layout_lock ();
2905+
2906+ recursive = TRUE;
2907+ char_u winid [NUMBUFLEN ];
2908+ vim_snprintf ((char * )winid , sizeof (winid ), "%d" , wp -> w_id );
2909+ apply_autocmds (EVENT_WINSCROLLED , winid , winid , FALSE,
2910+ wp -> w_buffer );
2911+ recursive = FALSE;
2912+ window_layout_unlock ();
2913+
2914+ break ;
28822915 }
2883- }
28842916}
28852917
28862918/*
0 commit comments