Subject: Re: bug#60585: 30.0.50; global-text-scale-adjust shrinks window (was not before), was: Re: bug#52493: 29.0.50; Setting Inconsolata up in init.el makes default face rendered wrong

From: Dmitry Gutov <[email-masked]>
Date: Thu, 9 Feb 2023 21:40:46 +0200

Hi Martin,

Sorry for the pause.

On 30/01/2023 11:28, martin rudalics wrote:
>  > OK, I have done so now.
> 
> Great.  If possible please keep the Lucid build around for a couple of
> days - there are yet a lot of mysteries to solve.

Sure, it's a separate worktree, it can stay around a while.

>  > First of all, they start up with different dimensions: Lucid's is a
>  > bit shorter and narrower. GNOME says Lucid is 78x34 and GTK3 is 79x35.
> 
> Can you try both with unpatched builds?  My unpatched Emacsen start here
> (according to xfce/xfwm4, no scaling) as 80x36 the patched ones as 79x35.

Unpatched Lucid agrees with GNOME (both say 80x36).

GTK3 is 79x36 still, again according to GNOME.

>  > Internally, both think they are 80x36.
> 
> Same here.

Yep.

>  > The end of *foo* for GTK3 contains:
>  >
>  > xg_frame_resized old native pixels 1488x1296 new native pixels 1488x1346
>  > xg_frame_resized old native pixels 1488x1296 new native pixels 1488x1296
>  > xg_wm_set_size_hint scale 2 char width 18 toolbar 0 vscroll 32 
> fringes 16 borders 0 text width 720 base width 33 width inc 9
>  >      char height 36 menubar 50 toolbar 0 hscroll 0 borders 0 text 
> height 648 base height 43 height inc 18
>  > xg_wm_set_size_hint scale 2 char width 18 toolbar 0 vscroll 32 
> fringes 16 borders 0 text width 720 base width 33 width inc 9
>  >      char height 36 menubar 50 toolbar 82 hscroll 0 borders 0 text 
> height 648 base height 84 height inc 18
>  > xg_frame_set_char_size old native pixels 1488x1296 new native pixels 
> 1488x1296 outer pixels 744x714 outer rest 0x0
>  >      base_size 33x84 size increments 9x18 WM hint 79x35
> 
> Can you show me the text pixels values?  These are the ones we should
> compare.  The native values differ because for Lucid the height includes
> the toolbar which we draw ourselves into the rectangle the WM allots to
> us.  GTK draws the toolbar into its own area which is outside the native
> rectangle.

How do I get that numbers?

In case that's relevant, (buffer-text-pixel-size) evaluated in *scratch* 
with its default message returns (1296 . 72).

>  > And for Lucid, it contains:
>  >
>  > EmacsFrameResize old native pixels 1474x1332 new native pixels 1474x1354
>  > EmacsFrameResize old native pixels 1474x1332 new native pixels 1474x1354
>  > adjust_frame_size old native pixels 1474x1332 new native pixels 
> 1474x1354 old text pixels 1440x1296 new text pixels 1440x1296 old text 
> chars 80x36 new text chars 80x36
> 
> Here I would have liked to see the value for the scroll bar - vscroll.
> I suppose these differ on Lucid and GTK.

   window-vscroll is a built-in function in ‘C source code’.

   Return the amount by which WINDOW is scrolled vertically.

Is that the value you were looking for? If not, please tell me how to 
find it.

>  > Lucid's menu bar and tool bar look shorter in height, with less 
> padding. The font size seems to be equal, however.
> 
> When you put the two frames side by side, does the text area start lower
> with GTK?  Here they start at exactly the same pixel position.  I attach
> a screenshot so you can see.

It does. See the attached screenshots with unpatched builds.

>  > And the tool bar icons are scaled on Lucid too.
> 
> Is that the reason for the height difference?

More likely, the reason is smaller padding in the Lucid build -- both in 
the menu and in the toolbar.

