;; generic code: (defvar predisplay-hook nil "Normal hook run before predisplay.") (defvar window-changed-size-hook nil "Normal hook run when a window displaying this buffer changed size.") (defvar predisplay-sizes (make-hash-table :weakness 'key :test 'eq) "Hash table of old window sizes to detect size changes.") (defun predisplay-check-window () "Run in hook `predisplay-hook' to determine which windows changed size." (let* ((w (selected-window)) (old-size (gethash w predisplay-sizes)) (new-size (cons (window-pixel-width w) (window-pixel-height w)))) (unless (equal old-size new-size) (run-hooks 'window-changed-size-hook) (puthash w new-size predisplay-sizes)))) (add-hook 'predisplay-hook #'predisplay-check-window) (defun predisplay-function (&rest args) (dolist (w (window-list-1 nil t t)) (with-selected-window w (run-hooks 'predisplay-hook)))) (add-function :before pre-redisplay-function #'predisplay-function) ;; demonstration code: (defun my-window-changed-size () (insert (format "%dx%d\n" (window-pixel-width (selected-window)) (window-pixel-height (selected-window))))) (defun display-dynamic-size () (add-hook 'window-changed-size-hook #'my-window-changed-size nil t)) ;; dead code: ;; I thought this would work, but it doesn't, for reasons I believe ;; Eli described. ;; (defun predisplay-run-hook (window) ;; (with-selected-window window ;; (run-hooks 'predisplay-hook))) ;; (push #'predisplay-run-hook pre-redisplay-functions)