From 5a261610b46b7da71bb1596bfb38ca7c27d3de79 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 3 Jun 2024 20:37:31 +0300 Subject: [PATCH] Avoid crashes and assertions while handling SIGWINCH * src/dispnew.c (build_frame_matrix_from_leaf_window) (window_to_frame_vpos): Avoid assertion violations when we have an unhandled SIGWINCH. (frame_size_change_delayed): New function. * src/dispextern.h (frame_size_change_delayed): Add prototype. * src/cm.c (cmcheckmagic): Don't check magicwrap if we have an unhandled SIGWINCH. (Bug#71289) (cherry picked from commit eb9afd558ec506f1d349dbb61668d6231fda136f) --- src/cm.c | 4 ++++ src/dispextern.h | 1 + src/dispnew.c | 15 +++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/cm.c b/src/cm.c index d6b54d507c7..85fc3e776c8 100644 --- a/src/cm.c +++ b/src/cm.c @@ -111,6 +111,10 @@ addcol (tty, n) { void cmcheckmagic (struct tty_display_info *tty) { + /* If we have unhandled SIGWINCH, we don't really know what are our + up-to-date frame diumensions. */ + if (frame_size_change_delayed ()) + return; if (curX (tty) == FrameCols (tty)) { if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1) diff --git a/src/dispextern.h b/src/dispextern.h index 28e59700469..8207e74a90c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3812,6 +3812,7 @@ extern void gui_update_window_end (struct window *, bool, bool); #endif void do_pending_window_change (bool); void change_frame_size (struct frame *, int, int, bool, bool, bool); +extern bool frame_size_change_delayed (void); void init_display (void); void syms_of_display (void); extern void spec_glyph_lookup_face (struct window *, GLYPH *); diff --git a/src/dispnew.c b/src/dispnew.c index 8eda8dbb358..dfa36a9f54f 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -2643,7 +2643,8 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w #ifdef GLYPH_DEBUG /* Window row window_y must be a slice of frame row frame_y. */ - eassert (glyph_row_slice_p (window_row, frame_row)); + eassert (delayed_size_change + || glyph_row_slice_p (window_row, frame_row)); /* If rows are in sync, we don't have to copy glyphs because frame and window share glyphs. */ @@ -3149,7 +3150,8 @@ window_to_frame_vpos (struct window *w, int vpos) eassert (!FRAME_WINDOW_P (XFRAME (w->frame))); eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows); vpos += WINDOW_TOP_EDGE_LINE (w); - eassert (vpos >= 0 && vpos <= FRAME_TOTAL_LINES (XFRAME (w->frame))); + eassert (delayed_size_change + || (vpos >= 0 && vpos <= FRAME_TOTAL_LINES (XFRAME (w->frame)))); return vpos; } @@ -6078,6 +6080,15 @@ change_frame_size (struct frame *f, int new_width, int new_height, else change_frame_size_1 (f, new_width, new_height, pretend, delay, safe); } + +/* Return non-zero if we delayed size-changes and haven't handled them + yet, which means we cannot be sure about the exact dimensions of our + frames. */ +bool +frame_size_change_delayed (void) +{ + return delayed_size_change; +} /*********************************************************************** Terminal Related Lisp Functions -- 2.39.2