I'm using something similar to @gavenkoa (by pure coincidence also with a helper named my-dpi
!) to make new frames get the right size, but calling on zoom-frm
since I use that package anyway. It also works on multiheaded setups, by using frame-monitor-attributes
instead of display-monitor-attributes-list
:
(defun my-dpi (&optional display)
"Get the DPI of DISPLAY.
DISPLAY is a display name, frame or terminal, as in
`display-monitor-attributes-list'."
(cl-flet ((pyth (lambda (w h)
(sqrt (+ (* w w)
(* h h)))))
(mm2in (lambda (mm)
(/ mm 25.4))))
(let* ((atts (car (displayframe-monitor-attributes-list display)))
(pix-w (cl-fourth (assoc 'geometry atts)))
(pix-h (cl-fifth (assoc 'geometry atts)))
(pix-d (pyth pix-w pix-h))
(mm-w (cl-second (assoc 'mm-size atts)))
(mm-h (cl-third (assoc 'mm-size atts)))
(mm-d (pyth mm-w mm-h)))
(/ pix-d (mm2in mm-d)))))
(defvar my-zoom-frm-wanted-dpi 70
"The DPI I want to achieve when using `my-zoom-frm-by-dpi'.")
(defun my-zoom-frm-by-dpi (&optional frame)
"Zoom FRAME so the DPI is closer to `my-zoom-frm-wanted-dpi'."
(interactive)
(let ((frame (or frame (selected-frame))))
(when (frame-parameter frame 'zoomed)
(zoom-frm-unzoom frame))
(let ((frame-zoom-font-difference (1- (round (/ (my-dpi frame)
my-zoom-frm-wanted-dpi)))))
(when (called-interactively-p 'interactive)
(message "Zooming by %S" frame-zoom-font-difference))
(zoom-frm-in frame))))
;; Apply the scaling I want to each newly created frame:
(add-hook 'after-make-frame-functions #'my-zoom-frm-by-dpi)