patch 9.1.1084: Unable to persistently ignore events in a window and its buffers

Problem:  Unable to persistently ignore events in a window and its buffers.
Solution: Add 'eventignorewin' option to ignore events in a window and buffer
          (Luuk van Baal)

Add the window-local 'eventignorewin' option that is analogous to
'eventignore', but applies to a certain window and its buffers. Identify
events that should be allowed in 'eventignorewin', adapt "auto_event"
and "event_tab" to encode this information. Window context is not passed
onto apply_autocmds_group(), and when to ignore an event is a bit
ambiguous when "buf" is not "curbuf", rather than a large refactor, only
ignore an event when all windows into "buf" are ignoring the event.

closes: #16530

Signed-off-by: Luuk van Baal <luukvbaal@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/autocmd.c b/src/autocmd.c
index 330db42..aa18087 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -82,30 +82,31 @@
 #define BUFNEWFILE_INDEX 9
 #define BUFREAD_INDEX 10
 
-// must be sorted by the 'value' field because it is used by bsearch()!
-static keyvalue_T event_tab[] = {
-    KEYVALUE_ENTRY(EVENT_BUFADD, "BufAdd"),
-    KEYVALUE_ENTRY(EVENT_BUFADD, "BufCreate"),
-    KEYVALUE_ENTRY(EVENT_BUFDELETE, "BufDelete"),
-    KEYVALUE_ENTRY(EVENT_BUFENTER, "BufEnter"),
-    KEYVALUE_ENTRY(EVENT_BUFFILEPOST, "BufFilePost"),
-    KEYVALUE_ENTRY(EVENT_BUFFILEPRE, "BufFilePre"),
-    KEYVALUE_ENTRY(EVENT_BUFHIDDEN, "BufHidden"),
-    KEYVALUE_ENTRY(EVENT_BUFLEAVE, "BufLeave"),
-    KEYVALUE_ENTRY(EVENT_BUFNEW, "BufNew"),
-    KEYVALUE_ENTRY(EVENT_BUFNEWFILE, "BufNewFile"),	// BUFNEWFILE_INDEX
-    KEYVALUE_ENTRY(EVENT_BUFREADPOST, "BufRead"),	// BUFREAD_INDEX
-    KEYVALUE_ENTRY(EVENT_BUFREADCMD, "BufReadCmd"),
-    KEYVALUE_ENTRY(EVENT_BUFREADPOST, "BufReadPost"),
-    KEYVALUE_ENTRY(EVENT_BUFREADPRE, "BufReadPre"),
-    KEYVALUE_ENTRY(EVENT_BUFUNLOAD, "BufUnload"),
-    KEYVALUE_ENTRY(EVENT_BUFWINENTER, "BufWinEnter"),
-    KEYVALUE_ENTRY(EVENT_BUFWINLEAVE, "BufWinLeave"),
-    KEYVALUE_ENTRY(EVENT_BUFWIPEOUT, "BufWipeout"),
-    KEYVALUE_ENTRY(EVENT_BUFWRITEPRE, "BufWrite"),
-    KEYVALUE_ENTRY(EVENT_BUFWRITECMD, "BufWriteCmd"),
-    KEYVALUE_ENTRY(EVENT_BUFWRITEPOST, "BufWritePost"),
-    KEYVALUE_ENTRY(EVENT_BUFWRITEPRE, "BufWritePre"),
+// Must be sorted by the 'value' field because it is used by bsearch()!
+// Events with positive keys aren't allowed in 'eventignorewin'.
+static keyvalue_T event_tab[NUM_EVENTS] = {
+    KEYVALUE_ENTRY(-EVENT_BUFADD, "BufAdd"),
+    KEYVALUE_ENTRY(-EVENT_BUFADD, "BufCreate"),
+    KEYVALUE_ENTRY(-EVENT_BUFDELETE, "BufDelete"),
+    KEYVALUE_ENTRY(-EVENT_BUFENTER, "BufEnter"),
+    KEYVALUE_ENTRY(-EVENT_BUFFILEPOST, "BufFilePost"),
+    KEYVALUE_ENTRY(-EVENT_BUFFILEPRE, "BufFilePre"),
+    KEYVALUE_ENTRY(-EVENT_BUFHIDDEN, "BufHidden"),
+    KEYVALUE_ENTRY(-EVENT_BUFLEAVE, "BufLeave"),
+    KEYVALUE_ENTRY(-EVENT_BUFNEW, "BufNew"),
+    KEYVALUE_ENTRY(-EVENT_BUFNEWFILE, "BufNewFile"),	// BUFNEWFILE_INDEX
+    KEYVALUE_ENTRY(-EVENT_BUFREADPOST, "BufRead"),	// BUFREAD_INDEX
+    KEYVALUE_ENTRY(-EVENT_BUFREADCMD, "BufReadCmd"),
+    KEYVALUE_ENTRY(-EVENT_BUFREADPOST, "BufReadPost"),
+    KEYVALUE_ENTRY(-EVENT_BUFREADPRE, "BufReadPre"),
+    KEYVALUE_ENTRY(-EVENT_BUFUNLOAD, "BufUnload"),
+    KEYVALUE_ENTRY(-EVENT_BUFWINENTER, "BufWinEnter"),
+    KEYVALUE_ENTRY(-EVENT_BUFWINLEAVE, "BufWinLeave"),
+    KEYVALUE_ENTRY(-EVENT_BUFWIPEOUT, "BufWipeout"),
+    KEYVALUE_ENTRY(-EVENT_BUFWRITEPRE, "BufWrite"),
+    KEYVALUE_ENTRY(-EVENT_BUFWRITECMD, "BufWriteCmd"),
+    KEYVALUE_ENTRY(-EVENT_BUFWRITEPOST, "BufWritePost"),
+    KEYVALUE_ENTRY(-EVENT_BUFWRITEPRE, "BufWritePre"),
     KEYVALUE_ENTRY(EVENT_CMDLINECHANGED, "CmdlineChanged"),
     KEYVALUE_ENTRY(EVENT_CMDLINEENTER, "CmdlineEnter"),
     KEYVALUE_ENTRY(EVENT_CMDLINELEAVE, "CmdlineLeave"),
@@ -117,44 +118,44 @@
     KEYVALUE_ENTRY(EVENT_COMPLETECHANGED, "CompleteChanged"),
     KEYVALUE_ENTRY(EVENT_COMPLETEDONE, "CompleteDone"),
     KEYVALUE_ENTRY(EVENT_COMPLETEDONEPRE, "CompleteDonePre"),
-    KEYVALUE_ENTRY(EVENT_CURSORHOLD, "CursorHold"),
-    KEYVALUE_ENTRY(EVENT_CURSORHOLDI, "CursorHoldI"),
-    KEYVALUE_ENTRY(EVENT_CURSORMOVED, "CursorMoved"),
-    KEYVALUE_ENTRY(EVENT_CURSORMOVEDC, "CursorMovedC"),
-    KEYVALUE_ENTRY(EVENT_CURSORMOVEDI, "CursorMovedI"),
+    KEYVALUE_ENTRY(-EVENT_CURSORHOLD, "CursorHold"),
+    KEYVALUE_ENTRY(-EVENT_CURSORHOLDI, "CursorHoldI"),
+    KEYVALUE_ENTRY(-EVENT_CURSORMOVED, "CursorMoved"),
+    KEYVALUE_ENTRY(-EVENT_CURSORMOVEDC, "CursorMovedC"),
+    KEYVALUE_ENTRY(-EVENT_CURSORMOVEDI, "CursorMovedI"),
     KEYVALUE_ENTRY(EVENT_DIFFUPDATED, "DiffUpdated"),
     KEYVALUE_ENTRY(EVENT_DIRCHANGED, "DirChanged"),
     KEYVALUE_ENTRY(EVENT_DIRCHANGEDPRE, "DirChangedPre"),
     KEYVALUE_ENTRY(EVENT_ENCODINGCHANGED, "EncodingChanged"),
     KEYVALUE_ENTRY(EVENT_EXITPRE, "ExitPre"),
-    KEYVALUE_ENTRY(EVENT_FILEAPPENDCMD, "FileAppendCmd"),
-    KEYVALUE_ENTRY(EVENT_FILEAPPENDPOST, "FileAppendPost"),
-    KEYVALUE_ENTRY(EVENT_FILEAPPENDPRE, "FileAppendPre"),
-    KEYVALUE_ENTRY(EVENT_FILECHANGEDRO, "FileChangedRO"),
-    KEYVALUE_ENTRY(EVENT_FILECHANGEDSHELL, "FileChangedShell"),
-    KEYVALUE_ENTRY(EVENT_FILECHANGEDSHELLPOST, "FileChangedShellPost"),
+    KEYVALUE_ENTRY(-EVENT_FILEAPPENDCMD, "FileAppendCmd"),
+    KEYVALUE_ENTRY(-EVENT_FILEAPPENDPOST, "FileAppendPost"),
+    KEYVALUE_ENTRY(-EVENT_FILEAPPENDPRE, "FileAppendPre"),
+    KEYVALUE_ENTRY(-EVENT_FILECHANGEDRO, "FileChangedRO"),
+    KEYVALUE_ENTRY(-EVENT_FILECHANGEDSHELL, "FileChangedShell"),
+    KEYVALUE_ENTRY(-EVENT_FILECHANGEDSHELLPOST, "FileChangedShellPost"),
     KEYVALUE_ENTRY(EVENT_ENCODINGCHANGED, "FileEncoding"),
-    KEYVALUE_ENTRY(EVENT_FILEREADCMD, "FileReadCmd"),
-    KEYVALUE_ENTRY(EVENT_FILEREADPOST, "FileReadPost"),
-    KEYVALUE_ENTRY(EVENT_FILEREADPRE, "FileReadPre"),
-    KEYVALUE_ENTRY(EVENT_FILETYPE, "FileType"),
-    KEYVALUE_ENTRY(EVENT_FILEWRITECMD, "FileWriteCmd"),
-    KEYVALUE_ENTRY(EVENT_FILEWRITEPOST, "FileWritePost"),
-    KEYVALUE_ENTRY(EVENT_FILEWRITEPRE, "FileWritePre"),
-    KEYVALUE_ENTRY(EVENT_FILTERREADPOST, "FilterReadPost"),
-    KEYVALUE_ENTRY(EVENT_FILTERREADPRE, "FilterReadPre"),
-    KEYVALUE_ENTRY(EVENT_FILTERWRITEPOST, "FilterWritePost"),
-    KEYVALUE_ENTRY(EVENT_FILTERWRITEPRE, "FilterWritePre"),
+    KEYVALUE_ENTRY(-EVENT_FILEREADCMD, "FileReadCmd"),
+    KEYVALUE_ENTRY(-EVENT_FILEREADPOST, "FileReadPost"),
+    KEYVALUE_ENTRY(-EVENT_FILEREADPRE, "FileReadPre"),
+    KEYVALUE_ENTRY(-EVENT_FILETYPE, "FileType"),
+    KEYVALUE_ENTRY(-EVENT_FILEWRITECMD, "FileWriteCmd"),
+    KEYVALUE_ENTRY(-EVENT_FILEWRITEPOST, "FileWritePost"),
+    KEYVALUE_ENTRY(-EVENT_FILEWRITEPRE, "FileWritePre"),
+    KEYVALUE_ENTRY(-EVENT_FILTERREADPOST, "FilterReadPost"),
+    KEYVALUE_ENTRY(-EVENT_FILTERREADPRE, "FilterReadPre"),
+    KEYVALUE_ENTRY(-EVENT_FILTERWRITEPOST, "FilterWritePost"),
+    KEYVALUE_ENTRY(-EVENT_FILTERWRITEPRE, "FilterWritePre"),
     KEYVALUE_ENTRY(EVENT_FOCUSGAINED, "FocusGained"),
     KEYVALUE_ENTRY(EVENT_FOCUSLOST, "FocusLost"),
     KEYVALUE_ENTRY(EVENT_FUNCUNDEFINED, "FuncUndefined"),
     KEYVALUE_ENTRY(EVENT_GUIENTER, "GUIEnter"),
     KEYVALUE_ENTRY(EVENT_GUIFAILED, "GUIFailed"),
-    KEYVALUE_ENTRY(EVENT_INSERTCHANGE, "InsertChange"),
-    KEYVALUE_ENTRY(EVENT_INSERTCHARPRE, "InsertCharPre"),
-    KEYVALUE_ENTRY(EVENT_INSERTENTER, "InsertEnter"),
-    KEYVALUE_ENTRY(EVENT_INSERTLEAVE, "InsertLeave"),
-    KEYVALUE_ENTRY(EVENT_INSERTLEAVEPRE, "InsertLeavePre"),
+    KEYVALUE_ENTRY(-EVENT_INSERTCHANGE, "InsertChange"),
+    KEYVALUE_ENTRY(-EVENT_INSERTCHARPRE, "InsertCharPre"),
+    KEYVALUE_ENTRY(-EVENT_INSERTENTER, "InsertEnter"),
+    KEYVALUE_ENTRY(-EVENT_INSERTLEAVE, "InsertLeave"),
+    KEYVALUE_ENTRY(-EVENT_INSERTLEAVEPRE, "InsertLeavePre"),
     KEYVALUE_ENTRY(EVENT_KEYINPUTPRE, "KeyInputPre"),
     KEYVALUE_ENTRY(EVENT_MENUPOPUP, "MenuPopup"),
     KEYVALUE_ENTRY(EVENT_MODECHANGED, "ModeChanged"),
@@ -168,7 +169,7 @@
     KEYVALUE_ENTRY(EVENT_SESSIONLOADPOST, "SessionLoadPost"),
     KEYVALUE_ENTRY(EVENT_SESSIONWRITEPOST, "SessionWritePost"),
     KEYVALUE_ENTRY(EVENT_SHELLCMDPOST, "ShellCmdPost"),
-    KEYVALUE_ENTRY(EVENT_SHELLFILTERPOST, "ShellFilterPost"),
+    KEYVALUE_ENTRY(-EVENT_SHELLFILTERPOST, "ShellFilterPost"),
     KEYVALUE_ENTRY(EVENT_SIGUSR1, "SigUSR1"),
     KEYVALUE_ENTRY(EVENT_SOURCECMD, "SourceCmd"),
     KEYVALUE_ENTRY(EVENT_SOURCEPOST, "SourcePost"),
@@ -187,11 +188,11 @@
     KEYVALUE_ENTRY(EVENT_TERMINALWINOPEN, "TerminalWinOpen"),
     KEYVALUE_ENTRY(EVENT_TERMRESPONSE, "TermResponse"),
     KEYVALUE_ENTRY(EVENT_TERMRESPONSEALL, "TermResponseAll"),
-    KEYVALUE_ENTRY(EVENT_TEXTCHANGED, "TextChanged"),
-    KEYVALUE_ENTRY(EVENT_TEXTCHANGEDI, "TextChangedI"),
-    KEYVALUE_ENTRY(EVENT_TEXTCHANGEDP, "TextChangedP"),
-    KEYVALUE_ENTRY(EVENT_TEXTCHANGEDT, "TextChangedT"),
-    KEYVALUE_ENTRY(EVENT_TEXTYANKPOST, "TextYankPost"),
+    KEYVALUE_ENTRY(-EVENT_TEXTCHANGED, "TextChanged"),
+    KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDI, "TextChangedI"),
+    KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDP, "TextChangedP"),
+    KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDT, "TextChangedT"),
+    KEYVALUE_ENTRY(-EVENT_TEXTYANKPOST, "TextYankPost"),
     KEYVALUE_ENTRY(EVENT_USER, "User"),
     KEYVALUE_ENTRY(EVENT_VIMENTER, "VimEnter"),
     KEYVALUE_ENTRY(EVENT_VIMLEAVE, "VimLeave"),
