Skip to content

Commit

Permalink
Restore window scroll after popup close
Browse files Browse the repository at this point in the history
Currently, if displaying the popup would hide point, the window is
scrolled to prevent this; but it is not scrolled back when the popup
closes. This can be disorienting when the popup is tall, as the scroll
changes by a large amount.

The solution is to store the scroll position of the selected window
before showing the popup, and restore it after closing it.
  • Loading branch information
45mg committed Feb 7, 2024
1 parent 4d20bc8 commit 40abb43
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion which-key.el
Expand Up @@ -663,6 +663,9 @@ to a non-nil value for the execution of a command. Like this
(defvar which-key--frame nil
"Internal: Holds reference to which-key frame.
Used when `which-key-popup-type' is frame.")
(defvar which-key--scroll-pos-table (make-hash-table :test 'equal)
"Internal: Holds initial scroll positions of windows
in which the which-key popup is showing.")
(defvar which-key--echo-keystrokes-backup nil
"Internal: Backup the initial value of `echo-keystrokes'.")
(defvar which-key--prefix-help-cmd-backup nil
Expand Down Expand Up @@ -1132,7 +1135,13 @@ total height."
(when (and which-key-idle-secondary-delay which-key--secondary-timer-active)
(which-key--start-timer))
(which-key--lighter-restore)
(which-key--hide-popup-ignore-command)))
(which-key--hide-popup-ignore-command)
;; restore scroll position saved earlier by `which-key--show-popup'
(let ((top-pos (gethash (selected-window) which-key--scroll-pos-table)))
(when top-pos
(scroll-down (* (if (> top-pos (window-start)) -1 1)
(count-screen-lines (window-start) top-pos)))
(remhash (selected-window) which-key--scroll-pos-table)))))

(defun which-key--hide-popup-ignore-command ()
"Version of `which-key--hide-popup' without the check of
Expand Down Expand Up @@ -1179,6 +1188,8 @@ buffer text to be displayed in the popup. Return nil if no window
is shown, or if there is no need to start the closing timer."
(when (and (> (car act-popup-dim) 0)
(> (cdr act-popup-dim) 0))
;; save pos at top of this window
(puthash (selected-window) (window-start) which-key--scroll-pos-table)
(cl-case which-key-popup-type
;; Not called for minibuffer
;; (minibuffer (which-key--show-buffer-minibuffer act-popup-dim))
Expand Down

0 comments on commit 40abb43

Please sign in to comment.