Ajustement rapide du texte aux modifications DPI


9

Mon portable a un écran 4K donc un DPI très élevé, bien supérieur à mes moniteurs externes. Donc, lorsque je passe de l'utilisation de moniteurs externes à l'écran d'ordinateur portable intégré, je voudrais rapidement mettre à l'échelle le texte et, si possible, tous les widgets GUI d'Emacs pour intégrer le nouveau DPI. Je connais set-frame-font mais je n'ai pas trouvé de fonction correspondante qui ajuste également la mise à l'échelle. Et le réglage de l'échelle du texte ne fonctionne que localement sur un tampon.

Réponses:


7
  1. Vous pouvez définir la valeur de default-frame-alist, y compris son fontparamètre, de manière conditionnelle, en fonction du moniteur / affichage actuel. (Vous pouvez utiliser la fonction display-monitor-attributes-listpour vous donner les informations de moniteur / affichage.) Cela vous permet d'utiliser différentes tailles de police par défaut pour différents moniteurs ou d'autres contextes différents.

  2. Vous pouvez également modifier la taille de police dynamiquement, pour toutes les fenêtres et les tampons indiqués dans un cadre, commande à l' aide zoom-in, zoom-outou zoom-in/out, de la bibliothèque zoom-frm.el.

    Ces mêmes commandes peuvent soit zoomer un tampon (dans toutes les fenêtres, sur n'importe quel cadre) ou un cadre (toutes ses fenêtres, quel que soit leur tampon). Voir la page Wiki Emacs Définir les polices .


4

J'utilise quelque chose de similaire à @gavenkoa (par pure coïncidence également avec un assistant nommé my-dpi!) Pour que les nouveaux cadres obtiennent la bonne taille, mais j'appelle zoom-frmdepuis que j'utilise ce package de toute façon. Il fonctionne également sur les configurations à plusieurs têtes, en utilisant à la frame-monitor-attributesplace 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)

S'il existe un moyen de déclencher cela automatiquement lorsque le cadre est affiché pour la première fois sur un affichage différent et que le DPI a changé?
krokodil

(add-hook 'after-make-frame-functions #'my-zoom-frm-by-dpi)le fera fonctionner lors de la création du cadre. Je ne sais pas s'il y a un crochet pour déplacer un cadre existant sur des écrans, si c'est ce que vous vouliez dire.
unhammer


2
J'ai trouvé que sous Windows, la fonction my-dpi est un peu plus précise si vous utilisez l'attribut 'workarea' au lieu de l'attribut 'geometry'. En effet, l'attribut 'mm-size' est la taille de la zone non masquée par les barres des tâches, etc.
glmorous

Après la modification, displayn'est-il pas utilisé à my-dpidroite?
KevinOrr

2

J'ai rendu ma configuration portable sur différents ordinateurs portables / ordinateurs de bureau avec:

(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)))

Même si je n'ai pas essayé de le faire fonctionner dans une configuration à plusieurs têtes. Je ne sais pas si c'est possible.


1
En fait, cela fonctionne mieux pour moi lors de la fixation du facteur d'échelle dans my-dpi de 25,4 à 17,2 (car emacs utilise xrandr pour les dimensions du moniteur, pas xdpyinfo)
Greg B
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.