Subject: Re: bug#73244: Emacs29.3 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.41

From: martin rudalics <[email-masked]>
Date: Mon, 14 Oct 2024 17:58:43 +0200

>>>>>>>>>> The bug I have, since upgrading to Ubuntu 24.04 and install emacs29 is that the initial frame has width x height of 20 x 9, even though I have a .Xresources file containing
 >>>>>>>>>>     Emacs*geometry: 100x40+1900+0
 >>>>>>>>>> end a default-frame-alist of
 >>>>>>>>>>    Value:
 >>>>>>>>>>    ((font . "Monospace-10")
 >>>>>>>>>>     (height . 42)
 >>>>>>>>>>     (width . 90)
 >>>>>>>>>>     (tool-bar-lines . 0)
 >>>>>>>>>>     (menu-bar-lines . 1)
 >>>>>>>>>>     (top . 0)
 >>>>>>>>>>     (left . 1200))
 >>>>>>>>>>    Original value was nil
 >>>>>>>>>> set up by my .emacs file.
 >>>>>>>>>>
 >>>>>>>>>> Using either the pull-down File->New Frame, or C-x 5 2, both generate new frames of the 20 x 9 size.
...
 > Martin, any suggestions or ideas?

Welcome to the club, John.  Some standard questions:

- You're using GNOME desktop and the mutter window manager.  Right?  If
   so, what does mutter --version tell?  Can you try setting the
   environment variable MUTTER_DEBUG="geometry" and then look into stderr
   whether anything shows up there at all?  If so, we could try to
   investigate further.

- Is your screen scaled?

- What does evaluating (frame-geometry) tell for the first frame?  What
   do (frame-char-height) and (frame-char-width) evaluate too?

- Can you build with other toolkits?  GTK2, Lucid, Motif or with the
   --with-x-toolkit=no option?

- Can you build with the attached patch?  If so, please evaluate the
   form (frame--size-history) and post the contents of the the buffer
   *frame-size-history* here.

Thanks, martin

diff --git a/src/frame.c b/src/frame.c
index 7f4bf274ad9..6b6f6aa3c5c 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -6769,7 +6769,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..a02be51600e 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1129,11 +1129,48 @@ xg_set_geometry (struct frame *f)
     }
 }
 
+static struct frame *last_resize_frame = NULL;
+static int last_resize_height = -1;
+static int last_resize_width = -1;
+static int last_resize_count = 0;
+
 /** Function to handle resize of native frame F to WIDTH and HEIGHT
     pixels after we got a ConfigureNotify event.  */
 void
 xg_frame_resized (struct frame *f, int width, int height)
 {
+#ifndef HAVE_PGTK
+  if (f == last_resize_frame
+      && (width != ((last_resize_width * xg_get_scale (f))
+		    - FRAME_TOOLBAR_WIDTH (f))
+	  || height != ((last_resize_height * xg_get_scale (f))
+			- FRAME_MENUBAR_HEIGHT (f)
+			- FRAME_TOOLBAR_HEIGHT (f)))
+      && last_resize_count <= 3)
+    /* We did not get what we wanted, retry.  */
+    {
+      if (CONSP (frame_size_history))
+	frame_size_history_extra
+	  (f, build_string ("xg_frame_resized, rejected"),
+	   FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
+	   last_resize_width, last_resize_height);
+
+      gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+			 last_resize_width, last_resize_height);
+
+      last_resize_count++;
+
+      return;
+    }
+  else
+    /* We either got what we asked for or lost the battle.  */
+    {
+      last_resize_frame = NULL;
+      last_resize_height = -1;
+      last_resize_width = -1;
+      last_resize_count = 0;
+    }
+#endif
   /* Ignore case where size of native rectangle didn't change.  */
   if (width != FRAME_PIXEL_WIDTH (f)
       || height != FRAME_PIXEL_HEIGHT (f)
@@ -1297,19 +1334,20 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
   else
     {
 #ifndef HAVE_PGTK
+      last_resize_frame = f;
+      last_resize_width = outer_width;
+      last_resize_height = outer_height;
+      last_resize_count = 0;
+
       gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 			 outer_width, outer_height);
 #else
       if (FRAME_GTK_OUTER_WIDGET (f))
-	{
-	  gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-			     outer_width, outer_height);
-	}
+	gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+			   outer_width, outer_height);
       else
-	{
-	  gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
-				       outer_width, outer_height);
-	}
+	gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
+				     outer_width, outer_height);
 #endif
       fullscreen = Qnil;
     }
@@ -1327,10 +1365,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 ();