>  > I tried to resize them, but (as long as pixelwise resizing is
>  > disabled), they don't match exactly. But if I line them up very close,
>  > GNOME says Lucid (which is slightly larger) is 81x37 and GTK3 is
>  > 80x36. Here are respective logs:
>  >
>  > GTK3:
>  >
>  > xg_frame_resized old native pixels 1506x1296 new native pixels 1488x1296
>  > adjust_frame_size old native pixels 1506x1296 new native pixels 
> 1488x1296 old text pixels 1458x1296 new text pixels 1440x1296 old text 
> chars 81x36 new text chars 80x36
>  >      base_size 33x84 size increments 9x18 WM hint 79x35
>  > xg_frame_resized old native pixels 1488x1296 new native pixels 1488x1332
>  > adjust_frame_size old native pixels 1488x1296 new native pixels 
> 1488x1332 old text pixels 1440x1296 new text pixels 1440x1332 old text 
> chars 80x36 new text chars 80x37
>  >      base_size 33x84 size increments 9x18 WM hint 79x36
>  > xg_frame_resized old native pixels 1488x1332 new native pixels 1506x1332
>  > adjust_frame_size old native pixels 1488x1332 new native pixels 
> 1506x1332 old text pixels 1440x1332 new text pixels 1458x1332 old text 
> chars 80x37 new text chars 81x37
>  >      base_size 33x84 size increments 9x18 WM hint 80x36
>  >
>  > Lucid:
>  >
>  > EmacsFrameResize old native pixels 1492x1354 new native pixels 1492x1390
>  > adjust_frame_size old native pixels 1492x1354 new native pixels 
> 1492x1390 old text pixels 1458x1296 new text pixels 1458x1332 old text 
> chars 81x36 new text chars 81x37
>  > EmacsFrameResize old native pixels 1492x1390 new native pixels 1510x1390
>  > adjust_frame_size old native pixels 1492x1390 new native pixels 
> 1510x1390 old text pixels 1458x1332 new text pixels 1476x1332 old text 
> chars 81x37 new text chars 82x37
>  > EmacsFrameResize old native pixels 1510x1390 new native pixels 1510x1426
>  > adjust_frame_size old native pixels 1510x1390 new native pixels 
> 1510x1426 old text pixels 1476x1332 new text pixels 1476x1368 old text 
> chars 82x37 new text chars 82x38
>  >
>  > Which is to say Lucid's log is slightly inaccurate here because, 
> again, GNOME reports that window to be 81x37.
> 
> Lucid builds do not report the "WM hint" values (yet).  What stupefies
> me most here is one thing: The Lucid build apparently also resizes in
> 18x36 increments although your font should ask for 17x37 pixels and we
> nowhere do any scaling.  Please show me what the Lucid build outputs
> after x_new_font.

If I understood your request correctly:

Here's the output after I evaluate s-f-a for the first time:

x_new_font old char size 18x36 new char size 21x45 text chars 80x36 old 
text pixels 1440x1296 new text pixels 1680x1620
update_wm_hints char width 21 old char width 18 vscroll 16 fringes 16 
borders 2 base width 55 old_base width 52 min width 55 old min width 52
     char height 45 old char height 36 menubar 45 hscroll 0 borders 2 
base height 148 old base height 139 min height 148 old min height 139
EmacsFrameResize old native pixels 1474x1354 new native pixels 1714x1678
EmacsFrameResize old native pixels 1474x1354 new native pixels 1714x1678
adjust_frame_size old native pixels 1474x1354 new native pixels 
1714x1678 old text pixels 1440x1296 new text pixels 1680x1620 old text 
chars 80x36 new text chars 80x36

x_new_font old char size 21x45 new char size 17x37 text chars 80x36 old 
text pixels 1680x1620 new text pixels 1360x1332
update_wm_hints char width 17 old char width 21 vscroll 16 fringes 16 
borders 2 base width 51 old_base width 55 min width 51 old min width 55
     char height 37 old char height 45 menubar 45 hscroll 0 borders 2 
base height 140 old base height 148 min height 140 old min height 148
EmacsFrameResize old native pixels 1714x1678 new native pixels 1394x1390
EmacsFrameResize old native pixels 1714x1678 new native pixels 1394x1390
adjust_frame_size old native pixels 1714x1678 new native pixels 
1394x1390 old text pixels 1680x1620 new text pixels 1360x1332 old text 
chars 80x36 new text chars 80x36

And here's its output when I call s-f-a for the second time:

x_new_font old char size 17x37 new char size 17x37 text chars 80x36 old 
text pixels 1360x1332 new text pixels 1360x1332

x_new_font old char size 17x37 new char size 17x37 text chars 80x36 old 
text pixels 1360x1332 new text pixels 1360x1332

>  > I'm pretty sure, yes. I performed that experiment and observed the 
> log several times.
>  >
>  > Would a counter really help? I guess you'll be able to confirm what 
> I'm saying, but then what? Would that bring any new information?
> 
> Maybe.  You could try putting a breakpoint at x_new_font and, whenever
> it has triggered a second time in a row after you've done
> 'set-face-attribute', show me the backtrace for that second time.  Then
> we could find out what strange force is triggering that.  If you manage
> to do that, we don't need the counter.

I think the above means that x_new_font is called for the second time 
even in the Lucid build. Anyway, with GNOME and the patch:

It is hit twice, and both calls seems to have the same backtrace.

