Subject: bug#60585: 30.0.50; global-text-scale-adjust shrinks window (was not before)

From: martin rudalics <[email-masked]>
Date: Sat, 14 Jan 2023 11:24:35 +0100

> I missed your instructions, then I pulled new Emacs, did the patch,
 > and now I can't see shrinking of window in Lucid build.

Thank you.  This looks better than I expected.

 > Did anything change in meantime?

No.  If this was the first time you applied a patch, something might
have easily gone wrong.  Don't worry.

 > adjust_frame_size old native pixels 80x25 new native pixels 80x25 old text pixels 80x25 new text pixels 80x24 old text chars 80x25 new text chars 80x24
 > adjust_frame_size old native pixels 80x25 new native pixels 818x552 old text pixels 80x25 new text pixels 800x550 old text chars 80x25 new text chars 80x25
 > adjust_frame_size old native pixels 818x552 new native pixels 818x574 old text pixels 800x550 new text pixels 800x550 old text chars 80x25 new text chars 80x25
 > adjust_frame_size old native pixels 818x574 new native pixels 818x828 old text pixels 800x550 new text pixels 800x792 old text chars 80x25 new text chars 80x36
 > update_from_various_frame_slots native pixels 818x828
 > set_frame_size native pixels 818x828
 > update_wm_hints char width 10 vscroll 0 fringes 16 borders 2 base width 28 min width 28
 >      char height 22 menubar 0 hscroll 0 borders 2 base height 58 min height 58
 > EmacsFrameResize old native pixels 818x828 new native pixels 818x828
 > update_wm_hints char width 10 vscroll 0 fringes 16 borders 2 base width 28 min width 28
 >      char height 22 menubar 0 hscroll 0 borders 2 base height 58 min height 58
 > adjust_frame_size old native pixels 818x828 new native pixels 834x828 old text pixels 800x792 new text pixels 800x792 old text chars 80x36 new text chars 80x36

Note the "new text chars 80x36" at the end of the last line.  This
should appear in any run on a graphic display.  It means that we were
able to set up the initial frame size as we intended.  Earlier on this
line you will notice that the native width of the frame increased from
818 to 834 pixels.  The 16 pixels stem from the fringes, the vertical
scroll bar has not been counted yet.

 > EmacsFrameResize old native pixels 834x828 new native pixels 818x795

Here we apparently try to account for the scroll bar width (the 16
pixels from 834 to 828) and the tool bar (33 pixels from 828 to 795).
The widget builds apparently have to detract these values from the
native rectangle to keep the number of lines and columns constant.  I
never understood the widget code.

 > update_wm_hints char width 10 vscroll 16 fringes 16 borders 2 base width 48 min width 48
 >      char height 22 menubar 33 hscroll 0 borders 2 base height 102 min height 102

I elided many identical update_wm_hints lines here.  Something's wrong,
presumably with that memcmp call in update_wm_hints.

 > adjust_frame_size old native pixels 834x828 new native pixels 834x830 old text pixels 800x792 new text pixels 800x792 old text chars 80x36 new text chars 80x36

Whatever the code did, we have the expected (* 80 10) 800 and (* 22 36)
792 integral text pixels here.  Now things get interesting.

 > x_new_font old char size 10x22 new char size 11x23 text chars 80x36 old text pixels 800x792 new text pixels 880x828

Here you ask (presumably via 'global-text-scale-adjust') to increase the
character size of the default font from 10x22 to 11x23 pixels.  This
means that if we want to keep the frame's pixel size constant, we have
to shrink its text character width (apparently from 80 to 72) and its
text character height (from 36 to 34).

 > adjust_frame_size old native pixels 834x830 new native pixels 834x830 old text pixels 800x792 new text pixels 800x792 old text chars 80x36 new text chars 72x34

Here you can see that both, native and text size in pixels remain
unaltered which is what we wanted to achieve.  And note that here
neither (* 72 11) equals 800 nor does (* 34 23) equal 792.  So the text
sizes in pixels are no more integral multiples of the sizes in terms of
characters.

I still think that 'global-text-scale-adjust' should not modify the
default font but maybe this ship has sailed.  And I suppose that with
WMs like yours this problem might bite us in other occasions as well.

 > EmacsFrameResize old native pixels 834x830 new native pixels 834x830
 > update_wm_hints char width 11 vscroll 16 fringes 16 borders 2 base width 53 min width 53
 >      char height 23 menubar 33 hscroll 0 borders 2 base height 104 min height 104

And here you can see that both the base width and the base height
changed - something our code never did before.

 > x_new_font old char size 11x23 new char size 10x22 text chars 72x34 old text pixels 800x792 new text pixels 720x748

Here, IIUC you size back to the initial size ...

 > adjust_frame_size old native pixels 834x830 new native pixels 834x830 old text pixels 800x792 new text pixels 800x792 old text chars 72x34 new text chars 80x36

... and while Emacs restores to our initial 80x36 text chars sizes and
keeps the pixel sizes constant ...

 > EmacsFrameResize old native pixels 834x830 new native pixels 834x830
 > update_wm_hints char width 10 vscroll 16 fringes 16 borders 2 base width 44 min width 44
 >      char height 22 menubar 33 hscroll 0 borders 2 base height 93 min height 93

... the base size hints go somewhere else (from 48x102 to 44x93) which
apparently doesn't harm.

For the rest of the experiment note that if things don't go wrong, in
each line headed by adjust_frame_size like

 > adjust_frame_size old native pixels 834x830 new native pixels 834x830 old text pixels 800x792 new text pixels 800x792 old text chars 80x36 new text chars 80x37

both old and next text and native pixels should have the same value
after each 'global-text-scale-adjust' call which means that the frame
size did not change visually.

I invite you to conduct this experiment further and also intersperse
manual frame resizes (using the mouse) in between.  The idea is that no
unexpected or strange resizing should happen any more.

Good luck, martin