@@ -199,44 +200,17 @@
     KEYVALUE_ENTRY(EVENT_VIMRESIZED, "VimResized"),
     KEYVALUE_ENTRY(EVENT_VIMRESUME, "VimResume"),
     KEYVALUE_ENTRY(EVENT_VIMSUSPEND, "VimSuspend"),
-    KEYVALUE_ENTRY(EVENT_WINCLOSED, "WinClosed"),
-    KEYVALUE_ENTRY(EVENT_WINENTER, "WinEnter"),
-    KEYVALUE_ENTRY(EVENT_WINLEAVE, "WinLeave"),
+    KEYVALUE_ENTRY(-EVENT_WINCLOSED, "WinClosed"),
+    KEYVALUE_ENTRY(-EVENT_WINENTER, "WinEnter"),
+    KEYVALUE_ENTRY(-EVENT_WINLEAVE, "WinLeave"),
     KEYVALUE_ENTRY(EVENT_WINNEW, "WinNew"),
     KEYVALUE_ENTRY(EVENT_WINNEWPRE, "WinNewPre"),
-    KEYVALUE_ENTRY(EVENT_WINRESIZED, "WinResized"),
-    KEYVALUE_ENTRY(EVENT_WINSCROLLED, "WinScrolled")
+    KEYVALUE_ENTRY(-EVENT_WINRESIZED, "WinResized"),
+    KEYVALUE_ENTRY(-EVENT_WINSCROLLED, "WinScrolled"),
 };
 
