Emacs: default-frame-alist setting is ignored

2019-04-11 23:44发布

问题:

I would like all frames to overlap at (1,1). Yet with a .emacs containing

(setq initial-frame-alist
      '((top . 1) (left . 1) (width . 80) (height . 55)))

(setq default-frame-alist
      '((top . 1) (left . 1) (width . 80) (height . 55)))

calling C-x 5 2 results in frames in a cascade, as you see in the figure.

How can I force all frames to be anchored at the same place?

I am running Emacs 23.3.1 on OS X (Mountain Lion).

回答1:

The settings are not being ignored. The reason you see the above behaviour is due to a before-make-frame-hook in ns-win.el that adds 25 to top and left.

To avoid the above effect you can add the following to your .emacs file:

(setq default-frame-alist '((left . 0) (top . 0) (width . 80) (height . 55)))
(defvar parameters)
(add-hook 'before-make-frame-hook 
  (lambda ()
    (let ((left (cdr (assq 'left (frame-parameters))))
      (top (cdr (assq 'top (frame-parameters)))))
      (setq parameters (cons (cons 'left (+ left 0))
                     (cons (cons 'top (+ top 0))
                       parameters))))))

If the above doesn't work you can try the following which is taken from ns-win.el before-make-frame-hook.

(setq default-frame-alist '((left . 0) (top . 0) (width . 80) (height . 55)))

(defvar parameters)
(add-hook 'before-make-frame-hook
  (lambda ()
    (let ((left (cdr (assq 'left (frame-parameters))))
          (top (cdr (assq 'top (frame-parameters)))))
      (if (consp left) (setq left (cadr left)))
      (if (consp top) (setq top (cadr top)))
      (cond
       ((or (assq 'top parameters) (assq 'left parameters)))
       ((or (not left) (not top)))
       (t
         (setq parameters (cons (cons 'left (+ left 0))
                   (cons (cons 'top (+ top 0))
                     parameters))))))))