]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.0915: WinScrolled may trigger immediately when defined v9.0.0915
authorBram Moolenaar <Bram@vim.org>
Sun, 20 Nov 2022 12:11:45 +0000 (12:11 +0000)
committerBram Moolenaar <Bram@vim.org>
Sun, 20 Nov 2022 12:11:45 +0000 (12:11 +0000)
Problem:    WinScrolled may trigger immediately when defined.
Solution:   Initialize the fields in all windows. (closes #11582)

src/autocmd.c
src/proto/window.pro
src/testdir/dumps/Test_winscrolled_not_when_defined_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_winscrolled_not_when_defined_2.dump [new file with mode: 0644]
src/testdir/test_autocmd.vim
src/version.c
src/window.c

index 8a0992c092e973ec27497ca588f271a7b98daea9..999ee890cbdc7f43e2fa468218f8bd67304dcafd 100644 (file)
@@ -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)
index 5141b05d43f9e497733037a31491a5bbea607a6b..d675b71891a7cccfed8d6da8991f8fd06db61cdb 100644 (file)
@@ -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 (file)
index 0000000..ef42464
--- /dev/null
@@ -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 (file)
index 0000000..b5cbca4
--- /dev/null
@@ -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
index 5d3e0acdbe2d6974632194c435df93f215ee7a45..bcd4c53d2af40c4fd346562d33fd687f0cb846c3 100644 (file)
@@ -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
 
index 5347a7fddf4e537448ed8655601683e2a74e07d5..136521d7b465ac3042e927fd15c4977a69470c94 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    915,
 /**/
     914,
 /**/
index b5166db6b8c790739621b4cf7ecb98b1ef431deb..35be397d2ce3d712ee00c44dd9e6e06f8de3f5a6 100644 (file)
@@ -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;
@@ -3863,6 +3863,33 @@ close_others(
        emsg(_(e_other_window_contains_changes));
 }
 
+/*
+ * 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().
@@ -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.