-static AutoPat *first_autopat[NUM_EVENTS] = {
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-static AutoPat *last_autopat[NUM_EVENTS] = {
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL
-};
+static AutoPat *first_autopat[NUM_EVENTS] = { NULL };
+static AutoPat *last_autopat[NUM_EVENTS] = { NULL };
 
 #define AUGROUP_DEFAULT    (-1)	    // default autocmd group
 #define AUGROUP_ERROR	   (-2)	    // erroneous autocmd group
@@ -715,17 +689,17 @@
     // so we check for them first.
     if (cmp_keyvalue_value_ni(&target, bufnewfile) == 0)
 	entry = bufnewfile;
-    else
-    if (cmp_keyvalue_value_ni(&target, bufread) == 0)
+    else if (cmp_keyvalue_value_ni(&target, bufread) == 0)
 	entry = bufread;
     else
-	entry = (keyvalue_T *)bsearch(&target, &event_tab, ARRAY_LENGTH(event_tab), sizeof(event_tab[0]), cmp_keyvalue_value_ni);
+	entry = (keyvalue_T *)bsearch(&target, &event_tab, NUM_EVENTS,
+				sizeof(event_tab[0]), cmp_keyvalue_value_ni);
 
     if (*p == ',')
 	++p;
     *end = p;
 
-    return (entry == NULL) ? NUM_EVENTS : (event_T)entry->key;
+    return (entry == NULL) ? NUM_EVENTS : (event_T)abs(entry->key);
 }
 
 /*
@@ -741,9 +715,9 @@
 
     if (cache_last_index < 0)
     {
-	for (i = 0; i < (int)ARRAY_LENGTH(cache_tab); ++i)
+	for (i = 0; i < CACHE_SIZE; ++i)
 	    cache_tab[i] = -1;
-	cache_last_index = ARRAY_LENGTH(cache_tab) - 1;
+	cache_last_index = CACHE_SIZE - 1;
     }
 
     // first look in the cache
@@ -751,11 +725,11 @@
     // and go backwards wrapping around when we get to index 0.
     for (i = cache_last_index; cache_tab[i] >= 0; )
     {
-	if ((event_T)event_tab[cache_tab[i]].key == event)
+	if ((event_T)abs(event_tab[cache_tab[i]].key) == event)
 	    return event_tab[cache_tab[i]].value.string;
 
 	if (i == 0)
-	    i = ARRAY_LENGTH(cache_tab) - 1;
+	    i = CACHE_SIZE - 1;
 	else
 	    --i;
 
@@ -765,13 +739,13 @@
     }
 
     // look in the event table itself
-    for (i = 0; i < (int)ARRAY_LENGTH(event_tab); ++i)
+    for (i = 0; i < NUM_EVENTS; ++i)
     {
-	if ((event_T)event_tab[i].key == event)
+	if ((event_T)abs(event_tab[i].key) == event)
 	{
 	    // store the found entry in the next position in the cache,
 	    // wrapping around when we get to the maximum index.
-	    if (cache_last_index == ARRAY_LENGTH(cache_tab) - 1)
+	    if (cache_last_index == CACHE_SIZE - 1)
 		cache_last_index = 0;
 	    else
 		++cache_last_index;
@@ -780,8 +754,8 @@
 	}
     }
 
-    return (i == (int)ARRAY_LENGTH(event_tab)) ? (char_u *)"Unknown" :
-	event_tab[i].value.string;
+    return (i == NUM_EVENTS) ? (char_u *)"Unknown" :
+						    event_tab[i].value.string;
 }
 
 /*
@@ -822,18 +796,17 @@
 }
 
 /*
- * Return TRUE if "event" is included in 'eventignore'.
+ * Return TRUE if "event" is included in 'eventignore(win)'.
  */
