Subject: bug#70038: 29.3.50; Shift up/down in buffer with images on M-x other-window with some fonts

From: martin rudalics <[email-masked]>
Date: Mon, 15 Apr 2024 11:23:18 +0200

> Did I succeed explaining the issue?

Not yet.  When we freeze window starts in the case at hand we do that to
approximate the behavior of a 'save-window-excursion'.  But doesn't
Emacs always try to preserve window start positions regardless of
whether it enlarges or shrinks a window?  So what, if possibly, could
motivate Emacs to "willfully" change a start position?  It's obvious that
'recenter' asks for it and sets optional_new_start.  It's already not
clear to me why 'delete-other-windows' should want it.  So why treating
frozen starts like asking for new start positions is still a mystery to
me ...

I suppose that freezing should handle one situation only: Emacs enlarges
the mini window, shrinks another window for that purpose and - for a
reason that is still unclear to me as mentioned above - would like to
change that window's start position.  To avoid that - Emacs will still
have to change the start position to avoid that point goes off-screen -
we set that flag.  Now it seems obvious that shrinking the mini window
and thus enlarging another window cannot harm in this regard since
otherwise we couldn't have reset the flag when shrinking a mini window
as we did earlier.  Is it about making the cursor line fully visible?

 > Is that in addition to what I suggested to do in shrink_mini_window?

It should replace it.

 > Also, shouldn't we do this instead:
 >
 >> -      FRAME_WINDOWS_FROZEN (f) = true;
 >> +      FRAME_WINDOWS_FROZEN (f) = (old_height + delta > min_height) ? true : false;
 >
 > IOW, shouldn't we unfreeze only when resizing to the default one-line
 > height?

Since every enlarging of the mini window freezes starts again, this
shouldn't be necessary.  But to make sure that we cover all possible
scenarios we could use the below.

martin

diff --git a/src/window.c b/src/window.c
index fe26311fbb2..34d0def7d72 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5376,7 +5376,6 @@ grow_mini_window (struct window *w, int delta)
        struct window *r = XWINDOW (root);
        Lisp_Object grow;

-      FRAME_WINDOWS_FROZEN (f) = true;
        grow = call3 (Qwindow__resize_root_window_vertically,
  		    root, make_fixnum (- delta), Qt);

@@ -5390,6 +5389,9 @@ grow_mini_window (struct window *w, int delta)
  	  && window_resize_check (r, false))
  	resize_mini_window_apply (w, -XFIXNUM (grow));
      }
+
+  FRAME_WINDOWS_FROZEN (f)
+    = window_body_height (w, WINDOW_BODY_IN_PIXELS) > FRAME_LINE_HEIGHT (f);
  }

  /**
@@ -5413,7 +5415,6 @@ shrink_mini_window (struct window *w)
        struct window *r = XWINDOW (root);
        Lisp_Object grow;

-      FRAME_WINDOWS_FROZEN (f) = false;
        grow = call3 (Qwindow__resize_root_window_vertically,
  		    root, make_fixnum (delta), Qt);

@@ -5425,6 +5426,8 @@ shrink_mini_window (struct window *w)
         bar.  */
      grow_mini_window (w, -delta);

+  FRAME_WINDOWS_FROZEN (f)
+    = window_body_height (w, WINDOW_BODY_IN_PIXELS) > FRAME_LINE_HEIGHT (f);
  }

  DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal,