Subject: bug#38705: 26.3; set-frame-size pixelwise makes frame larger

From: [email-masked]
Date: Tue, 24 Dec 2019 22:49:55 +0900

martin rudalics <[email-masked]> writes:

> Right.  But here
>
> (progn (set-frame-size nil 500 500 t)
>        (list (list (frame-outer-width)
>                    (frame-pixel-width)
>                    (frame-inner-width)
>                    (frame-text-width))
>              (list (frame-outer-height)
>                    (frame-pixel-height)
>                    (frame-inner-height)
>                    (frame-text-height))))
> =>((540 532 532 500) (583 536 536 500))
>
> This is because 'set-frame-size' sets "the size of the text area of
> FRAME" and the size of the text area is returned by 'frame-text-width'
> and 'frame-text-height'.  Just another Emacs idiosyncrasy ...
>
> martin

I tried to set up the frame outer size like below.
  ;;; sample ~/.emacs.d/init.el
  (defun test-set-frame-outer-size (frame width height)
    (set-frame-size frame width height t)
    (set-frame-size frame
                    (- width  (- (frame-outer-width  frame) width))
                    (- height (- (frame-outer-height frame) height))
                    t))
  (setq frame-inhibit-implied-resize t)
  (test-set-frame-outer-size nil 500 500)
  ;;; sample ~/.emacs.d/init.el end

But the function does not work well inside init.el.
After emacs started, the size is:
  (list (frame-outer-width) (frame-outer-height))
  =>(500 502)
When user input is allowed, evaluating
  (test-set-frame-outer-size nil 500 500)
works as expected.

About another point.
If the frame has no menu-bar, tool-bar, scroll-bar nor fringes,
frame-pixel-width and frame-pixel-height can be set by set-frame-size.
But if the frame is undecorated, the outer size is as large as the size
of non-undecorated frame regardless of the value of
frame-inhibit-implied-resize. 
The inner size is enlarged to the outer size after redisplay.
The size can not be set as expected.
  (let ((width 500) (height 500)
        (params '((undecorated . t)
                  (menu-bar-lines . 0)
                  (tool-bar-lines . 0)
                  (horizontal-scroll-bars . nil)
                  (vertical-scroll-bars . nil)
                  (left-fringe . 0)
                  (right-fringe . 0)))
        (f (lambda () (list (list (frame-outer-width)
                                  (frame-inner-width))
                            (list (frame-outer-height)
                                  (frame-inner-height))))))
    (setq frame-inhibit-implied-resize t)
    (modify-frame-parameters nil params)
    (set-frame-size nil width height t)
    (list (funcall f)
          (progn (redisplay) (funcall f))))
  =>(((516 500) (539 500)) ((516 516) (539 539)))

If the form above is evaluated twice, the frame outer size stays
516x539 pixels and the inner size shrinks to 500x500 pixels.
The inner text area is displayed at the top-left,
and there are blank areas at the right and the bottom.