-    static int
-event_ignored(event_T event)
+    int
+event_ignored(event_T event, char_u *ei)
 {
-    char_u	*p = p_ei;
-
-    while (*p != NUL)
+    while (*ei != NUL)
     {
-	if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
+	if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ',')
+	    && (ei == p_ei || (event_tab[event].key <= 0)))
 	    return TRUE;
-	if (event_name2nr(p, &p) == event)
+	if (event_name2nr(ei, &ei) == event)
 	    return TRUE;
     }
 
@@ -841,23 +814,28 @@
 }
 
 /*
- * Return OK when the contents of p_ei is valid, FAIL otherwise.
+ * Return OK when the contents of 'eventignore' or 'eventignorewin' is valid,
+ * FAIL otherwise.
  */
     int
-check_ei(void)
+check_ei(char_u *ei)
 {
-    char_u	*p = p_ei;
+    int	win = ei != p_ei;
 
-    while (*p)
+    while (*ei)
     {
-	if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
+	if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ','))
 	{
-	    p += 3;
-	    if (*p == ',')
-		++p;
+	    ei += 3;
+	    if (*ei == ',')
+		++ei;
 	}
-	else if (event_name2nr(p, &p) == NUM_EVENTS)
-	    return FAIL;
+	else
+	{
+	    event_T event = event_name2nr(ei, &ei);
+	    if (event == NUM_EVENTS || (win && event_tab[event].key > 0))
+		return FAIL;
+	}
     }
 
     return OK;
@@ -2152,7 +2130,20 @@
     /*
      * Ignore events in 'eventignore'.
      */
