Skip to content

Commit 2996773

Browse files
committed
patch 9.0.0915: WinScrolled may trigger immediately when defined
Problem: WinScrolled may trigger immediately when defined. Solution: Initialize the fields in all windows. (closes #11582)
1 parent 228e422 commit 2996773

7 files changed

Lines changed: 93 additions & 15 deletions

File tree

src/autocmd.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,14 +1264,20 @@ do_autocmd_event(
12641264
get_mode(last_mode);
12651265
#endif
12661266
// Initialize the fields checked by the WinScrolled trigger to
1267-
// stop it from firing right after the first autocmd is defined.
1267+
// prevent it from firing right after the first autocmd is
1268+
// defined.
12681269
if (event == EVENT_WINSCROLLED && !has_winscrolled())
12691270
{
1270-
curwin->w_last_topline = curwin->w_topline;
1271-
curwin->w_last_leftcol = curwin->w_leftcol;
1272-
curwin->w_last_skipcol = curwin->w_skipcol;
1273-
curwin->w_last_width = curwin->w_width;
1274-
curwin->w_last_height = curwin->w_height;
1271+
tabpage_T *save_curtab = curtab;
1272+
tabpage_T *tp;
1273+
FOR_ALL_TABPAGES(tp)
1274+
{
1275+
unuse_tabpage(curtab);
1276+
use_tabpage(tp);
1277+
snapshot_windows_scroll_size();
1278+
}
1279+
unuse_tabpage(curtab);
1280+
use_tabpage(save_curtab);
12751281
}
12761282

12771283
if (is_buflocal)

src/proto/window.pro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ void curwin_init(void);
1818
void close_windows(buf_T *buf, int keep_curwin);
1919
int one_window(void);
2020
int win_close(win_T *win, int free_buf);
21+
void snapshot_windows_scroll_size(void);
2122
void may_make_initial_scroll_size_snapshot(void);
2223
void may_trigger_winscrolled(void);
2324
void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp);
2425
void win_free_all(void);
2526
win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp);
2627
void close_others(int message, int forceit);
28+
void unuse_tabpage(tabpage_T *tp);
29+
void use_tabpage(tabpage_T *tp);
2730
int win_alloc_first(void);
2831
win_T *win_alloc_popup_win(void);
2932
void win_init_popup_win(win_T *wp, buf_T *buf);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
>a+0&#ffffff0@2| @56
2+
|b@2| @56
3+
|~+0#4040ff13&| @58
4+
|~| @58
5+
|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @28|1|,|1| @11|A|l@1
6+
|a+0&&@2| @56
7+
|b@2| @56
8+
|~+0#4040ff13&| @58
9+
|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @28|1|,|1| @11|A|l@1
10+
|:+0&&|a|u| |W|i|n|S|c|r|o|l@1|e|d| |*| |c|a|l@1| |t|i|m|e|r|_|s|t|a|r|t|(|1|0@1|,| |'|S|h|o|w|T|r|i|g@1|e|r|e|d|'|)| @3
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
>b+0&#ffffff0@2| @56
2+
|~+0#4040ff13&| @58
3+
|~| @58
4+
|~| @58
5+
|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @28|2|,|1| @11|B|o|t
6+
|a+0&&@2| @56
7+
|b@2| @56
8+
|~+0#4040ff13&| @58
9+
|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @28|1|,|1| @11|A|l@1
10+
|t+0&&|r|i|g@1|e|r|e|d| @50

src/testdir/test_autocmd.vim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,32 @@ func Test_WinScrolled_once_only()
439439
call StopVimInTerminal(buf)
440440
endfunc
441441

442+
" Check that WinScrolled is not triggered immediately when defined and there
443+
" are split windows.
444+
func Test_WinScrolled_not_when_defined()
445+
CheckRunVimInTerminal
446+
447+
let lines =<< trim END
448+
call setline(1, ['aaa', 'bbb'])
449+
echo 'nothing happened'
450+
func ShowTriggered(id)
451+
echo 'triggered'
452+
endfunc
453+
END
454+
call writefile(lines, 'Xtest_winscrolled_not', 'D')
455+
let buf = RunVimInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2})
456+
call term_sendkeys(buf, ":split\<CR>")
457+
call TermWait(buf)
458+
" use a timer to show the message after redrawing
459+
call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\<CR>")
460+
call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {})
461+
462+
call term_sendkeys(buf, "\<C-E>")
463+
call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {})
464+
465+
call StopVimInTerminal(buf)
466+
endfunc
467+
442468
func Test_WinScrolled_long_wrapped()
443469
CheckRunVimInTerminal
444470

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
915,
698700
/**/
699701
914,
700702
/**/

src/window.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2846,7 +2846,7 @@ trigger_winclosed(win_T *win)
28462846
* Make a snapshot of all the window scroll positions and sizes of the current
28472847
* tab page.
28482848
*/
2849-
static void
2849+
void
28502850
snapshot_windows_scroll_size(void)
28512851
{
28522852
win_T *wp;
@@ -3863,6 +3863,33 @@ close_others(
38633863
emsg(_(e_other_window_contains_changes));
38643864
}
38653865

3866+
/*
3867+
* Store the relevant window pointers for tab page "tp". To be used before
3868+
* use_tabpage().
3869+
*/
3870+
void
3871+
unuse_tabpage(tabpage_T *tp)
3872+
{
3873+
tp->tp_topframe = topframe;
3874+
tp->tp_firstwin = firstwin;
3875+
tp->tp_lastwin = lastwin;
3876+
tp->tp_curwin = curwin;
3877+
}
3878+
3879+
/*
3880+
* Set the relevant pointers to use tab page "tp". May want to call
3881+
* unuse_tabpage() first.
3882+
*/
3883+
void
3884+
use_tabpage(tabpage_T *tp)
3885+
{
3886+
curtab = tp;
3887+
topframe = curtab->tp_topframe;
3888+
firstwin = curtab->tp_firstwin;
3889+
lastwin = curtab->tp_lastwin;
3890+
curwin = curtab->tp_curwin;
3891+
}
3892+
38663893
/*
38673894
* Allocate the first window and put an empty buffer in it.
38683895
* Called from main().
@@ -3877,11 +3904,8 @@ win_alloc_first(void)
38773904
first_tabpage = alloc_tabpage();
38783905
if (first_tabpage == NULL)
38793906
return FAIL;
3880-
first_tabpage->tp_topframe = topframe;
38813907
curtab = first_tabpage;
3882-
curtab->tp_firstwin = firstwin;
3883-
curtab->tp_lastwin = lastwin;
3884-
curtab->tp_curwin = curwin;
3908+
unuse_tabpage(first_tabpage);
38853909

38863910
return OK;
38873911
}
@@ -4389,10 +4413,7 @@ enter_tabpage(
43894413
win_T *next_prevwin = tp->tp_prevwin;
43904414
tabpage_T *last_tab = curtab;
43914415

4392-
curtab = tp;
4393-
firstwin = tp->tp_firstwin;
4394-
lastwin = tp->tp_lastwin;
4395-
topframe = tp->tp_topframe;
4416+
use_tabpage(tp);
43964417

43974418
// We would like doing the TabEnter event first, but we don't have a
43984419
// valid current window yet, which may break some commands.

0 commit comments

Comments
 (0)