Patch 9.0.0913
Problem:    Only a change in the current window triggers the WinScrolled
            event.
Solution:   Trigger WinScrolled if any window scrolled or changed size.
            (issue #11576)
Files:      runtime/doc/autocmd.txt, src/window.c, src/proto/window.pro,
            src/main.c, src/testdir/test_autocmd.vim,
            src/testdir/dumps/Test_winscrolled_once_only_1.dump


*** ../vim-9.0.0912/runtime/doc/autocmd.txt     2022-10-15 11:47:54.213416782 
+0100
--- runtime/doc/autocmd.txt     2022-11-19 21:05:58.892154099 +0000
***************
*** 1370,1385 ****
  
                                                        *WinScrolled*
  WinScrolled                   After scrolling the content of a window or
!                               resizing a window.
!                               The pattern is matched against the
!                               |window-ID|.  Both <amatch> and <afile> are
!                               set to the |window-ID|.
!                               Non-recursive (the event cannot trigger
!                               itself).  However, if the command causes the
!                               window to scroll or change size another
                                WinScrolled event will be triggered later.
                                Does not trigger when the command is added,
                                only after the first scroll or resize.
  
  ==============================================================================
  6. Patterns                                   *autocmd-patterns* *{aupat}*
--- 1372,1403 ----
  
                                                        *WinScrolled*
  WinScrolled                   After scrolling the content of a window or
!                               resizing a window in the current tab page.
! 
!                               When more than one window scrolled or resized
!                               only one WinScrolled event is triggered.  You
!                               can use the `winlayout()` and `getwininfo()`
!                               functions to see what changed.
! 
!                               The pattern is matched against the |window-ID|
!                               of the first window that scrolled or resized.
!                               Both <amatch> and <afile> are set to the
!                               |window-ID|.
! 
!                               Only starts triggering after startup finished
!                               and the first screen redraw was done.
! 
!                               Non-recursive: the event will not trigger
!                               while executing commands for the WinScrolled
!                               event.  However, if the command causes a
!                               window to scroll or change size, then another
                                WinScrolled event will be triggered later.
+ 
                                Does not trigger when the command is added,
                                only after the first scroll or resize.
+                                                       *E1312*
+                               It is not allowed to change the window layout
+                               here (split, close or move windows).
  
  ==============================================================================
  6. Patterns                                   *autocmd-patterns* *{aupat}*
*** ../vim-9.0.0912/src/window.c        2022-11-19 13:14:05.741367062 +0000
--- src/window.c        2022-11-19 20:40:31.104818992 +0000
***************
*** 2843,2886 ****
  }
  
  /*
!  * Trigger WinScrolled for "curwin" if needed.
   */
      void
  may_trigger_winscrolled(void)
  {
      static int            recursive = FALSE;
  
!     if (recursive || !has_winscrolled())
        return;
  
!     win_T *wp = curwin;
!     if (wp->w_last_topline != wp->w_topline
!           || wp->w_last_leftcol != wp->w_leftcol
!           || wp->w_last_skipcol != wp->w_skipcol
!           || wp->w_last_width != wp->w_width
!           || wp->w_last_height != wp->w_height)
!     {
!       // "curwin" may be different from the actual current window, make sure
!       // it can be restored.
!       window_layout_lock();
! 
!       recursive = TRUE;
!       char_u winid[NUMBUFLEN];
!       vim_snprintf((char *)winid, sizeof(winid), "%d", wp->w_id);
!       apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, wp->w_buffer);
!       recursive = FALSE;
!       window_layout_unlock();
! 
!       // an autocmd may close the window, "wp" may be invalid now
!       if (win_valid_any_tab(wp))
        {
!           wp->w_last_topline = wp->w_topline;
!           wp->w_last_leftcol = wp->w_leftcol;
!           wp->w_last_skipcol = wp->w_skipcol;
!           wp->w_last_width = wp->w_width;
!           wp->w_last_height = wp->w_height;
        }
-     }
  }
  
  /*
--- 2843,2918 ----
  }
  
  /*
!  * Make a snapshot of all the window scroll positions and sizes of the current
!  * tab page.
!  */
!     static void
! snapshot_windows_scroll_size(void)
! {
!     win_T *wp;
!     FOR_ALL_WINDOWS(wp)
!     {
!       wp->w_last_topline = wp->w_topline;
!       wp->w_last_leftcol = wp->w_leftcol;
!       wp->w_last_skipcol = wp->w_skipcol;
!       wp->w_last_width = wp->w_width;
!       wp->w_last_height = wp->w_height;
!     }
! }
! 
! static int did_initial_scroll_size_snapshot = FALSE;
! 
!     void
! may_make_initial_scroll_size_snapshot(void)
! {
!     if (!did_initial_scroll_size_snapshot)
!     {
!       did_initial_scroll_size_snapshot = TRUE;
!       snapshot_windows_scroll_size();
!     }
! }
! 
! /*
!  * Trigger WinScrolled if any window scrolled or changed size.
   */
      void
  may_trigger_winscrolled(void)
  {
      static int            recursive = FALSE;
  
!     if (recursive
!           || !has_winscrolled()
!           || !did_initial_scroll_size_snapshot)
        return;
  
!     win_T *wp;
!     FOR_ALL_WINDOWS(wp)
!       if (wp->w_last_topline != wp->w_topline
!               || wp->w_last_leftcol != wp->w_leftcol
!               || wp->w_last_skipcol != wp->w_skipcol
!               || wp->w_last_width != wp->w_width
!               || wp->w_last_height != wp->w_height)
        {
!           // WinScrolled is triggered only once, even when multiple windows
!           // scrolled or changed size.  Store the current values before
!           // triggering the event, if a scroll or resize happens as a side
!           // effect then WinScrolled is triggered again later.
!           snapshot_windows_scroll_size();
! 
!           // "curwin" may be different from the actual current window, make
!           // sure it can be restored.
!           window_layout_lock();
! 
!           recursive = TRUE;
!           char_u winid[NUMBUFLEN];
!           vim_snprintf((char *)winid, sizeof(winid), "%d", wp->w_id);
!           apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE,
!                                                                wp->w_buffer);
!           recursive = FALSE;
!           window_layout_unlock();
! 
!           break;
        }
  }
  
  /*
*** ../vim-9.0.0912/src/proto/window.pro        2022-11-19 13:14:05.741367062 
+0000
--- src/proto/window.pro        2022-11-19 20:34:36.729047134 +0000
***************
*** 18,23 ****
--- 18,24 ----
  void close_windows(buf_T *buf, int keep_curwin);
  int one_window(void);
  int win_close(win_T *win, int free_buf);
+ void may_make_initial_scroll_size_snapshot(void);
  void may_trigger_winscrolled(void);
  void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp);
  void win_free_all(void);
*** ../vim-9.0.0912/src/main.c  2022-11-09 16:29:20.396373252 +0000
--- src/main.c  2022-11-19 20:32:40.889122817 +0000
***************
*** 1469,1474 ****
--- 1469,1477 ----
                time_fd = NULL;
            }
  #endif
+           // After the first screen update may start triggering WinScrolled
+           // autocmd events.  Store all the scroll positions and sizes now.
+           may_make_initial_scroll_size_snapshot();
        }
  #ifdef FEAT_GUI
        if (need_mouse_correct)
*** ../vim-9.0.0912/src/testdir/test_autocmd.vim        2022-11-19 
13:14:05.741367062 +0000
--- src/testdir/test_autocmd.vim        2022-11-19 21:14:30.645003458 +0000
***************
*** 407,417 ****
    call TermWait(buf)
    call StopVimInTerminal(buf)
  
    call assert_equal(['123456'], readfile('Xtestout'))
- 
    call delete('Xtestout')
  endfunc
  
  func Test_WinScrolled_long_wrapped()
    CheckRunVimInTerminal
  
--- 407,444 ----
    call TermWait(buf)
    call StopVimInTerminal(buf)
  
+   " check the startup script finished to the end
    call assert_equal(['123456'], readfile('Xtestout'))
    call delete('Xtestout')
  endfunc
  
+ func Test_WinScrolled_once_only()
+   CheckRunVimInTerminal
+ 
+   let lines =<< trim END
+       set cmdheight=2
+       call setline(1, ['aaa', 'bbb'])
+       let trigger_count = 0
+       func ShowInfo(id)
+         echo g:trigger_count g:winid winlayout()
+       endfunc
+ 
+       vsplit
+       split
+       " use a timer to show the info after a redraw
+       au WinScrolled * let trigger_count += 1 | let winid = 
expand('<amatch>') | call timer_start(100, 'ShowInfo')
+       wincmd j
+       wincmd l
+   END
+   call writefile(lines, 'Xtest_winscrolled_once', 'D')
+   let buf = RunVimInTerminal('-S Xtest_winscrolled_once', #{rows: 10, cols: 
60, statusoff: 2})
+ 
+   call term_sendkeys(buf, "\<C-E>")
+   call VerifyScreenDump(buf, 'Test_winscrolled_once_only_1', {})
+ 
+   call StopVimInTerminal(buf)
+ endfunc
+ 
  func Test_WinScrolled_long_wrapped()
    CheckRunVimInTerminal
  
***************
*** 2916,2921 ****
--- 2943,2949 ----
    call assert_fails('set spell spelllang=0', 'E937:')
  
    au! SpellFileMissing
+   set nospell spelllang=en
    bwipe
  endfunc
  
*** ../vim-9.0.0912/src/testdir/dumps/Test_winscrolled_once_only_1.dump 
2022-11-19 21:16:34.589147332 +0000
--- src/testdir/dumps/Test_winscrolled_once_only_1.dump 2022-11-19 
21:13:25.048920276 +0000
***************
*** 0 ****
--- 1,10 ----
+ |a+0&#ffffff0@2| @26||+1&&>b+0&&@2| @25
+ |b@2| @26||+1&&|~+0#4040ff13&| @27
+ |~| @28||+1#0000000&|~+0#4040ff13&| @27
+ |[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1| @8|A|l@1|||~+0#4040ff13&| @27
+ |a+0#0000000&@2| @26||+1&&|~+0#4040ff13&| @27
+ |b+0#0000000&@2| @26||+1&&|~+0#4040ff13&| @27
+ |~| @28||+1#0000000&|~+0#4040ff13&| @27
+ |[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @1|1|,|1| @8|A|l@1| |[+3&&|N|o| 
|N|a|m|e|]| |[|+|]| @1|2|,|1| @7|B|o|t
+ |1+0&&| |1|0@2| |[|'|r|o|w|'|,| |[@1|'|c|o|l|'|,| |[@1|'|l|e|a|f|'|,| 
|1|0@1|2|]|,| |[|'|l|e|a|f|'|,| |1|0@1|1|]@2|,| |[
+ |'|l|e|a|f|'|,| |1|0@2|]@2| @44
*** ../vim-9.0.0912/src/version.c       2022-11-19 19:02:33.957452667 +0000
--- src/version.c       2022-11-19 20:05:58.618459708 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     913,
  /**/

-- 
I AM THANKFUL...
...for the piles of laundry and ironing because it means I
have plenty of clothes to wear.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221119211837.B7EF91C12B2%40moolenaar.net.

Raspunde prin e-mail lui