-    if (event_ignored(event))
+    if (event_ignored(event, p_ei))
+	goto BYPASS_AU;
+
+    wininfo_T *wip;
+    int win_ignore = FALSE;
+    // If event is allowed in 'eventignorewin', check if curwin or all windows
+    // into "buf" are ignoring the event.
+    if (buf == curbuf && event_tab[event].key <= 0)
+	win_ignore = event_ignored(event, curwin->w_p_eiw);
+    else if (buf != NULL && event_tab[event].key <= 0)
+	FOR_ALL_BUF_WININFO(buf, wip)
+	    if (wip->wi_win != NULL && wip->wi_win->w_buffer == buf)
+		win_ignore = event_ignored(event, wip->wi_win->w_p_eiw);
+    if (win_ignore)
 	goto BYPASS_AU;
 
     /*
@@ -2878,7 +2869,7 @@
     }
 
     i = idx - augroups.ga_len;
-    if (i < 0 || i >= (int)ARRAY_LENGTH(event_tab))
+    if (i < 0 || i >= NUM_EVENTS)
 	return NULL;
 
     return event_tab[i].value.string;
@@ -2889,12 +2880,24 @@
  * include groups.
  */
     char_u *
-get_event_name_no_group(expand_T *xp UNUSED, int idx)
+get_event_name_no_group(expand_T *xp UNUSED, int idx, int win)
 {
-    if (idx < 0 || idx >= (int)ARRAY_LENGTH(event_tab))
+    if (idx < 0 || idx >= NUM_EVENTS)
 	return NULL;
 
-    return event_tab[idx].value.string;
+    if (!win)
+	return event_tab[idx].value.string;
+
+    // Need to check subset of allowed values for 'eventignorewin'.
+    int j = 0;
+    for (int i = 0; i < NUM_EVENTS; ++i)
+    {
+	j += event_tab[i].key <= 0;
+	if (j == idx + 1)
+	    return event_tab[i].value.string;
+    }
+
+    return NULL;
 }
 
 
@@ -3369,15 +3372,14 @@
 		target.value.string = name;
 		target.value.length = STRLEN(target.value.string);
 		entry = (keyvalue_T *)bsearch(&target, &event_tab,
-			ARRAY_LENGTH(event_tab), sizeof(event_tab[0]),
-			cmp_keyvalue_value_ni);
+		    NUM_EVENTS, sizeof(event_tab[0]), cmp_keyvalue_value_ni);
 		if (entry == NULL)
 		{
 		    semsg(_(e_no_such_event_str), name);
 		    vim_free(name);
 		    return;
 		}
-		event_arg = (event_T)entry->key;
+		event_arg = (event_T)abs(entry->key);
 	    }
 	    vim_free(name);
 	}
diff --git a/src/option.c b/src/option.c
index 3753c4a..60e1cf0 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6628,6 +6628,7 @@
 #ifdef FEAT_DIFF
 	case PV_DIFF:	return (char_u *)&(curwin->w_p_diff);
 #endif
+	case PV_EIW:	return (char_u *)&(curwin->w_p_eiw);
 #ifdef FEAT_FOLDING
 	case PV_FDC:	return (char_u *)&(curwin->w_p_fdc);
 	case PV_FEN:	return (char_u *)&(curwin->w_p_fen);
@@ -6941,6 +6942,7 @@
     to->wo_diff = from->wo_diff;
     to->wo_diff_saved = from->wo_diff_saved;
 #endif
+    to->wo_eiw = copy_option_val(from->wo_eiw);
 #ifdef FEAT_CONCEAL
     to->wo_cocu = copy_option_val(from->wo_cocu);
     to->wo_cole = from->wo_cole;
@@ -7006,6 +7008,7 @@
 # endif
     check_string_option(&wop->wo_fmr);
 #endif
+    check_string_option(&wop->wo_eiw);
 #ifdef FEAT_SIGNS
     check_string_option(&wop->wo_scl);
 #endif
@@ -7054,6 +7057,7 @@
 # endif
     clear_string_option(&wop->wo_fmr);
 #endif
+    clear_string_option(&wop->wo_eiw);
 #ifdef FEAT_SIGNS
     clear_string_option(&wop->wo_scl);
 #endif
diff --git a/src/option.h b/src/option.h
index df5bf4d..70206f3 100644
--- a/src/option.h
+++ b/src/option.h
@@ -1288,6 +1288,7 @@
 #ifdef FEAT_DIFF
     , WV_DIFF
 #endif
+    , WV_EIW
 #ifdef FEAT_FOLDING
     , WV_FDC
     , WV_FEN
diff --git a/src/optiondefs.h b/src/optiondefs.h
index c7c96de..8326537 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -164,6 +164,7 @@
 #ifdef FEAT_DIFF
 # define PV_DIFF	OPT_WIN(WV_DIFF)
 #endif
+# define PV_EIW		OPT_WIN(WV_EIW)
 #ifdef FEAT_FOLDING
 # define PV_FDC		OPT_WIN(WV_FDC)
 # define PV_FEN		OPT_WIN(WV_FEN)
@@ -917,6 +918,9 @@
     {"eventignore", "ei",   P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
 			    (char_u *)&p_ei, PV_NONE, did_set_eventignore, expand_set_eventignore,
 			    {(char_u *)"", (char_u *)0L} SCTX_INIT},
