GNU bug report logs - #78418
31.0.50; Change in fit-frame-to-buffer doesn't work with transient-posframe

Previous Next

Package: emacs;

Reported by: Gerd Möllmann <gerd.moellmann <at> gmail.com>

Date: Wed, 14 May 2025 07:22:01 UTC

Severity: normal

Found in version 31.0.50

Full log


View this message in rfc822 format

From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
To: martin rudalics <rudalics <at> gmx.at>
Cc: yhaoxie <at> gmail.com, 78418 <at> debbugs.gnu.org
Subject: bug#78418: 31.0.50; Change in fit-frame-to-buffer doesn't work with transient-posframe
Date: Wed, 14 May 2025 16:14:22 +0200
martin rudalics <rudalics <at> gmx.at> writes:

>> I see that the function is apparently called twice?
>
> Can you try to find out why?
>
>> And the output is
>>
>> 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
>>
>> Maybe the second '2:...' is what increases the frame size?
>
> I think so.  216 is the smallest multiple of 18 at least as large as
> 199.  That's what you will get anyway and should have happened also
> before my commit.  In a sense your were even lucky because if remainder
> were non-zero, it might have added another 17.  I probably should
> collapse these so at most 17 are added.
>
> But anyone who uses 'fit-frame-to-buffer' should have set
> 'frame-resize-pixelwise' to t.

I can't make much sense of it, ATM, but here's what I see. M-x
my-grab-bag is a transient.

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()

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.
The fit-frame-to-buffer in the second case is from here:

(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? And if so why? 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.




This bug report was last modified 87 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.