unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: martin rudalics via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Stefan Kangas <stefankangas@gmail.com>, Toomas Rosin <toomas@rosin.ee>
Cc: Eli Zaretskii <eliz@gnu.org>, 74866@debbugs.gnu.org
Subject: bug#74866: 29.4; fit-frame-to-window + no vertical scroll bar + ch
Date: Mon, 23 Dec 2024 18:59:50 +0100	[thread overview]
Message-ID: <44136318-1e16-406b-984f-b760f5fa4f8f@gmx.at> (raw)
In-Reply-To: <7e7b4037-5f71-4c74-9a93-2db76d2eb86e@gmx.at>

 > Whether 'set-face-attribute' DTRT and how it is involved in the scenario
 > at hand is a question I'd prefer not to answer.  If it affects the
 > canonical line height or column width of a frame, it should find its way
 > into the size hints for each frame.  Otherwise, chaos may result.

I now analyzed the problem and came to the conclusion below.  Note that
the scenario below is interesting only for window systems that employ
size hints as is the case for most GNU/Linux based systems.  The problem
cannot be seen on Windows, for example, because it does not use size
hints.

With emacs -Q of the release version put the following code into
*scratch* (which is the code from the OP plus two commented lines).

(defun fit (lin col)
   "Fit some text (LIN lines and COL columns) into a newly created frame."
   (interactive)
   (let ((buf (get-buffer-create "*bar*"))
         (frm (make-frame '((z-group . above)))))
     (with-current-buffer buf
       (erase-buffer)
       (setq mode-line-format '(""))
       (dotimes (_ lin) (insert (format "%s\n" (make-string col ?x))))
       (goto-char (point-min)))
     (with-selected-frame frm
       (switch-to-buffer buf)
       (fit-frame-to-buffer))))
;;; LIN and COL are arbitrary, make them sufficiently small.

;; (setq frame-resize-pixelwise t)
(setq-default vertical-scroll-bar nil)
(set-face-attribute 'default nil :height 75)
(fit 9 23)
;; (eval-buffer)

Now first evaluate the

(set-face-attribute 'default nil :height 75)

line to shrink the selected frame.  Note that if you call 'eval-buffer'
immediately, total chaos will ensue because the face attribute handling
code will annihilate any previous attempt to fit the frame.

Next evaluate the buffer.  You should see a new frame with wrapped
lines.  Now uncomment the

;; (setq frame-resize-pixelwise t)

line and eval the buffer again.  You should see a new frame fitting the
buffer.

What goes wrong when you see wrapped lines?

'fit-frame-to-buffer-1' inherently (assuming a fixed width font and
other simplifications) calculates the frame width by multiplying the
frame's character width (6 pixels) with the number of characters on the
longest line (23) resulting in 138 pixels.  It adds 16 pixels for the
fringes resulting in a requested width of 154 pixels.  Emacs asks the
window manager via xg_frame_set_char_size to set the width to 154 pixels
but the window manager allots us only 152 pixels.  Emacs concurs and
wraps the lines.

The reason for this is deeply rooted in the way we calculate size hints.
Emacs sets the base width of the frame to 32 pixels here (16 for the
widths of the frame's fringes, 16 for the scroll bar width).  So we have
a "variable" frame width of 154 - 32 = 122 pixels.  At the same time
Emacs sets the width increment to the frame's default character width.
Now the nearest multiple of 6 to 122 is 120 and that's the number of
pixels the window manager gives us.

I now installed a workaround in 'fit-frame-to-buffer-1' on master to
make the frame at least as large as needed to not wrap lines in such a
case (hopefully, it does not break anything on systems that do not use
size hints).

On the Emacs I daily use I do not see the problem because I calculate
size hints in a way that adds the "missing" 2 pixels to the base width -
resulting in a base width of 34 pixels and a "variable" width of 120
pixels.  If and when I feel that it's save to install it, I will do that
on master.  Till then either live with the workaround or either remove
the scroll bar from the frame (and not from the buffer) or set
'frame-resize-pixelwise' to t.

martin







      reply	other threads:[~2024-12-23 17:59 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-14 12:57 bug#74866: 29.4; fit-frame-to-window + no vertical scroll bar + changed face height = mess toomas
2024-12-14 13:26 ` Eli Zaretskii
2024-12-14 17:16   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-14 19:09     ` bug#74866: 29.4; fit-frame-to-window + no vertical scroll bar + ch Toomas Rosin
2024-12-17 13:07       ` Stefan Kangas
2024-12-17 13:15         ` Toomas Rosin
2024-12-18 10:05         ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-23 17:59           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44136318-1e16-406b-984f-b760f5fa4f8f@gmx.at \
    --to=bug-gnu-emacs@gnu.org \
    --cc=74866@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=rudalics@gmx.at \
    --cc=stefankangas@gmail.com \
    --cc=toomas@rosin.ee \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).