+    {"eventignorewin", "eiw",   P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
+			    (char_u *)VAR_WIN, PV_EIW, did_set_eventignore, expand_set_eventignore,
+			    {(char_u *)"", (char_u *)0L} SCTX_INIT},
     {"expandtab",   "et",   P_BOOL|P_VI_DEF|P_VIM,
 			    (char_u *)&p_et, PV_ET, NULL, NULL,
 			    {(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
diff --git a/src/optionstr.c b/src/optionstr.c
index 4dda7a0..f912e30 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -2150,29 +2150,34 @@
 }
 
 /*
- * The 'eventignore' option is changed.
+ * The 'eventignore(win)' option is changed.
  */
     char *
-did_set_eventignore(optset_T *args UNUSED)
+did_set_eventignore(optset_T *args)
 {
-    if (check_ei() == FAIL)
+    char_u	**varp = (char_u **)args->os_varp;
+
+    if (check_ei(*varp) == FAIL)
 	return e_invalid_argument;
     return NULL;
 }
 
+static int expand_eiw = FALSE;
+
     static char_u *
 get_eventignore_name(expand_T *xp, int idx)
 {
-    // 'eventignore' allows special keyword "all" in addition to
+    // 'eventignore(win)' allows special keyword "all" in addition to
     // all event names.
     if (idx == 0)
 	return (char_u *)"all";
-    return get_event_name_no_group(xp, idx - 1);
+    return get_event_name_no_group(xp, idx - 1, expand_eiw);
 }
 
     int
 expand_set_eventignore(optexpand_T *args, int *numMatches, char_u ***matches)
 {
+    expand_eiw = args->oe_varp != (char_u *)&p_ei;
     return expand_set_opt_generic(
 	    args,
 	    get_eventignore_name,
diff --git a/src/proto/autocmd.pro b/src/proto/autocmd.pro
index 920987a..ed85603 100644
--- a/src/proto/autocmd.pro
+++ b/src/proto/autocmd.pro
@@ -5,7 +5,8 @@
 void autocmd_init(void);
 void free_all_autocmds(void);
 int is_aucmd_win(win_T *win);
-int check_ei(void);
+int check_ei(char_u *ei);
+int event_ignored(event_T event, char_u *ei);
 char_u *au_event_disable(char *what);
 void au_event_restore(char_u *old_ei);
 void do_autocmd(exarg_T *eap, char_u *arg_in, int forceit);
@@ -40,7 +41,7 @@
 char_u *get_augroup_name(expand_T *xp, int idx);
 char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd);
 char_u *get_event_name(expand_T *xp, int idx);
-char_u *get_event_name_no_group(expand_T *xp, int idx);
+char_u *get_event_name_no_group(expand_T *xp, int idx, int eiw);
 int autocmd_supported(char_u *name);
 int au_exists(char_u *arg);
 void f_autocmd_add(typval_T *argvars, typval_T *rettv);
diff --git a/src/structs.h b/src/structs.h
index 7c51c72..03c28e2 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -210,6 +210,8 @@
     int		wo_diff;
 # define w_p_diff w_onebuf_opt.wo_diff	// 'diff'
 #endif
+    char_u	*wo_eiw;
+# define w_p_eiw w_onebuf_opt.wo_eiw	// 'eventignorewin'
 #ifdef FEAT_FOLDING
     long	wo_fdc;
 # define w_p_fdc w_onebuf_opt.wo_fdc	// 'foldcolumn'
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
index 2dfb070..1918bda 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -189,6 +189,8 @@
       \ 'encoding': [['latin1'], ['xxx', '']],
       \ 'eventignore': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
       \		['xxx']],
+      \ 'eventignorewin': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
+      \		['xxx', 'WinNew']],
       \ 'fileencoding': [['', 'latin1', 'xxx'], []],
       \ 'fileformat': [['', 'dos', 'unix', 'mac'], ['xxx']],
       \ 'fileformats': [['', 'dos', 'dos,unix'], ['xxx']],
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 5868f1c..bcb0f59 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -4103,10 +4103,10 @@
   augroup END
 
   let expected = [
-        \ {'cmd': 'echo "suspend"', 'group': 'TestAutoCmdFns', 'pattern': '*',
-        \ 'nested': v:true, 'once': v:false, 'event': 'VimSuspend'},
         \ {'cmd': 'echo "resume"', 'group': 'TestAutoCmdFns', 'pattern': '*',
-        \  'nested': v:false, 'once': v:true, 'event': 'VimResume'}]
+        \  'nested': v:false, 'once': v:true, 'event': 'VimResume'},
+        \ {'cmd': 'echo "suspend"', 'group': 'TestAutoCmdFns', 'pattern': '*',
+        \ 'nested': v:true, 'once': v:false, 'event': 'VimSuspend'}]
   call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'}))
 
   " Test for buffer-local autocmd
@@ -4926,4 +4926,64 @@
   set cmdheight& mouse& laststatus&
 endfunc
 
+func Test_eventignorewin()
+  defer CleanUpTestAuGroup()
+  augroup testing
+    au WinEnter * :call add(g:evs, ["WinEnter", expand("<afile>")])
+    au WinLeave * :call add(g:evs, ["WinLeave", expand("<afile>")])
+    au BufWinEnter * :call add(g:evs, ["BufWinEnter", expand("<afile>")])
+  augroup END
+
+  let g:evs = []
+  set eventignorewin=WinLeave,WinEnter
+  split foo
+  call assert_equal([['BufWinEnter', 'foo']], g:evs)
+  set eventignorewin=all
+  edit bar
+  call assert_equal([['BufWinEnter', 'foo']], g:evs)
+  set eventignorewin=
+  wincmd w
+  call assert_equal([['BufWinEnter', 'foo'], ['WinLeave', 'bar']], g:evs)
+
+  only!
+  %bwipe!
+  set eventignorewin&
+  unlet g:evs
+endfunc
+
+func Test_WinScrolled_Resized_eiw()
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+    call setline(1, ['foo']->repeat(32))
+    set eventignorewin=WinScrolled,WinResized
+    split
+    let [g:afile,g:resized,g:scrolled] = ['none',0,0]
+    au WinScrolled * let [g:afile,g:scrolled] = [expand('<afile>'),g:scrolled+1]
+    au WinResized * let [g:afile,g:resized] = [expand('<afile>'),g:resized+1]
+  END
+  call writefile(lines, 'Xtest_winscrolled_mouse', 'D')
+  let buf = RunVimInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10})
+
+  " Both windows are ignoring resize events
+  call term_sendkeys(buf, "\<C-W>-")
+  call TermWait(buf)
+  call term_sendkeys(buf, ":echo g:afile g:resized g:scrolled\<CR>")
+  call WaitForAssert({-> assert_equal('none 0 0', term_getline(buf, 10))}, 1000)
+
+  " And scroll events
+  call term_sendkeys(buf, "Ggg")
+  call TermWait(buf)
+  call term_sendkeys(buf, ":echo g:afile g:resized g:scrolled\<CR>")
+  call WaitForAssert({-> assert_equal('none 0 0', term_getline(buf, 10))}, 1000)
+
+  " Un-ignore events in second window, make first window current and resize
+  call term_sendkeys(buf, ":set eventignorewin=\<CR>\<C-W>w\<C-W>+")
+  call TermWait(buf)
+  call term_sendkeys(buf, ":echo win_getid() g:afile g:resized g:scrolled\<CR>")
+  call WaitForAssert({-> assert_equal('1000 1001 1 1', term_getline(buf, 10))}, 1000)
+
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index a7621f5..84a0035 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -577,6 +577,7 @@
 
   " Other string options that queries the system rather than fixed enum names
   call assert_equal(['all', 'BufAdd'], getcompletion('set eventignore=', 'cmdline')[0:1])
