GNU bug report logs - #74750
clone-frame and make-frame pixelwise issues

Previous Next

Package: emacs;

Reported by: Ship Mints <shipmints <at> gmail.com>

Date: Mon, 9 Dec 2024 15:53:02 UTC

Severity: normal

Done: martin rudalics <rudalics <at> gmx.at>

Bug is archived. No further changes may be made.

Full log


Message #8 received at 74750 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Ship Mints <shipmints <at> gmail.com>, martin rudalics <rudalics <at> gmx.at>
Cc: 74750 <at> debbugs.gnu.org
Subject: Re: bug#74750: clone-frame and make-frame pixelwise issues
Date: Tue, 10 Dec 2024 14:27:25 +0200
> From: Ship Mints <shipmints <at> gmail.com>
> Date: Mon, 9 Dec 2024 10:51:23 -0500
> 
> While trying to reconcile pixelwise frame sizing behaviors, I narrowed down
> two related issues.
> 
> clone-frame does not correctly clone frames on a pixelwise basis.
> 
> make-frame's text-pixels geometry support does not produce specified
> pixelwise geometry. This also impacts frameset-restore's ability to
> precisely reproduce pixelwise frame sizes.
> 
> I consider these to be related as clone-frame's use of make-frame could be
> using text-pixels but if that doesn't work then pixelwise cloning won't
> work. I did read through the code base as best as I could but could not
> find the source of the text-pixels issue.
> 
> The following reproducer, under -Q, shows the same results on 29.4 and
> 30.0.92. My main platform is NS and I also did some testing on GTK. GTK's
> issues seem a bit "messier" and I didn't spend any time trying to
> understand them in depth as I was more interested to know if GTK worked
> correctly or not, which it doesn't.
> 
> (switch-to-buffer "*Messages*")
> (let ((target-text-width 1700)
>       (target-text-height 1000)
>       (native-width)
>       (native-height)
>       (msg (lambda (s frame)
>              (message "%s text-width=%d (Δ%d) text-height=%d (Δ%d)
> native-width=%d (Δ%d) native-height %d (Δ%d)\n"
>                       s
>                       (frame-text-width frame) (- (frame-text-width frame)
> target-text-width)
>                       (frame-text-height frame) (- (frame-text-height
> frame) target-text-height)
>                       (frame-native-width frame) (- (frame-native-width
> frame) native-width)
>                       (frame-native-height frame) (- (frame-native-height
> frame) native-height)))))
>   (set-frame-position nil 0 0)
>   (set-frame-size nil target-text-width target-text-height 'pixelwise)
>   (setq native-width (frame-native-width)
>         native-height (frame-native-height))
>   (message "Targets: text-width=%d text-height=%d\n" target-text-width
> target-text-height)
>   (funcall msg "orig" (selected-frame))
> 
>   (message "clone-frame under frame-resize-pixelwise nil; expectation: use
> lines/columns geometry; outcome: met")
>   (let ((frame-resize-pixelwise nil))
>     (let ((new-frame (clone-frame)))
>       (funcall msg "new" new-frame)
>       (delete-frame new-frame)))
> 
>   (message "clone-frame under frame-resize-pixelwise t; expectation:
> pixelwise geometry; outcome: unmet")
>   (let ((frame-resize-pixelwise t))
>     (let ((new-frame (clone-frame)))
>       (funcall msg "new" new-frame)
>       (delete-frame new-frame)))
> 
>   (message "clone-frame followed by manual resize; expectation: pixelwise
> geometry; outcome: met (but two steps)")
>   (let ((new-frame (clone-frame)))
>     (set-frame-size new-frame target-text-width target-text-height
> 'pixelwise)
>     (funcall msg "new" new-frame)
>     (delete-frame new-frame))
> 
>   (message "manual clone under frame-resize-pixelwise using text-pixels;
> expectation: pixelwise geometry; outcome: unmet")
>   ;; code lifted from clone-frame
>   ;; incorrect width offset seems to be equal to frame-scroll-bar-width
>   (let* ((frame-resize-pixelwise t)
>          (frame (selected-frame))
>          (no-windows nil)
>          (windows (unless no-windows
>                     (window-state-get (frame-root-window frame))))
>          (default-frame-alist
>           (seq-remove (lambda (elem)
>                         (memq (car elem) frame-internal-parameters))
>                       (frame-parameters frame)))
>          (new-frame))
>     (when (and (display-graphic-p frame) frame-resize-pixelwise)
>       (push (cons 'width (cons 'text-pixels (frame-text-width frame)))
> default-frame-alist)
>       (push (cons 'height (cons 'text-pixels (frame-text-height frame)))
> default-frame-alist))
>     (setq new-frame (make-frame))
>     (when windows
>       (window-state-put windows (frame-root-window new-frame) 'safe))
>     (unless (display-graphic-p frame)
>       (select-frame new-frame))
>     (funcall msg "new" new-frame)
>     (delete-frame new-frame)))
> 
> This is an implementation of clone-frame that uses text-pixels under
> make-frame. This depends on make-frame text-pixels being corrected. Happy
> to supply this as a patch should the discussion of these issues progress in
> that direction.
> 
> (defun clone-frame (&optional frame no-windows pixelwise)
>   "Make a new frame with the same parameters and windows as FRAME.
> With a prefix arg NO-WINDOWS, don't clone the window configuration.  When
> PIXELWISE is non-nil or if `frame-resize-pixelwise' is non-nil, and frame
> is not text-only, clone the originating frame's pixel size.
> 
> FRAME defaults to the selected frame.  The frame is created on the
> same terminal as FRAME.  If the terminal is a text-only terminal then
> also select the new frame."
>   (interactive (list (selected-frame) current-prefix-arg))
>   (let* ((frame (or frame (selected-frame)))
>          (windows (unless no-windows
>                     (window-state-get (frame-root-window frame))))
>          (default-frame-alist
>           (seq-remove (lambda (elem)
>                         (memq (car elem) frame-internal-parameters))
>                       (frame-parameters frame)))
>          (new-frame))
>     (when (and (display-graphic-p frame)
>                (or pixelwise frame-resize-pixelwise))
>       (push (cons 'width (cons 'text-pixels (frame-text-width frame)))
>             default-frame-alist)
>       (push (cons 'height (cons 'text-pixels (frame-text-height frame)))
>             default-frame-alist))
>     (setq new-frame (make-frame))
>     (when windows
>       (window-state-put windows (frame-root-window new-frame) 'safe))
>     (unless (display-graphic-p frame)
>       (select-frame new-frame))
>     new-frame))

Thanks.  I hope Martin (CC'ed) will have some useful inputs.




This bug report was last modified 225 days ago.

Previous Next


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