Subject: Re: bug#72986: Disabling menu-bar-mode changes size of new frames

From: martin rudalics <[email-masked]>
Date: Sun, 6 Oct 2024 17:01:56 +0200

> (This is for first frame without menu bar.)
 >
 > (window-pixel-height) ⇒ 1257

+ 35 pixels for the minibuffer gets us 1292 as expected.  Your main
window is 32 pixels too high, the lowest 3 pixels of the last line
(provided it contains text) should be cut off.

 > I can only suspect that this comes from a request to move the frame that
 >> doesn't show up in the history.  Now the only location where this might
 >> happen is in xterm.c around like 29259 here:
 >>
 >>          if (original_left != x || original_top != y)
 >>            XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 >>                         original_left, original_top);
 >>
 >> Please put a breakpoint on that line and tell me whether it gets hit.
 >> The probability is less than 1% but who knows ...
 >>
 >
 > Nope, sorry, I put a breakpoint and it was not hit. Indeed, the whole block
 > starting at 29233 was not hit (I put a breakpoint at the call to
 > block_input on line 29245).

It was unlikely anyway.  Let us next check whether our event handler
drops events because they come with the same sizes.  With the attached
gtkutil-frame-2.diff and the first frame without minibuffer.

If you have any idea how to debug mutter on your system, we should be
able to get the cause right from there.  In window-x11.c the function
send_configure_notify calls

   meta_topic (META_DEBUG_GEOMETRY,
               "Sending synthetic configure notify to %s with x: %d y: %d w: %d h: %d",
               window->desc,
               event.xconfigure.x, event.xconfigure.y,
               event.xconfigure.width, event.xconfigure.height);

That height should tell us all.  IIUC you would have to set the
environment variable

MUTTER_DEBUG="geometry"

and then look into stderr (or redirect it) whether anything shows up.
IIUC mutter must have been built with a "verbose" option, so I doubt
that it will work for you out of the box but you could try nevertheless.

martin
diff --git a/src/frame.c b/src/frame.c
index 7f4bf274ad9..af95cb54701 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -734,6 +734,7 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
 	      && (new_native_height != old_native_height
 		  || inhibit == 0 || inhibit == 2))))
     {
+#ifndef USE_GTK
       if (inhibit == 2
 #ifdef USE_MOTIF
 	  && !EQ (parameter, Qmenu_bar_lines)
@@ -754,7 +755,7 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
 	  if (f->new_height >= 0)
 	    new_native_height = f->new_height;
 	}
-
+#endif
       if (CONSP (frame_size_history))
 	frame_size_history_adjust (f, inhibit, parameter,
 				   old_text_width, old_text_height,
@@ -6769,7 +6770,7 @@ focus (where a frame immediately loses focus when it's left by the mouse
 
 The function `frame--size-history' displays the value of this variable
 in a more readable form.  */);
-    frame_size_history = Qnil;
+  frame_size_history = Fcons (make_fixnum (100), Qnil);
 
   DEFVAR_BOOL ("tooltip-reuse-hidden-frame", tooltip_reuse_hidden_frame,
 	       doc: /* Non-nil means reuse hidden tooltip frames.
diff --git a/src/gtkutil.c b/src/gtkutil.c
index d57627f152f..2be84ae60b9 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1327,10 +1327,17 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
   if (FRAME_VISIBLE_P (f) && !was_visible)
     {
       if (CONSP (frame_size_history))
-	frame_size_history_extra
-	  (f, build_string ("xg_frame_set_char_size, visible"),
-	   FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
-	   f->new_width, f->new_height);
+	{
+	  frame_size_history_extra
+	    (f, build_string ("xg_frame_set_char_size, visible"),
+	     FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
+	     f->new_width, f->new_height);
+
+	  if (gwidth > 0 || gheight > 0)
+	    frame_size_history_extra
+	      (f, build_string (" +values"), gwidth, gheight,
+	       outer_width, outer_height, -1, -1);
+	}
 
       /* Must call this to flush out events */
       (void)gtk_events_pending ();
diff --git a/src/xterm.c b/src/xterm.c
index 0c20d38b0f7..07b368601c2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -18873,6 +18873,9 @@ x_find_selection_owner (struct x_display_info *dpyinfo, Atom selection)
 
    We return the number of characters stored into the buffer.  */
 
+static int
+configurenotifycount = 0;
+
 static int
 handle_one_xevent (struct x_display_info *dpyinfo,
 #ifndef HAVE_XINPUT2
@@ -21372,18 +21375,26 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         {
           XNextEvent (dpyinfo->display, &next_event);
           if (next_event.type != ConfigureNotify
-              || next_event.xconfigure.window != event->xconfigure.window
+              || next_event.xconfigure.window != event->xconfigure.window)
+	    {
+	      XPutBackEvent (dpyinfo->display, &next_event);
+	      break;
+	    }
               /* Skipping events with different sizes can lead to a
                  mispositioned mode line at initial window creation.
                  Only drop window motion events for now.  */
-              || next_event.xconfigure.width != event->xconfigure.width
-              || next_event.xconfigure.height != event->xconfigure.height)
+	  else if (next_event.xconfigure.width != event->xconfigure.width
+		   || next_event.xconfigure.height != event->xconfigure.height)
             {
               XPutBackEvent (dpyinfo->display, &next_event);
-              break;
+	      configurenotifycount++;
+	      break;
             }
           else
-	    configureEvent = next_event;
+	    {
+	      configurenotifycount = 0;
+	      configureEvent = next_event;
+	    }
         }
 
       /* If we get a ConfigureNotify for the root window, this means
@@ -21575,12 +21586,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
         {
 
 	  if (CONSP (frame_size_history))
-	    frame_size_history_extra
-	      (f, build_string ("ConfigureNotify"),
-	       FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
-	       configureEvent.xconfigure.width,
-	       configureEvent.xconfigure.height,
-	       f->new_width, f->new_height);
+	    {
+	      frame_size_history_extra
+		(f, build_string ("ConfigureNotify"),
+		 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+		 configureEvent.xconfigure.width,
+		 configureEvent.xconfigure.height,
+		 f->new_width, f->new_height);
+
+	      if (configurenotifycount > 0)
+		frame_size_history_extra
+		  (f, build_string (" +count"),
+		   configurenotifycount, -1, -1, -1, -1, -1);
+	    }
 
 #ifdef HAVE_XDBE
           if (FRAME_X_DOUBLE_BUFFERED_P (f))