+  call assert_equal(['WinLeave', 'WinResized', 'WinScrolled'], getcompletion('set eiw=', 'cmdline')[-3:-1])
   call assert_equal('latin1', getcompletion('set fileencodings=', 'cmdline')[1])
   call assert_equal('top', getcompletion('set printoptions=', 'cmdline')[0])
   call assert_equal('SpecialKey', getcompletion('set wincolor=', 'cmdline')[0])
@@ -2499,6 +2500,7 @@
         \ ['eadirection', 'hor', 'a123'],
         \ ['encoding', 'utf-8', 'a123'],
         \ ['eventignore', 'TextYankPost', 'a123'],
+        \ ['eventignorewin', 'WinScrolled', 'a123'],
         \ ['fileencoding', 'utf-8', 'a123,'],
         \ ['fileformat', 'mac', 'a123'],
         \ ['fileformats', 'mac', 'a123'],
diff --git a/src/version.c b/src/version.c
index 4651be2..cb4805a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1084,
+/**/
     1083,
 /**/
     1082,
diff --git a/src/vim.h b/src/vim.h
index eb31217..e0c40c9 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1333,11 +1333,12 @@
 #define SID_WINLAYOUT	(-7)	// changing window size
 
 /*
- * Events for autocommands.
+ * Events for autocommands. Must be kept in sync with "event_tab".
  */
 enum auto_event
 {
     EVENT_BUFADD = 0,		// after adding a buffer to the buffer list
+    EVENT_BUFCREATE,		// UNUSED: BufCreate == BufAdd
     EVENT_BUFDELETE,		// deleting a buffer from the buffer list
     EVENT_BUFENTER,		// after entering a buffer
     EVENT_BUFFILEPOST,		// after renaming a buffer
@@ -1346,6 +1347,7 @@
     EVENT_BUFLEAVE,		// before leaving a buffer
     EVENT_BUFNEW,		// after creating any buffer
     EVENT_BUFNEWFILE,		// when creating a buffer for a new file
+    EVENT_BUFREAD,		// UNUSED: BufRead == BufReadPost
     EVENT_BUFREADCMD,		// read buffer using command
     EVENT_BUFREADPOST,		// after reading a buffer
     EVENT_BUFREADPRE,		// before reading a buffer
@@ -1353,6 +1355,7 @@
     EVENT_BUFWINENTER,		// after showing a buffer in a window
     EVENT_BUFWINLEAVE,		// just after buffer removed from window
     EVENT_BUFWIPEOUT,		// just before really deleting a buffer
+    EVENT_BUFWRITE,		// UNUSED: BufWrite == BufWritePost
     EVENT_BUFWRITECMD,		// write buffer using command
     EVENT_BUFWRITEPOST,		// after writing a buffer
     EVENT_BUFWRITEPRE,		// before writing a buffer
@@ -1383,6 +1386,7 @@
     EVENT_FILECHANGEDRO,	// before first change to read-only file
     EVENT_FILECHANGEDSHELL,	// after shell command that changed file
     EVENT_FILECHANGEDSHELLPOST,	// after (not) reloading changed file
+    EVENT_FILEENCODING,		// UNUSED: FileEncoding == EncodingChanged
     EVENT_FILEREADCMD,		// read from a file using command
     EVENT_FILEREADPOST,		// after reading a file
     EVENT_FILEREADPRE,		// before reading a file
@@ -1402,8 +1406,8 @@
     EVENT_INSERTCHANGE,		// when changing Insert/Replace mode
     EVENT_INSERTCHARPRE,	// before inserting a char
     EVENT_INSERTENTER,		// when entering Insert mode
-    EVENT_INSERTLEAVEPRE,	// just before leaving Insert mode
     EVENT_INSERTLEAVE,		// just after leaving Insert mode
+    EVENT_INSERTLEAVEPRE,	// just before leaving Insert mode
     EVENT_KEYINPUTPRE,		// before key input
     EVENT_MENUPOPUP,		// just before popup menu is displayed
     EVENT_MODECHANGED,		// after changing the mode
@@ -1420,8 +1424,8 @@
     EVENT_SHELLFILTERPOST,	// after ":1,2!cmd", ":w !cmd", ":r !cmd".
     EVENT_SIGUSR1,		// after the SIGUSR1 signal
     EVENT_SOURCECMD,		// sourcing a Vim script using command
-    EVENT_SOURCEPRE,		// before sourcing a Vim script
     EVENT_SOURCEPOST,		// after sourcing a Vim script
+    EVENT_SOURCEPRE,		// before sourcing a Vim script
     EVENT_SPELLFILEMISSING,	// spell file missing
     EVENT_STDINREADPOST,	// after reading from stdin
     EVENT_STDINREADPRE,		// before reading from stdin
@@ -1447,17 +1451,17 @@
     EVENT_VIMLEAVE,		// before exiting Vim
     EVENT_VIMLEAVEPRE,		// before exiting Vim and writing .viminfo
     EVENT_VIMRESIZED,		// after Vim window was resized
+    EVENT_VIMRESUME,		// after Vim is resumed
+    EVENT_VIMSUSPEND,		// before Vim is suspended
+    EVENT_WINCLOSED,		// after closing a window
     EVENT_WINENTER,		// after entering a window
     EVENT_WINLEAVE,		// before leaving a window
-    EVENT_WINNEWPRE,		// before creating a new window
     EVENT_WINNEW,		// after creating a new window
-    EVENT_WINCLOSED,		// after closing a window
-    EVENT_VIMSUSPEND,		// before Vim is suspended
-    EVENT_VIMRESUME,		// after Vim is resumed
+    EVENT_WINNEWPRE,		// before creating a new window
     EVENT_WINRESIZED,		// after a window was resized
     EVENT_WINSCROLLED,		// after a window was scrolled or resized
 
-    NUM_EVENTS			// MUST be the last one
+    NUM_EVENTS,			// MUST be the last one
 };
 
 typedef enum auto_event event_T;