(gdb) xbacktrace
"internal-set-lisp-face-attribute" (0xf09ff218)
"set-face-attribute" (0xffffd8c0)
"progn" (0xffffda70)
"eval" (0xf09ff180)
"elisp--eval-last-sexp" (0xf09ff100)
"eval-last-sexp" (0xffffdc50)
"funcall-interactively" (0xffffdc48)
"call-interactively" (0xf09ff070)
"command-execute" (0xffffdef8)

and

(gdb) backtrace
#0  x_new_font (f=0x5555562f8430, font_object=0x5555569e1a45, 
fontset=-1) at xterm.c:26517
#1  0x00005555555c4656 in gui_set_font (f=0x5555562f8430, 
arg=0x5555568fe364, oldval=0x55555622d224) at frame.c:4733
#2  0x00005555555c1ff9 in gui_set_frame_parameters_1 
(f=f@entry=0x5555562f8430, alist=<optimized out>, 
alist@entry=0x7fffffffd6f3, 
default_parameter=default_parameter@entry=true) at frame.c:4325
#3  0x000055555567fea1 in set_font_frame_param (lface=0x5555562f6e45, 
frame=0x5555562f8435) at xfaces.c:3816
#4  Finternal_set_lisp_face_attribute (face=0x5940, attr=<optimized 
out>, value=<optimized out>, frame=<optimized out>) at xfaces.c:3629
#5  0x000055555567eb38 in Finternal_set_lisp_face_attribute 
(face=0x5940, attr=0xdb0, value=0x5555568fe544, frame=<optimized out>) 
at xfaces.c:3092
...

vs

(gdb) backtrace
#0  x_new_font (f=0x5555562f8430, font_object=0x555556945b6d, 
fontset=-1) at xterm.c:26517
#1  0x00005555555c4656 in gui_set_font (f=0x5555562f8430, 
arg=0x5555563e1e74, oldval=0x5555568fe364) at frame.c:4733
#2  0x00005555555c1ff9 in gui_set_frame_parameters_1 
(f=f@entry=0x5555562f8430, alist=<optimized out>, 
alist@entry=0x7fffffffd6f3, 
default_parameter=default_parameter@entry=true) at frame.c:4325
#3  0x000055555567fea1 in set_font_frame_param (lface=0x5555562f6e45, 
frame=0x5555562f8435) at xfaces.c:3816
#4  Finternal_set_lisp_face_attribute (face=0x5940, attr=<optimized 
out>, value=<optimized out>, frame=<optimized out>) at xfaces.c:3629
#5  0x000055555567eb38 in Finternal_set_lisp_face_attribute 
(face=0x5940, attr=0x1020, value=0x1ba, frame=<optimized out>) at 
xfaces.c:3092
...

What seems to be different between the two are the font_object argument 
to x_new_font and the arguments to Finternal_set_lisp_face_attribute at 
the end of the backtrace.

It seems like they are called twice because my original example sets two 
attributes: :height and :family.

>  > Should we try to circle back to finding the difference between
>  > "InconsolataLGC" and "Inconsolata LGC"? The latter doesn't exhibit
>  > most of the problematic behaviors we have been discussing here.
> 
> The first thing to try would be obvious: Does the latter trigger the
> "two x_new_font entries in *foo* in a row behavior"?

When called for the first time -- yes:

x_new_font old char size 18x36 new char size 21x45 text chars 80x36 old 
text pixels 1440x1296 new text pixels 1680x1620
xg_wm_set_size_hint scale 2 char width 21 toolbar 0 vscroll 32 fringes 
16 borders 0 text width 840 base width 34 width inc 10
     char height 45 menubar 50 toolbar 82 hscroll 0 borders 0 text 
height 810 base height 106 height inc 22
xg_frame_set_char_size old native pixels 1488x1296 new native pixels 
1728x1620 outer pixels 864x876 outer rest 0x0
     base_size 34x106 size increments 10x22 WM hint 83x35
xg_frame_resized old native pixels 1488x1296 new native pixels 1728x1620
adjust_frame_size old native pixels 1488x1296 new native pixels 
1728x1620 old text pixels 1440x1296 new text pixels 1680x1620 old text 
chars 80x36 new text chars 80x36
     base_size 34x106 size increments 10x22 WM hint 83x35

x_new_font old char size 21x45 new char size 17x37 text chars 80x36 old 
text pixels 1680x1620 new text pixels 1360x1332
xg_wm_set_size_hint scale 2 char width 17 toolbar 0 vscroll 32 fringes 
16 borders 0 text width 680 base width 32 width inc 8
     char height 37 menubar 50 toolbar 82 hscroll 0 borders 0 text 
height 666 base height 84 height inc 18
xg_frame_set_char_size old native pixels 1728x1620 new native pixels 
1408x1332 outer pixels 704x732 outer rest 0x0
     base_size 32x84 size increments 8x18 WM hint 84x36
