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
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, tumashu <at> 163.com Subject: bug#78418: 31.0.50; Change in fit-frame-to-buffer doesn't work with transient-posframe Date: Wed, 14 May 2025 18:20:14 +0200
martin rudalics <rudalics <at> gmx.at> writes: >>>> 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? That's posframe.el: 840 (defun posframe--fit-frame-to-buffer (posframe max-height min-height max-width min-width only) 841 "POSFRAME version of function `fit-frame-to-buffer'. 842 Arguments HEIGHT, MAX-HEIGHT, MIN-HEIGHT, WIDTH, MAX-WIDTH, 843 MIN-WIDTH and ONLY are similar function `fit-frame-to-buffer''s." 844 ;; This only has effect if the user set the latter var to `hide'. 845 (let ((x-gtk-resize-child-frames posframe-gtk-resize-child-frames)) 846 ;; More info: Don't skip empty lines when fitting mini frame to buffer (Bug#44080) 847 ;; http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=e0de9f3295b4c46cb7198ec0b9634809d7b7a36d 848 (if (functionp 'fit-frame-to-buffer-1) 849 (fit-frame-to-buffer-1 850 posframe max-height min-height max-width min-width only nil nil) 851 (fit-frame-to-buffer 852 posframe max-height min-height max-width min-width only)))) And after some digging, I found several bindings for frame-resize-pixel-wise, for example in posframe-show which is in the backtrace. posframe.el: 419 (window-tab-line-height) 420 0)) 421 (mouse-position (cdr (mouse-pixel-position))) 422 (frame-resize-pixelwise t) 423 posframe) If I understand correctly what you write further down, this should not be done, right? (Feng Shu <tumashu <at> 163.com> added to CC, the posframe author). Si I guess that explains that difference. > >> (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. If you express it that way, I almost understand what it does :-). So, if my WM is not ever rounding down, I should set it to t? Might be a good default for macOS...
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.