Subject: bug#76275: 31.0.50; frame-inhibit-implied-resize broken on recent master

From: martin rudalics <[email-masked]>
Date: Mon, 17 Feb 2025 10:21:34 +0100

> This frame has no toolbar, because it's a (minibuffer . only) frame.
 > Did you notice that?  I don't know whether it's significant.

Hopefully not.  The tool_bar_resized flag should be set regardless of
whether a tool bar was made or not.  This is emphasized by this comment
in xdisp.c:

       /* Even if we do not display a tool bar initially, still pretend
	 that we have resized it already.  This avoids that a later
	 activation of the tool bar resizes the frame, despite of the
	 fact that a setting of 'frame-inhibit-implied-resize' should
	 inhibit it (Bug#52986).  */
       f->tool_bar_resized = true;

 >> Are you sure you did something like
 >>
 >>        if (!FRAME_LIVE_P (f)
 >> 	  || !f->can_set_window_size
 >> 	  || !f->after_make_frame
 >> 	  || !f->tool_bar_resized
 >> 	  || FRAME_TOOLTIP_P (f)
 >> 	  || !(frame_window_change
 >> 	       || frame_selected_change
 >> 	       || frame_selected_window_change
 >> 	       || frame_window_state_change))
 >> 	/* Either we are not allowed to run hooks for this frame or no
 >> 	   window change has been reported for it since the last time
 >> 	   we ran window change functions on it.  */
 >> 	continue;
 >>
 >> If that hook is still run, we'd have to find out why.
 >
 > Oops.  I patched run_window_configuration_change_hook, not
 > run_window_change_functions.  Sorry about that!  So, let me go back to
 > the debugging instructions in your previous e-mail.

Should teach me to always include a diff when proposing changes.

 > First I tried the unpatched code and printed the three variables.  My
 > breakpoint was hit eight times and in each case, f->can_set_window_size
 > and f->after_make_frame were true, and f->tool_bar_resized was false.

Sounds encouraging.

 > Then I patched in the check for f->tool_bar_resized.  This makes the
 > problem not reproducible.

OK.  So to fix your problem the attached patch suffices?  I also patched
the corresponding part for running the configuration change hook.

 >> I am also stupefied by the fact that the
 >>
 >>>       (with-selected-frame frame
 >>>         (apply #'completing-read prompt collection optional-args))))
 >>
 >> is apparently needed.  WOW a pure 'make-frame' together with the hook on
 >> 'window-size-change-functions' is _not_ sufficient.  Right?
 >
 > Yes, I just reconfirmed this.

Whatever it does, it triggers the hook.

 >> Is the
 >>
 >> (apply #'completing-read prompt collection optional-args))))
 >>
 >> needed literally or would just selecting the frame suffice?  Or does
 >> ‘completing-read’ trigger the window size change that puts the bad
 >> sequence in motion?
 >
 > I just tested this.  I replaced
 >
 > --8<---------------cut here---------------start------------->8---
 >      (with-selected-frame frame
 >        (apply #'completing-read prompt collection optional-args))
 > --8<---------------cut here---------------end--------------->8---
 >
 > with
 >
 > --8<---------------cut here---------------start------------->8---
 >      (select-frame frame)
 > --8<---------------cut here---------------end--------------->8---
 >
 > and then, indeed, the problem is not reproducible.  So just selecting
 > the frame does *not* suffice.

It probably would suffice to show another buffer in that window.

 >> One other thing: Would enlarging the scope via
 >>
 >> (defun spw/scale-default (frame)
 >>    (let ((frame-inhibit-implied-resize t))
 >>      (set-face-attribute 'default frame :height 120)))
 >>
 >> change anything?
 >
 > I just tested this.  No, it doesn't help.  The problem is still
 > reproducible.

So likely the let-binding in 'make-frame' extends until here.  Can you
confirm that in your "My breakpoint was hit eight times and in each
case, ..." the value of the _variable_ frame_inhibit_implied_resize was
always t while the function with the same name returned false?

martin
diff --git a/src/window.c b/src/window.c
index 330a95a716f..e4990d06148 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3785,7 +3785,11 @@ run_window_configuration_change_hook (struct frame *f)
 
   if (NILP (Vrun_hooks)
       || !f->can_set_window_size
-      || !f->after_make_frame)
+      || !f->after_make_frame
+#ifdef USE_GTK
+      || !f->tool_bar_resized
+#endif
+      )
     return;
 
   /* Use the right buffer.  Matters when running the local hooks.  */
@@ -4120,6 +4124,9 @@ run_window_change_functions (void)
       if (!FRAME_LIVE_P (f)
 	  || !f->can_set_window_size
 	  || !f->after_make_frame
+#ifdef USE_GTK
+	  || !f->tool_bar_resized
+#endif
 	  || FRAME_TOOLTIP_P (f)
 	  || !(frame_window_change
 	       || frame_selected_change