Subject: Re: bug#52493: 29.0.50; Setting Inconsolata up in init.el makes default face rendered wrong

From: martin rudalics <[email-masked]>
Date: Wed, 28 Dec 2022 11:08:34 +0100

> Here you go, three attachments.

Thank you, they now contain all we need.

 > As you previously guessed, the effect didn't show up when the scaling was off, or when resize-pixelwise was enabled.

In both cases we don't scale.  Scaling introduces a rounding effect
mutter apparently doesn't like.  Take, for example, these lines of
foo-with-scaling.txt produced when we set a new font (actually the first
line belongs to the previous request and is here only to show that we
start with a frame of 35 lines):

adjust_frame_size .. old pixels/lines .. 1296 .. 36 .. new pixels/lines .. 1584 .. 35
x_new_font .. line_height .. 37 .. lines .. 35 .. new_text_height .. 1295
xg_wm_set_size_hint .. line_height & scale .. 37 .. 2 .. base_height .. 84 .. height_inc .. 18
   menubar_height .. 50 .. toolbar_height .. 82
xg_frame_set_char_size .. old .. 1584 .. arg .. 1295 .. new .. -1
   outer .. 713 .. gheight .. 858
xg_frame_resized .. old .. 1584 .. req .. -1 .. con/text .. 1260 .. 1260
adjust_frame_size .. old pixels/lines .. 1584 .. 35 .. new pixels/lines .. 1260 .. 34

The base_height value (84 pixels) we calculate here is the sum of the
line_height value, the menubar_height value and the toolbar_height
values divided by the scale factor:

(/ (+ 37 50 82) 2)

height_inc (18) is the line height divided by the scale factor (/ 37 2).

These size hints have mutter expect us to resize our frame to something
like

(+ base_height (* height_inc N))

for some positive integer N.  Now we want to resize the frame to
line_height times lines, that is (* 37 35) yielding 1295 pixels.

But (% (/ 1295 2) 18) is not zero and so mutter declines our request
giving us 1260 pixels text height instead.  Apparently, mutter starts
with (/ 1295 2) that is 647, 630 is the next multiple of 18 it finds, so
(* 630 2) is the value it concedes us.

So the height we should ask for with scaling is 1296 instead of 1295.

Please try the attached patch - I can't test it here because I don't
scale.  If it doesn't work, please post the contents of *foo* as usual.

Thanks, martin

diff --git a/lisp/window.el b/lisp/window.el
index a11293d372..3d064e12d7 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -10596,6 +10596,17 @@ window-prefix-map
   "0" #'delete-windows-on)
 (define-key ctl-x-map "w" window-prefix-map)
 
