mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 9.0.0913: only change in current window triggers the WinScrolled event
Problem: Only a change in the current window triggers the WinScrolled event. Solution: Trigger WinScrolled if any window scrolled or changed size. (issue #11576)
This commit is contained in:
@@ -1372,16 +1372,32 @@ WinNew When a new window was created. Not done for
|
||||
|
||||
*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
|
||||
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}*
|
||||
|
@@ -1469,6 +1469,9 @@ main_loop(
|
||||
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)
|
||||
|
@@ -18,6 +18,7 @@ void curwin_init(void);
|
||||
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);
|
||||
|
10
src/testdir/dumps/Test_winscrolled_once_only_1.dump
Normal file
10
src/testdir/dumps/Test_winscrolled_once_only_1.dump
Normal file
@@ -0,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
|
@@ -407,11 +407,38 @@ func Test_WinScrolled_close_curwin()
|
||||
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,6 +2943,7 @@ func Test_SpellFileMissing_bwipe()
|
||||
call assert_fails('set spell spelllang=0', 'E937:')
|
||||
|
||||
au! SpellFileMissing
|
||||
set nospell spelllang=en
|
||||
bwipe
|
||||
endfunc
|
||||
|
||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
913,
|
||||
/**/
|
||||
912,
|
||||
/**/
|
||||
|
88
src/window.c
88
src/window.c
@@ -2843,44 +2843,76 @@ trigger_winclosed(win_T *win)
|
||||
}
|
||||
|
||||
/*
|
||||
* Trigger WinScrolled for "curwin" if needed.
|
||||
* 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())
|
||||
if (recursive
|
||||
|| !has_winscrolled()
|
||||
|| !did_initial_scroll_size_snapshot)
|
||||
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))
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user