diff --git a/src/window.c b/src/window.c
index b15ad3e..cc76f79 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3076,14 +3076,10 @@
 
 /*
  * This function is used for three purposes:
- * 1. Goes over all windows in the current tab page and returns:
- *	0				no scrolling and no size changes found
- *	CWSR_SCROLLED			at least one window scrolled
- *	CWSR_RESIZED			at least one window changed size
- *	CWSR_SCROLLED + CWSR_RESIZED	both
- *    "size_count" is set to the nr of windows with size changes.
- *    "first_scroll_win" is set to the first window with any relevant changes.
- *    "first_size_win" is set to the first window with size changes.
+ * 1. Goes over all windows in the current tab page and sets:
+ *    "size_count" to the nr of windows with size changes.
+ *    "first_scroll_win" to the first window with any relevant changes.
+ *    "first_size_win" to the first window with size changes.
  *
  * 2. When the first three arguments are NULL and "winlist" is not NULL,
  *    "winlist" is set to the list of window IDs with size changes.
@@ -3091,7 +3087,7 @@
  * 3. When the first three arguments are NULL and "v_event" is not NULL,
  *    information about changed windows is added to "v_event".
  */
-    static int
+    static void
 check_window_scroll_resize(
 	int	*size_count,
 	win_T	**first_scroll_win,
@@ -3099,7 +3095,6 @@
 	list_T	*winlist UNUSED,
 	dict_T	*v_event UNUSED)
 {
-    int result = 0;
 #ifdef FEAT_EVAL
     int listidx = 0;
     int tot_width = 0;
@@ -3115,11 +3110,12 @@
     win_T *wp;
     FOR_ALL_WINDOWS(wp)
     {
-	int size_changed = wp->w_last_width != wp->w_width
-					  || wp->w_last_height != wp->w_height;
+	int ignore_scroll = event_ignored(EVENT_WINSCROLLED, wp->w_p_eiw);
+	int size_changed = !event_ignored(EVENT_WINRESIZED, wp->w_p_eiw)
+			    && (wp->w_last_width != wp->w_width
+			    || wp->w_last_height != wp->w_height);
 	if (size_changed)
 	{
-	    result |= CWSR_RESIZED;
 #ifdef FEAT_EVAL
 	    if (winlist != NULL)
 	    {
@@ -3139,23 +3135,21 @@
 		    *first_size_win = wp;
 		// For WinScrolled the first window with a size change is used
 		// even when it didn't scroll.
-		if (*first_scroll_win == NULL)
+		if (*first_scroll_win == NULL && !ignore_scroll)
 		    *first_scroll_win = wp;
 	    }
 	}
 
-	int scroll_changed = wp->w_last_topline != wp->w_topline
+	int scroll_changed = !ignore_scroll
+				&& (wp->w_last_topline != wp->w_topline
 #ifdef FEAT_DIFF
 				|| wp->w_last_topfill != wp->w_topfill
 #endif
 				|| wp->w_last_leftcol != wp->w_leftcol
-				|| wp->w_last_skipcol != wp->w_skipcol;
-	if (scroll_changed)
-	{
-	    result |= CWSR_SCROLLED;
-	    if (first_scroll_win != NULL && *first_scroll_win == NULL)
-		*first_scroll_win = wp;
-	}
+				|| wp->w_last_skipcol != wp->w_skipcol);
+	if (scroll_changed
+	    && first_scroll_win != NULL && *first_scroll_win == NULL)
+	    *first_scroll_win = wp;
 
 #ifdef FEAT_EVAL
 	if ((size_changed || scroll_changed) && v_event != NULL)
@@ -3214,8 +3208,6 @@
 	}
     }
 #endif
-
-    return result;
 }
 
 /*
@@ -3238,11 +3230,10 @@
 
     int size_count = 0;
     win_T *first_scroll_win = NULL, *first_size_win = NULL;
-    int cwsr = check_window_scroll_resize(&size_count,
-					   &first_scroll_win, &first_size_win,
-					   NULL, NULL);
+    check_window_scroll_resize(&size_count, &first_scroll_win, &first_size_win,
+								    NULL, NULL);
     int trigger_resize = do_resize && size_count > 0;
-    int trigger_scroll = do_scroll && cwsr != 0;
+    int trigger_scroll = do_scroll && first_scroll_win != NULL;
     if (!trigger_resize && !trigger_scroll)
 	return;  // no relevant changes
 #ifdef FEAT_EVAL