Ajuste rápido de texto a cambios de DPI

9

Mi laptop tiene una pantalla 4K, por lo tanto, un DPI muy alto, mucho más alto que mis monitores externos. Entonces, cuando cambio de usar monitores externos a la pantalla de computadora portátil incorporada, me gustaría escalar rápidamente el texto y, si es posible, todos los widgets GUI en Emacs para adaptar el nuevo DPI. Soy consciente de set-frame-font pero no he encontrado una función correspondiente que también ajuste la escala. Y el ajuste de escala de texto solo funciona en un búfer localmente.

Nordlöw
fuente

Respuestas:

7
  1. Puede establecer el valor de default-frame-alist, incluido su fontparámetro, condicionalmente, dependiendo del monitor / pantalla actual. (Puede usar la función display-monitor-attributes-listpara proporcionarle la información del monitor / pantalla). Esto le permite usar diferentes tamaños de fuente predeterminados para diferentes monitores u otros contextos diferentes.

  2. También puede cambiar el tamaño de fuente dinámica, para todas las ventanas y tampones mostrados en cualquier marco, con el comando zoom-in, zoom-outo zoom-in/out, a partir de la biblioteca zoom-frm.el.

    Estos mismos comandos pueden hacer zoom en un búfer (en todas las ventanas, en cualquier marco) o en un marco (todas sus ventanas, sea cual sea su búfer). Consulte la página Wiki de Emacs Establecer fuentes .

Dibujó
fuente
4

Estoy usando algo similar a @gavenkoa (¡por pura coincidencia también con un ayudante llamado my-dpi!) Para hacer que los nuevos marcos tengan el tamaño correcto, pero llamo zoom-frmdesde que uso ese paquete de todos modos. También funciona en configuraciones de varios encabezados, al usar en frame-monitor-attributeslugar de display-monitor-attributes-list:

(defun my-dpi (&optional frame)
  "Get the DPI of FRAME (or current if nil)."
  (cl-flet ((pyth (lambda (w h)
                    (sqrt (+ (* w w)
                             (* h h)))))
            (mm2in (lambda (mm)
                     (/ mm 25.4))))
    (let* ((atts (frame-monitor-attributes frame))
           (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)
desarmar
fuente
Si hay una manera de activar esto automáticamente cuando el cuadro se muestra por primera vez en una pantalla diferente y el DPI ha cambiado.
krokodil
(add-hook 'after-make-frame-functions #'my-zoom-frm-by-dpi)hará que se ejecute al crear el marco. No sé si hay un gancho para mover un marco existente a través de pantallas, si eso es lo que querías decir.
Martillo
2
Encontrado esto: github.com/mnp/dispwatch
krokodil
2
Descubrí que en Windows, la función my-dpi es un poco más precisa si usa el atributo 'área de trabajo' en lugar del atributo 'geometría'. Esto se debe a que el atributo 'mm-size' es el tamaño del área no ocultada por las barras de tareas, etc.
sombrío
Después de la edición, display¿no se usa en la my-dpiderecha?
KevinOrr
2

Hice mi configuración portátil en diferentes computadoras portátiles / de escritorio con:

(defun my-dpi ()
  (let* ((attrs (car (display-monitor-attributes-list)))
         (size (assoc 'mm-size attrs))
         (sizex (cadr size))
         (res (cdr (assoc 'geometry attrs)))
         (resx (- (caddr res) (car res)))
         dpi)
    (catch 'exit
      ;; in terminal
      (unless sizex
        (throw 'exit 10))
      ;; on big screen
      (when (> sizex 1000)
        (throw 'exit 10))
      ;; DPI
      (* (/ (float resx) sizex) 25.4))))

(defun my-preferred-font-size ()
  (let ( (dpi (my-dpi)) )
  (cond
    ((< dpi 110) 10)
    ((< dpi 130) 11)
    ((< dpi 160) 12)
    (t 12))))

(defvar my-preferred-font-size (my-preferred-font-size))

(defvar my-regular-font
  (cond
   ((eq window-system 'x) (format "DejaVu Sans Mono-%d:weight=normal" my-preferred-font-size))
   ((eq window-system 'w32) (format "Courier New-%d:antialias=none" my-preferred-font-size))))
(defvar my-symbol-font
  (cond
   ((eq window-system 'x) (format "DejaVu Sans Mono-%d:weight=normal" my-preferred-font-size))
   ((eq window-system 'w32) (format "DejaVu Sans Mono-%d:antialias=none" my-preferred-font-size))))

(cond
 ((eq window-system 'x)
  (if (and (fboundp 'find-font) (find-font (font-spec :name my-regular-font)))
      (set-frame-font my-regular-font)
    (set-frame-font "7x14")))
 ((eq window-system 'w32)
  (set-frame-font my-regular-font)
  (set-fontset-font nil 'cyrillic my-regular-font)
  (set-fontset-font nil 'greek my-regular-font)
  (set-fontset-font nil 'phonetic my-regular-font)
  (set-fontset-font nil 'symbol my-symbol-font)))

Aunque no he intentado que funcione en una configuración de varios encabezados. No sé si alguna vez es posible.

gavenkoa
fuente
1
En realidad, esto funciona mejor para mí al corregir el factor de escala en my-dpi de 25.4 a 17.2 (ya que emacs usa xrandr para las dimensiones del monitor, no xdpyinfo)
Greg B