xg_frame_resized old native pixels 1728x1620 new native pixels 1408x1332
adjust_frame_size old native pixels 1728x1620 new native pixels 
1408x1332 old text pixels 1680x1620 new text pixels 1360x1332 old text 
chars 80x36 new text chars 80x36
     base_size 32x84 size increments 8x18 WM hint 84x36

When called the second time -- no:

x_new_font old char size 17x37 new char size 17x37 text chars 80x36 old 
text pixels 1360x1332 new text pixels 1360x1332

When called the third time and further -- no entries are added to *foo* 
at all.

I can resize the frame -- and xg_frame_resized stuff is printed -- but 
when I evaluate the s-f-a form again, still nothing gets added to the 
output. Nor does the frame get resized, naturally.

>  > And when s-f-a is evaluated at dimensions 118x35 with the latter
>  > family name, it first corrects the dimensions slightly to 118x34 (with
>  > like a few pixel difference in height, 2 or 3), and then no subsequent
>  > evaluations of s-f-a change frame dimensions, no matter how I resize
>  > it with a mouse first.
> 
> Please send me the *foo* transcript for that.

...
     base_size 32x84 size increments 8x18 WM hint 118x41
xg_frame_resized old native pixels 1952x1512 new native pixels 1952x1476
adjust_frame_size old native pixels 1952x1512 new native pixels 
1952x1476 old text pixels 1904x1512 new text pixels 1904x1476 old text 
chars 112x40 new text chars 112x39
     base_size 32x84 size increments 8x18 WM hint 118x40
xg_frame_resized old native pixels 1952x1476 new native pixels 1952x1440
adjust_frame_size old native pixels 1952x1476 new native pixels 
1952x1440 old text pixels 1904x1476 new text pixels 1904x1440 old text 
chars 112x39 new text chars 112x38
     base_size 32x84 size increments 8x18 WM hint 118x39
xg_frame_resized old native pixels 1952x1440 new native pixels 1952x1404
adjust_frame_size old native pixels 1952x1440 new native pixels 
1952x1404 old text pixels 1904x1440 new text pixels 1904x1404 old text 
chars 112x38 new text chars 112x37
     base_size 32x84 size increments 8x18 WM hint 118x38
xg_frame_resized old native pixels 1952x1404 new native pixels 1952x1368
adjust_frame_size old native pixels 1952x1404 new native pixels 
1952x1368 old text pixels 1904x1404 new text pixels 1904x1368 old text 
chars 112x37 new text chars 112x36
     base_size 32x84 size increments 8x18 WM hint 118x37
xg_frame_resized old native pixels 1952x1368 new native pixels 1952x1332
adjust_frame_size old native pixels 1952x1368 new native pixels 
1952x1332 old text pixels 1904x1368 new text pixels 1904x1332 old text 
chars 112x36 new text chars 112x36
     base_size 32x84 size increments 8x18 WM hint 118x36
xg_frame_resized old native pixels 1952x1332 new native pixels 1952x1296
adjust_frame_size old native pixels 1952x1332 new native pixels 
1952x1296 old text pixels 1904x1332 new text pixels 1904x1296 old text 
chars 112x36 new text chars 112x35
     base_size 32x84 size increments 8x18 WM hint 118x35

x_new_font old char size 17x37 new char size 17x37 text chars 112x35 old 
text pixels 1904x1296 new text pixels 1904x1295
xg_wm_set_size_hint scale 2 char width 17 toolbar 0 vscroll 32 fringes 
16 borders 0 text width 952 base width 32 width inc 8
     char height 37 menubar 50 toolbar 82 hscroll 0 borders 0 text 
height 647 base height 101 height inc 18
xg_frame_set_char_size old native pixels 1952x1296 new native pixels 
1952x1295 outer pixels 976x713 outer rest 0x0
     base_size 32x101 size increments 8x18 WM hint 118x34
xg_frame_resized old native pixels 1952x1296 new native pixels 1952x1294
adjust_frame_size old native pixels 1952x1296 new native pixels 
1952x1294 old text pixels 1904x1296 new text pixels 1904x1294 old text 
chars 112x35 new text chars 112x34
     base_size 32x101 size increments 8x18 WM hint 118x34

Like mentioned above, the additional s-f-a evaluations don't get 
reflected in the log. I evaluated it about 10 times at the end.

>  > Visually, the resulting text seems identical between these two
>  > fonts. Maybe the former font name is somehow "autocorrected" into the
>  > latter? And that triggers some kind of callback internally that can
>  > additionally resize the frame?
> 
> Maybe fontset_from_font does such a thing.  We'd have to find out first
> whether the values x_new_font finds for font->average_width and
> font_ascent + font_descent differ for the two Inconsolatas.

Anything I can evaluate to find that out?