summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-11-20 12:11:45 +0000
committerBram Moolenaar <Bram@vim.org>2022-11-20 12:11:45 +0000
commit29967732761d1ffb5592db5f5aa7036f5b52abf1 (patch)
tree8ce74785996d6a469d1ab29c7d0f995210f75885 /src
parent228e422855d43965f2c3319ff0cdc26ea422c10f (diff)
downloadvim-git-29967732761d1ffb5592db5f5aa7036f5b52abf1.tar.gz
patch 9.0.0915: WinScrolled may trigger immediately when definedv9.0.0915
Problem: WinScrolled may trigger immediately when defined. Solution: Initialize the fields in all windows. (closes #11582)
Diffstat (limited to 'src')
-rw-r--r--src/autocmd.c18
-rw-r--r--src/proto/window.pro3
-rw-r--r--src/testdir/dumps/Test_winscrolled_not_when_defined_1.dump10
-rw-r--r--src/testdir/dumps/Test_winscrolled_not_when_defined_2.dump10
-rw-r--r--src/testdir/test_autocmd.vim26
-rw-r--r--src/version.c2
-rw-r--r--src/window.c39
7 files changed, 93 insertions, 15 deletions
diff --git a/src/autocmd.c b/src/autocmd.c
index 8a0992c09..999ee890c 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -1264,14 +1264,20 @@ do_autocmd_event(
get_mode(last_mode);
#endif
// Initialize the fields checked by the WinScrolled trigger to
- // stop it from firing right after the first autocmd is defined.
+ // prevent it from firing right after the first autocmd is
+ // defined.
if (event == EVENT_WINSCROLLED && !has_winscrolled())
{
- curwin->w_last_topline = curwin->w_topline;
- curwin->w_last_leftcol = curwin->w_leftcol;
- curwin->w_last_skipcol = curwin->w_skipcol;
- curwin->w_last_width = curwin->w_width;
- curwin->w_last_height = curwin->w_height;
+ tabpage_T *save_curtab = curtab;
+ tabpage_T *tp;
+ FOR_ALL_TABPAGES(tp)
+ {
+ unuse_tabpage(curtab);
+ use_tabpage(tp);
+ snapshot_windows_scroll_size();
+ }
+ unuse_tabpage(curtab);
+ use_tabpage(save_curtab);
}
if (is_buflocal)
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 5141b05d4..d675b7189 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -18,12 +18,15 @@ 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 snapshot_windows_scroll_size(void);
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);
win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp);
void close_others(int message, int forceit);
+void unuse_tabpage(tabpage_T *tp);
+void use_tabpage(tabpage_T *tp);
int win_alloc_first(void);
win_T *win_alloc_popup_win(void);
void win_init_popup_win(win_T *wp, buf_T *buf);
diff --git a/src/testdir/dumps/Test_winscrolled_not_when_defined_1.dump b/src/testdir/dumps/Test_winscrolled_not_when_defined_1.dump
new file mode 100644
index 000000000..ef42464cd
--- /dev/null
+++ b/src/testdir/dumps/Test_winscrolled_not_when_defined_1.dump
@@ -0,0 +1,10 @@
+>a+0&#ffffff0@2| @56
+|b@2| @56
+|~+0#4040ff13&| @58
+|~| @58
+|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @28|1|,|1| @11|A|l@1
+|a+0&&@2| @56
+|b@2| @56
+|~+0#4040ff13&| @58
+|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @28|1|,|1| @11|A|l@1
+|:+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
diff --git a/src/testdir/dumps/Test_winscrolled_not_when_defined_2.dump b/src/testdir/dumps/Test_winscrolled_not_when_defined_2.dump
new file mode 100644
index 000000000..b5cbca404
--- /dev/null
+++ b/src/testdir/dumps/Test_winscrolled_not_when_defined_2.dump
@@ -0,0 +1,10 @@
+>b+0&#ffffff0@2| @56
+|~+0#4040ff13&| @58
+|~| @58
+|~| @58
+|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @28|2|,|1| @11|B|o|t
+|a+0&&@2| @56
+|b@2| @56
+|~+0#4040ff13&| @58
+|[+1#0000000&|N|o| |N|a|m|e|]| |[|+|]| @28|1|,|1| @11|A|l@1
+|t+0&&|r|i|g@1|e|r|e|d| @50
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 5d3e0acdb..bcd4c53d2 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -439,6 +439,32 @@ func Test_WinScrolled_once_only()
call StopVimInTerminal(buf)
endfunc
+" Check that WinScrolled is not triggered immediately when defined and there
+" are split windows.
+func Test_WinScrolled_not_when_defined()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ call setline(1, ['aaa', 'bbb'])
+ echo 'nothing happened'
+ func ShowTriggered(id)
+ echo 'triggered'
+ endfunc
+ END
+ call writefile(lines, 'Xtest_winscrolled_not', 'D')
+ let buf = RunVimInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2})
+ call term_sendkeys(buf, ":split\<CR>")
+ call TermWait(buf)
+ " use a timer to show the message after redrawing
+ call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\<CR>")
+ call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {})
+
+ call term_sendkeys(buf, "\<C-E>")
+ call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_WinScrolled_long_wrapped()
CheckRunVimInTerminal
diff --git a/src/version.c b/src/version.c
index 5347a7fdd..136521d7b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 915,
+/**/
914,
/**/
913,
diff --git a/src/window.c b/src/window.c
index b5166db6b..35be397d2 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2846,7 +2846,7 @@ trigger_winclosed(win_T *win)
* Make a snapshot of all the window scroll positions and sizes of the current
* tab page.
*/
- static void
+ void
snapshot_windows_scroll_size(void)
{
win_T *wp;
@@ -3864,6 +3864,33 @@ close_others(
}
/*
+ * Store the relevant window pointers for tab page "tp". To be used before
+ * use_tabpage().
+ */
+ void
+unuse_tabpage(tabpage_T *tp)
+{
+ tp->tp_topframe = topframe;
+ tp->tp_firstwin = firstwin;
+ tp->tp_lastwin = lastwin;
+ tp->tp_curwin = curwin;
+}
+
+/*
+ * Set the relevant pointers to use tab page "tp". May want to call
+ * unuse_tabpage() first.
+ */
+ void
+use_tabpage(tabpage_T *tp)
+{
+ curtab = tp;
+ topframe = curtab->tp_topframe;
+ firstwin = curtab->tp_firstwin;
+ lastwin = curtab->tp_lastwin;
+ curwin = curtab->tp_curwin;
+}
+
+/*
* Allocate the first window and put an empty buffer in it.
* Called from main().
* Return FAIL when something goes wrong (out of memory).
@@ -3877,11 +3904,8 @@ win_alloc_first(void)
first_tabpage = alloc_tabpage();
if (first_tabpage == NULL)
return FAIL;
- first_tabpage->tp_topframe = topframe;
curtab = first_tabpage;
- curtab->tp_firstwin = firstwin;
- curtab->tp_lastwin = lastwin;
- curtab->tp_curwin = curwin;
+ unuse_tabpage(first_tabpage);
return OK;
}
@@ -4389,10 +4413,7 @@ enter_tabpage(
win_T *next_prevwin = tp->tp_prevwin;
tabpage_T *last_tab = curtab;
- curtab = tp;
- firstwin = tp->tp_firstwin;
- lastwin = tp->tp_lastwin;
- topframe = tp->tp_topframe;
+ use_tabpage(tp);
// We would like doing the TabEnter event first, but we don't have a
// valid current window yet, which may break some commands.