changeset 31178:f1c345ae4d89 v9.0.0923

patch 9.0.0923: second SIGWINCH signal may be ignored Commit: https://github.com/vim/vim/commit/a787c24e009b46955fb03a1f51b745e5e9795b7b Author: Bram Moolenaar <Bram@vim.org> Date: Tue Nov 22 20:41:05 2022 +0000 patch 9.0.0923: second SIGWINCH signal may be ignored Problem: Second SIGWINCH signal may be ignored. Solution: When set_shellsize() is busy when called then run the inner code again when it's done. (issue #424)
author Bram Moolenaar <Bram@vim.org>
date Tue, 22 Nov 2022 21:45:02 +0100
parents 4f996248835e
children 551a8be12cf9
files src/term.c src/version.c
diffstat 2 files changed, 37 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/term.c
+++ b/src/term.c
@@ -3439,28 +3439,9 @@ shell_resized_check(void)
  * If 'mustset' is FALSE, we may try to get the real window size and if
  * it fails use 'width' and 'height'.
  */
-    void
-set_shellsize(int width, int height, int mustset)
+    static void
+set_shellsize_inner(int width, int height, int mustset)
 {
-    static int		busy = FALSE;
-
-    /*
-     * Avoid recursiveness, can happen when setting the window size causes
-     * another window-changed signal.
-     */
-    if (busy)
-	return;
-
-    if (width < 0 || height < 0)    // just checking...
-	return;
-
-    if (State == MODE_HITRETURN || State == MODE_SETWSIZE)
-    {
-	// postpone the resizing
-	State = MODE_SETWSIZE;
-	return;
-    }
-
     if (updating_screen)
 	// resizing while in update_screen() may cause a crash
 	return;
@@ -3472,8 +3453,6 @@ set_shellsize(int width, int height, int
     if (curwin->w_buffer == NULL || curwin->w_lines == NULL)
 	return;
 
-    ++busy;
-
 #ifdef AMIGA
     out_flush();	    // must do this before mch_get_shellsize() for
 			    // some obscure reason
@@ -3547,7 +3526,39 @@ set_shellsize(int width, int height, int
 	cursor_on();	    // redrawing may have switched it off
     }
     out_flush();
-    --busy;
+}
+
+    void
+set_shellsize(int width, int height, int mustset)
+{
+    static int	busy = FALSE;
+    static int	do_run = FALSE;
+
+    if (width < 0 || height < 0)    // just checking...
+	return;
+
+    if (State == MODE_HITRETURN || State == MODE_SETWSIZE)
+    {
+	// postpone the resizing
+	State = MODE_SETWSIZE;
+	return;
+    }
+
+    // Avoid recursiveness.  This can happen when setting the window size
+    // causes another window-changed signal or when two SIGWINCH signals come
+    // very close together.  There needs to be another run then after the
+    // current one is done to pick up the latest size.
+    do_run = TRUE;
+    if (busy)
+	return;
+
+    while (do_run)
+    {
+	do_run = FALSE;
+	busy = TRUE;
+	set_shellsize_inner(width, height, mustset);
+	busy = FALSE;
+    }
 }
 
 /*
--- 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 */
 /**/
+    923,
+/**/
     922,
 /**/
     921,