Subject: Re: 31.0.50; Change in fit-frame-to-buffer doesn't work with transient-posframe

From: martin rudalics <[email-masked]>
Date: Wed, 14 May 2025 17:11:08 +0200

>>> 1: height 199
 >>> 2: height 199
 >>> height 199 text-minus-body-height 0
 >>> 1: height 199
 >>> 2: height 216
 >>> remainder 0 text-minus-body-height 0 char-height 18
 >>> height 216 text-minus-body-height 0
[...]
 > First call. At this point, the transient is not yet visible on the
 > display.
 >
 >    fit-frame-to-buffer-1(#<frame window.el 0x10b830000> 55 1 120 83 nil nil nil)
 >    posframe--fit-frame-to-buffer(#<frame window.el 0x10b830000> 55 1 120 83 nil)
 >    posframe--set-frame-size((:posframe #<frame window.el 0x10b830000> :width nil :height nil :max-width 120 :max-height 55 :min-width 83 :min-height 1))
 >    posframe-show(#<buffer  *transient*> :font nil :position 432383 :poshandler posframe-poshandler-frame-center :background-color "gray15" :foreground-color "white" :min-width 83 :internal-border-width 1 :internal-border-color "gray50" :override-parameters nil)
 >    transient-posframe--show-buffer(#<buffer  *transient*> nil)
 >    display-buffer(#<buffer  *transient*> (transient-posframe--show-buffer))
 >    transient--show()
 >    transient--redisplay()
 >    #f(compiled-function () #<bytecode -0x1b4f9e178d9e629f>)()
 >    transient--env-apply(#f(compiled-function () #<bytecode -0x1b4f9e178d9e629f>) #<transient-prefix 2b8339>)
 >    transient-setup(my-grab-bag)
 >    my-grab-bag()

The mysterious thing is that in the first call 'fit-frame-to-buffer-1'
did _not_ round from 199 to 216.

 > Second call. The child frame is visible already.
 >
 >    fit-frame-to-buffer-1(#<frame  0x10b830000> nil nil nil 83 nil t t)
 >    fit-frame-to-buffer(#<frame  0x10b830000> nil nil nil 83)
 >    transient--fit-window-to-buffer(#<window 14 on  *transient*>)
 >    transient--show()
 >    transient--redisplay()
 >    #f(compiled-function () #<bytecode -0x1b4f9e178d9e629f>)()
 >    transient--env-apply(#f(compiled-function () #<bytecode -0x1b4f9e178d9e629f>) #<transient-prefix 2b8339>)
 >    transient-setup(my-grab-bag)
 >    my-grab-bag()
 >
 > Naively, I would assume that that all happens in the same
 > transient--redisplay -> transient--show, but I'm not sure of course.

And in the second call it did round.  But note that this call has many
arguments that differ from the first.

 > The fit-frame-to-buffer in the second case is from here:

And that from the first case?

 > (defun transient--fit-window-to-buffer (window)
 >    (set-window-parameter window 'window-preserved-size nil)
 >    (let ((fit-window-to-buffer-horizontally t)
 >          (window-resize-pixelwise t)
 >          (window-size-fixed nil))
 >      (cond ((not (window-parent window))
 >             (fit-frame-to-buffer (window-frame window) nil nil nil
 >                                  transient-minimal-frame-width))
 >            ((eq (car (window-parameter window 'quit-restore)) 'other)
 >             ;; Grow but never shrink window that previously displayed
 >             ;; another buffer and is going to display that again.
 >             (fit-window-to-buffer window nil (window-height window)))
 >            ((fit-window-to-buffer window nil 1))))
 >    (set-window-parameter window 'window-preserved-size
 >                          (list (window-buffer window)
 >                                (window-body-width window t)
 >                                (window-body-height window t))))
 >
 > Should that have bound frame-resize-pixelwise?

It should _not_ since 'frame-resize-pixelwise' is a user variable.

 > I think I
 > understand more or less what the doc string of that variable says, but
 > the transient doesn't have anything I recognize that would make
 > pixel-wise resizing necessary. Or is some internal border or something?
 > Sorry, I'm in unknown territory here.

If 'fit-frame-to-buffer' resizes pixelwise and 'frame-resize-pixelwise'
is globally nil, the WM may round down to character sizes which usually
means that text gets truncated.

martin