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.