Subject: bug#73022: 31.0.50; Crash in build_frame_matrix_from_leaf_window after C-x 2 and reducing terminal size

From: martin rudalics <[email-masked]>
Date: Thu, 5 Sep 2024 18:27:07 +0200

> What is supposed to happen, with the current code, when the frame is
 > resized to less than the minimum dimensions we allow?  Shouldn't we
 > disallow/refuse such resizes?  And if we don't refuse, what will
 > happen to the windows?  E.g., if the frame is not tall enough to show
 > the menu bar, the two mode lines, the mini-window, and at least one
 > line for each of the two windows, what should I expect to see on
 > display?

As for GUI frames I wrote some code to handle that but you didn't like
it back then.  Basically, we should do the following:

- Add min-size-hints so the window manage never tries to make the frame
   to small.  These have to correspond to the current window layout and
   the window decorations - a frame with split windows has a larger
   minimum size than one with one window only as we can see in the
   present thread.

- When the window manager doesn't comply, simple ignore the shrink
   request.  Portions of our frame that don't fit will be clipped by the
   window manager.  I wrote some code to always keep the minibuffer
   window visible in such case but cannot remember whether it works well.
   My WM (and Windows too) never tried to make a GUI frame smaller than I
   wanted.

On terminal emulators we should (or even do) conceptually the same as
with a non-compliant WM.  The terminal emulator has to do the clipping
just like the WM.

 > Taking some code and moving it to another place in the same function
 > can only affect what's going on in that function and the functions it
 > calls.  For example, if you had
 >
 >     foo ();
 >     bar ();
 >     baz ();
 >
 > and then you move the call to baz to be before the call to bar, like
 > this:
 >
 >     foo ();
 >     baz ();
 >     bar ();
 >
 > then I can understand why bar and its subroutines are affected.  But
 > once we are done with this code, all the 3 calls have been made, and
 > the order in which they were made can hardly matter for the code which
 > runs after that, right?

So I moved the assignments within adjust_frame_size (baz) in front of
the resize_frame_windows (bar) calls.  Is it that what you mean?

 > So if the crash was inside the call to bar, then I could understand
 > how moving the call to baz before it could affect the crash.  But the
 > backtrace from the assertion violation didn't show adjust_frame_glyphs
 > anywhere on the call-stack, so I don't understand how simply
 > rearranging code inside adjust_frame_glyphs could change something
 > _outside_ it.

Do you mean adjust_frame_size instead of adjust_frame_glyphs here so the
fact that makes you wonder is that adjust_frame_size never shows up in
the backtraces?

I could imagine that resize_frame_windows (or even
'window--pixel-to-total') mess up things in a way that confuses frame
based redisplay later.  In adjust_frame_glyphs_for_frame_redisplay we do

       eassert (matrix_dim.width == FRAME_TOTAL_COLS (f)
	       && matrix_dim.height == FRAME_TOTAL_LINES (f));

and I wonder whether there's an execution path that could bypass that
assertion.

martin