Ajustando rapidamente o texto às alterações de DPI

9

Meu laptop tem uma tela 4K, portanto, um DPI muito alto, muito maior que meus monitores externos. Portanto, quando deixo de usar monitores externos na tela do laptop, gostaria de escalar rapidamente o texto e, se possível, todos os widgets da GUI no Emacs para acomodar o novo DPI. Estou ciente do conjunto-quadro-fonte, mas não encontrei uma função correspondente que ajusta a escala também. E o ajuste da escala de texto funciona apenas em um buffer localmente.

Nordlöw
fonte

Respostas:

7
  1. Você pode definir o valor de default-frame-alist, incluindo seu fontparâmetro, condicionalmente, dependendo do monitor / monitor atual. (Você pode usar a função display-monitor-attributes-listpara fornecer informações sobre o monitor / exibição.) Isso permite usar diferentes tamanhos de fonte padrão para diferentes monitores ou outros contextos diferentes.

  2. Você também pode alterar o tamanho da fonte de forma dinâmica, para todas as janelas e buffers mostrados em qualquer estrutura, usando o comando zoom-in, zoom-outou zoom-in/out, a partir da biblioteca zoom-frm.el.

    Esses mesmos comandos podem ampliar um buffer (em todas as janelas, em qualquer quadro) ou um quadro (todas as janelas, qualquer que seja seu buffer). Consulte a página Wiki do Emacs Definir fontes .

Desenhou
fonte
4

Estou usando algo semelhante ao @gavenkoa (por pura coincidência também com um ajudante chamado my-dpi!) Para fazer com que os novos quadros obtenham o tamanho certo, mas chamando, zoom-frmjá que eu uso esse pacote de qualquer maneira. Também funciona em configurações com várias cabeças, usando em frame-monitor-attributesvez 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)
desenfreado
fonte
Se houver uma maneira de disparar isso automaticamente quando o quadro for exibido pela primeira vez em uma tela diferente e o DPI for alterado?
precisa
(add-hook 'after-make-frame-functions #'my-zoom-frm-by-dpi)fará com que seja executado na criação do quadro. Não sei se há um gancho para mover um quadro existente entre os monitores, se é isso que você quis dizer.
Unhammer # 13/19
2
Encontrado este: github.com/mnp/dispwatch
krokodil
2
Descobri que no Windows, a função my-dpi é um pouco mais precisa se você usar o atributo 'workarea' em vez do atributo 'geometry'. Isso ocorre porque o atributo 'mm-size' é o tamanho da área não obscurecida pelas barras de tarefas e assim por diante.
glmorous
Após a edição, displaynão é usado my-dpicorretamente?
KevinOrr 12/03
2

Fiz minha configuração portátil em diferentes laptops / desktops com:

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

Embora eu não tenha tentado fazê-lo funcionar na configuração de várias cabeças. Não sei se é possível.

gavenkoa
fonte
Isso realmente funciona melhor para mim ao corrigir o fator de escala em my-dpi de 25,4 a 17,2 (desde o emacs usando xrandr para dimensões de monitor, não xdpyinfo)
Greg B