feat: true screen magnifier — global default face + pinned modeline/minibuffer
This commit is contained in:
117
config.el
117
config.el
@@ -698,96 +698,103 @@ Skips past the TODO keyword and optional priority indicator [#A]."
|
|||||||
;;; ============================================================
|
;;; ============================================================
|
||||||
;;; ACCESSIBILITY — GLOBAL TEXT SCALING (SPC z)
|
;;; ACCESSIBILITY — GLOBAL TEXT SCALING (SPC z)
|
||||||
;;; ============================================================
|
;;; ============================================================
|
||||||
;; Uses per-buffer `text-scale-mode' applied to ALL buffers simultaneously.
|
;; True screen magnifier: scales the global `default' face (all buffers,
|
||||||
;; Unlike `default-text-scale', this scales ONLY buffer text.
|
;; help windows, doom menus, org-agenda, magit — everything).
|
||||||
;; Modeline, minibuffer, which-key, corfu popups stay at base size
|
|
||||||
;; and remain fully visible and usable even at very high zoom levels.
|
|
||||||
;;
|
;;
|
||||||
;; Step: ×1.5 per step (multiplicative). From 14pt base:
|
;; Modeline + minibuffer are PINNED to base size after every zoom so they
|
||||||
;; +1 → ×1.5 ≈ 21pt +2 → ×2.25 ≈ 32pt
|
;; stay fully visible and usable regardless of zoom level.
|
||||||
;; +3 → ×3.4 ≈ 47pt +4 → ×5.1 ≈ 71pt
|
;; which-key shows in the minibuffer area → also stays readable.
|
||||||
;; +5 → ×7.6 ≈ 106pt
|
|
||||||
;;
|
;;
|
||||||
;; SPC z + / SPC z = zoom in
|
;; Step: ×1.5 per step (multiplicative, not additive). From 14pt base:
|
||||||
;; SPC z - zoom out
|
;; +1 ≈ 21pt +2 ≈ 32pt +3 ≈ 47pt
|
||||||
;; SPC z 0 reset to default (saves for restore)
|
;; +4 ≈ 71pt +5 ≈ 106pt +6 ≈ 159pt
|
||||||
;; SPC z z restore previous zoom
|
;;
|
||||||
|
;; SPC z + / = zoom in
|
||||||
|
;; SPC z - zoom out
|
||||||
|
;; SPC z 0 reset to default (saves level for restore)
|
||||||
|
;; SPC z z restore zoom before last reset
|
||||||
|
|
||||||
(setq text-scale-mode-step 1.5)
|
;; Base height: captured once at startup (reflects doom-font :size).
|
||||||
|
;; Fallback to 140 = 14pt if face-attribute returns non-integer.
|
||||||
|
(defvar my/zoom-base-height 140
|
||||||
|
"Default face height before any zoom. Captured at Doom init.")
|
||||||
|
|
||||||
(defvar my/zoom-steps 0
|
(defvar my/zoom-steps 0
|
||||||
"Current global zoom step count. 0 = default, positive = bigger.")
|
"Current zoom step count. 0 = default.")
|
||||||
|
|
||||||
(defvar my/zoom-saved-steps nil
|
(defvar my/zoom-saved-steps nil
|
||||||
"Step count saved before last `my/zoom-reset', for restore.")
|
"Step count saved before last `my/zoom-reset', for `my/zoom-restore'.")
|
||||||
|
|
||||||
(defun my/zoom--apply-all (steps)
|
;; Faces that must stay at base height (do not scale with text).
|
||||||
"Apply text-scale of STEPS to every live buffer."
|
;; These form the fixed UI chrome: status bar, minibuffer, tab bar.
|
||||||
(dolist (buf (buffer-list))
|
(defvar my/zoom-pinned-faces
|
||||||
(when (buffer-live-p buf)
|
'(mode-line mode-line-inactive mode-line-active
|
||||||
(with-current-buffer buf
|
minibuffer-prompt header-line
|
||||||
(text-scale-set steps)))))
|
tab-bar tab-bar-tab tab-bar-tab-inactive)
|
||||||
|
"Faces pinned to `my/zoom-base-height' after every zoom operation.")
|
||||||
|
|
||||||
(defun my/zoom--auto-apply ()
|
(defun my/zoom-pin-ui ()
|
||||||
"Apply current zoom to newly opened/switched buffers."
|
"Set pinned UI faces to base height so they don't scale with text."
|
||||||
(unless (= my/zoom-steps 0)
|
(dolist (face my/zoom-pinned-faces)
|
||||||
(text-scale-set my/zoom-steps)))
|
(when (facep face)
|
||||||
|
(set-face-attribute face nil :height my/zoom-base-height))))
|
||||||
|
|
||||||
;; Hook: apply zoom when a new buffer gets a major mode (covers find-file,
|
(defun my/zoom--apply (steps)
|
||||||
;; new scratch buffers, magit, org-agenda, help, etc.)
|
"Set global default face to base × 1.5^STEPS and re-pin UI faces."
|
||||||
(add-hook 'after-change-major-mode-hook #'my/zoom--auto-apply)
|
(let ((new-h (max 80 (round (* my/zoom-base-height (expt 1.5 steps))))))
|
||||||
|
(set-face-attribute 'default nil :height new-h)
|
||||||
|
(my/zoom-pin-ui)
|
||||||
|
(message "Zoom %+d ×%.2f ≈%dpt"
|
||||||
|
steps (expt 1.5 steps) (/ new-h 10))))
|
||||||
|
|
||||||
|
;; Capture base height after Doom finishes font setup.
|
||||||
|
(add-hook 'doom-after-init-hook
|
||||||
|
(lambda ()
|
||||||
|
(let ((h (face-attribute 'default :height nil t)))
|
||||||
|
(when (and (integerp h) (> h 0))
|
||||||
|
(setq my/zoom-base-height h)))))
|
||||||
|
|
||||||
|
;; Re-pin UI faces after any theme reload (Doom resets faces on theme change).
|
||||||
|
(add-hook 'doom-load-theme-hook #'my/zoom-pin-ui)
|
||||||
|
|
||||||
(defun my/zoom-in ()
|
(defun my/zoom-in ()
|
||||||
"Zoom in one step (×1.5) across all buffers."
|
"Zoom in one step (×1.5) — all buffers, help, menus, everything."
|
||||||
(interactive)
|
(interactive)
|
||||||
(cl-incf my/zoom-steps)
|
(cl-incf my/zoom-steps)
|
||||||
(my/zoom--apply-all my/zoom-steps)
|
(my/zoom--apply my/zoom-steps))
|
||||||
(message "Zoom +%d (×%.2f ≈%dpt)"
|
|
||||||
my/zoom-steps
|
|
||||||
(expt text-scale-mode-step my/zoom-steps)
|
|
||||||
(round (* 14 (expt text-scale-mode-step my/zoom-steps)))))
|
|
||||||
|
|
||||||
(defun my/zoom-out ()
|
(defun my/zoom-out ()
|
||||||
"Zoom out one step (÷1.5) across all buffers."
|
"Zoom out one step (÷1.5) — all buffers."
|
||||||
(interactive)
|
(interactive)
|
||||||
(cl-decf my/zoom-steps)
|
(cl-decf my/zoom-steps)
|
||||||
(my/zoom--apply-all my/zoom-steps)
|
(my/zoom--apply my/zoom-steps))
|
||||||
(message "Zoom %d (×%.2f ≈%dpt)"
|
|
||||||
my/zoom-steps
|
|
||||||
(expt text-scale-mode-step my/zoom-steps)
|
|
||||||
(round (* 14 (expt text-scale-mode-step my/zoom-steps)))))
|
|
||||||
|
|
||||||
(defun my/zoom-reset ()
|
(defun my/zoom-reset ()
|
||||||
"Reset all buffers to default text size. Saves current step for restore."
|
"Reset to default font size. Saves current level so SPC z z can restore."
|
||||||
(interactive)
|
(interactive)
|
||||||
(if (= my/zoom-steps 0)
|
(if (= my/zoom-steps 0)
|
||||||
(message "Zoom: already at default")
|
(message "Zoom: already at default")
|
||||||
(setq my/zoom-saved-steps my/zoom-steps)
|
(setq my/zoom-saved-steps my/zoom-steps)
|
||||||
(my/zoom--apply-all 0)
|
(my/zoom--apply 0)
|
||||||
(setq my/zoom-steps 0)
|
(setq my/zoom-steps 0)
|
||||||
(message "Zoom reset to default (was %+d — SPC z z to restore)"
|
(message "Zoom reset (SPC z z to restore %+d)" my/zoom-saved-steps)))
|
||||||
my/zoom-saved-steps)))
|
|
||||||
|
|
||||||
(defun my/zoom-restore ()
|
(defun my/zoom-restore ()
|
||||||
"Restore zoom level saved before last reset."
|
"Restore zoom level saved before last reset."
|
||||||
(interactive)
|
(interactive)
|
||||||
(if (null my/zoom-saved-steps)
|
(if (null my/zoom-saved-steps)
|
||||||
(message "Zoom: nothing to restore")
|
(message "Zoom: nothing to restore")
|
||||||
(my/zoom--apply-all my/zoom-saved-steps)
|
(my/zoom--apply my/zoom-saved-steps)
|
||||||
(setq my/zoom-steps my/zoom-saved-steps
|
(setq my/zoom-steps my/zoom-saved-steps
|
||||||
my/zoom-saved-steps nil)
|
my/zoom-saved-steps nil)))
|
||||||
(message "Zoom restored: %+d (×%.2f ≈%dpt)"
|
|
||||||
my/zoom-steps
|
|
||||||
(expt text-scale-mode-step my/zoom-steps)
|
|
||||||
(round (* 14 (expt text-scale-mode-step my/zoom-steps))))))
|
|
||||||
|
|
||||||
(map! :leader
|
(map! :leader
|
||||||
(:prefix ("z" . "zoom")
|
(:prefix ("z" . "zoom")
|
||||||
:desc "Zoom in (×1.5/krok)" "+" #'my/zoom-in
|
:desc "Zoom in (×1.5)" "+" #'my/zoom-in
|
||||||
:desc "Zoom in (×1.5/krok)" "=" #'my/zoom-in
|
:desc "Zoom in (×1.5)" "=" #'my/zoom-in
|
||||||
:desc "Zoom out (÷1.5/krok)" "-" #'my/zoom-out
|
:desc "Zoom out (÷1.5)" "-" #'my/zoom-out
|
||||||
:desc "Reset na výchozí" "0" #'my/zoom-reset
|
:desc "Reset na výchozí" "0" #'my/zoom-reset
|
||||||
:desc "Restore předchozí zoom" "z" #'my/zoom-restore))
|
:desc "Restore předchozí" "z" #'my/zoom-restore))
|
||||||
|
|
||||||
|
|
||||||
;;; ============================================================
|
;;; ============================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user