+(defun foo-it (&rest rest)
+  (with-current-buffer (get-buffer-create "*foo*")
+    (goto-char (point-max))
+    (when rest
+      (insert (format "%s" (car rest)))
+      (setq rest (cdr rest))
+      (while rest
+	(insert (format " .. %s" (car rest)))
+	(setq rest (cdr rest)))
+      (insert "\n"))))
+
 (provide 'window)
 
 ;;; window.el ends here
diff --git a/src/frame.c b/src/frame.c
index b57b296be5..4501c8dc14 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -906,6 +906,14 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
 
   unblock_input ();
 
+  if (old_native_height != new_native_height
+      || old_text_lines != new_text_lines)
+    call7 (Qfoo_it, intern ("adjust_frame_size"),
+	   intern ("old pixels/lines"), make_fixnum (old_native_height),
+	   make_fixnum (old_text_lines),
+	   intern ("new pixels/lines"), make_fixnum (new_native_height),
+	   make_fixnum (new_text_lines));
+
 #ifdef HAVE_WINDOW_SYSTEM
   {
     /* Adjust size of F's child frames.  */
diff --git a/src/gtkutil.c b/src/gtkutil.c
index a6bba096a4..681cbcd52c 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1149,6 +1149,13 @@ xg_frame_resized (struct frame *f, int width, int height)
 	   f->new_size_p ? f->new_height : -1);
 
       FRAME_RIF (f)->clear_under_internal_border (f);
+
+      call8 (Qfoo_it, intern ("xg_frame_resized"),
+	     intern ("old"), make_fixnum (FRAME_PIXEL_HEIGHT (f)),
+	     intern ("req"), make_fixnum (f->new_height),
+	     intern ("con/text"), make_fixnum (height),
+	     make_fixnum (FRAME_PIXEL_TO_TEXT_HEIGHT (f, height)));
+
       change_frame_size (f, width, height, false, true, false);
       SET_FRAME_GARBAGED (f);
       cancel_mouse_face (f);
@@ -1174,6 +1181,23 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
   int outer_width = width + FRAME_TOOLBAR_WIDTH (f);
   bool was_visible = false;
   bool hide_child_frame;
+  int scale = xg_get_scale (f);
+
+  if (scale != 1 && !frame_resize_pixelwise)
+    {
+      if (FRAME_COLUMN_WIDTH (f) % 2 != 0)
+	{
+	  width = FRAME_COLS (f) * (FRAME_COLUMN_WIDTH (f) + 1);
+	  outer_width = width + FRAME_TOOLBAR_WIDTH (f);
+	}
+
+      if (FRAME_LINE_HEIGHT (f) % 2 != 0)
+	{
+	  height = FRAME_LINES (f) * (FRAME_LINE_HEIGHT (f) + 1);
+	  outer_height
+	    = height + FRAME_TOOLBAR_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
+	}
+    }
 
 #ifndef HAVE_PGTK
   gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
@@ -1196,8 +1220,8 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
   /* Do this before resize, as we don't know yet if we will be resized.  */
   FRAME_RIF (f)->clear_under_internal_border (f);
 
-  outer_height /= xg_get_scale (f);
-  outer_width /= xg_get_scale (f);
+  outer_height /= scale;
+  outer_width /= scale;
 
   xg_wm_set_size_hint (f, 0, 0);
 
@@ -1317,6 +1341,14 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
   SET_FRAME_GARBAGED (f);
   cancel_mouse_face (f);
 
+  call7 (Qfoo_it, intern ("xg_frame_set_char_size"),
+	 intern ("old"), make_fixnum (FRAME_PIXEL_HEIGHT (f)),
+	 intern ("arg"), make_fixnum (height),
+	 intern ("new"), make_fixnum (f->new_height));
+  call4 (Qfoo_it,
+	 intern ("  outer"), make_fixnum (outer_height),
+	 intern ("gheight"), make_fixnum (gheight));
+
   /* We can not call change_frame_size for a mapped frame,
      we can not set pixel width/height either.  The window manager may
      override our resize request, XMonad does this all the time.
@@ -2028,6 +2060,13 @@ xg_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
 		 &f->output_data.xp->size_hints,
 		 sizeof (size_hints)) != 0)
     {
+      call8 (Qfoo_it, intern ("xg_wm_set_size_hint"),
+	     intern ("line_height & scale"),
+	     make_fixnum (FRAME_LINE_HEIGHT (f)), make_fixnum (scale),
+	     intern ("base_height"), make_fixnum (size_hints.base_height),
+	     intern ("height_inc"), make_fixnum (size_hints.height_inc));
+      call4 (Qfoo_it, intern ("  menubar_height"), make_fixnum (FRAME_MENUBAR_HEIGHT (f)),
+	     intern ("toolbar_height"), make_fixnum (FRAME_TOOLBAR_HEIGHT (f)));
       block_input ();
       gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
                                      NULL, &size_hints, hint_flags);
diff --git a/src/window.c b/src/window.c
index f116b9a9d7..c090f29461 100644
--- a/src/window.c
+++ b/src/window.c
@@ -8394,6 +8394,7 @@ syms_of_window (void)
   DEFSYM (Qheader_line_format, "header-line-format");
   DEFSYM (Qtab_line_format, "tab-line-format");
   DEFSYM (Qno_other_window, "no-other-window");
+  DEFSYM (Qfoo_it, "foo-it");
 
   DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function,
 	       doc: /* Non-nil means call as function to display a help buffer.
diff --git a/src/xterm.c b/src/xterm.c
index 7eaf59d54b..277b53043a 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -26197,9 +26197,17 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
      because it's done in Fx_show_tip, and it leads to problems because
      the tip frame has no widget.  */
   if (FRAME_X_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f))
-    adjust_frame_size
-      (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
-       FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont);
+    {
+      call7 (Qfoo_it, intern ("x_new_font"),
+	     intern ("line_height"), make_fixnum (FRAME_LINE_HEIGHT (f)),
+	     intern ("lines"), make_fixnum (FRAME_LINES (f)),
+	     intern ("new_text_height"),
+	     make_fixnum (FRAME_LINES (f) * FRAME_LINE_HEIGHT (f)));
+
+      adjust_frame_size
+	(f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+	 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont);
+    }
 
 #ifdef HAVE_X_I18N
   if (FRAME_XIC (f)