Using an Emacs daemon (28, pgtk branch) switching between GUI and terminal, I can't get mouse scrolling to work on both. They work on each individually, but the issue is with the mouse-wheel-{up,down}-event var - it's mouse-4/5 on terminal and wheel-down/up on GUI. This has been documented in bug-gnu-emacs as far back as 2009. I tried:

(global-set-key (kbd "<mouse-4>") (kbd "<mouse-down>"))
(global-set-key (kbd "<mouse-5>") (kbd "<mouse-up>"))

as suggested, but that gave me bad binding in mwheel-scroll. Trying other things with kbd macros gave me After 0 kbd macro iterations: undefined: Keyboard macro terminated by a command ringing the bell. Any other ideas?

1 Answer 1


I reported this bug to the feature/pgtk maintainer


and it has just been fixed in


This is only a partial answer to the question.

I recently upgraded to Emacs 28.0.50 with feature/pgtk to have better Wayland integration. Just like you I am connecting with both GUI and terminal clients to the same daemon, but scrolling no longer worked in the terminal.

I figured out that I need the following Elisp to restore scrolling in the terminal.

(unless window-system
  (defun track-mouse (e))
  (xterm-mouse-mode t)
  (when (featurep 'pgtk)
    (setq mouse-wheel-down-event 'mouse-4)
    (setq mouse-wheel-up-event 'mouse-5)
    (global-set-key (kbd "<mouse-4>") 'mwheel-scroll)
    (global-set-key (kbd "<mouse-5>") 'mwheel-scroll)
    (global-set-key (kbd "<C-mouse-4>") 'mouse-wheel-text-scale)
    (global-set-key (kbd "<C-mouse-5>") 'mouse-wheel-text-scale)
    (global-set-key (kbd "<S-mouse-4>") 'mwheel-scroll)
    (global-set-key (kbd "<S-mouse-5>") 'mwheel-scroll)))

Unfortunately, this only fires once, so it breaks scrolling for GUI clients. I tried to work around this using focus-in-hook and make-variable-frame-local but the former crashed Emacs when switching between frames and the latter is deprecated.

EDIT: I've managed to find something that seems to do what I want. Essentially I advise mwheel-scroll and mouse-wheel-text-scale to locally change the event type for scrolling when invoked through mouse-4 and mouse-5. This is probably extremely inefficient but it seem to work.

(defun track-mouse (e))
(xterm-mouse-mode t)
(when (featurep 'pgtk)
  (defun user/mwheel-scroll (&rest args)
    "Wraps `mwheel-scroll' for use with <mouse-4> and <mouse-5>."
    (interactive (advice-eval-interactive-spec
                  (cadr (interactive-form 'mwheel-scroll))))
    (let ((mouse-wheel-down-event 'mouse-4)
          (mouse-wheel-up-event 'mouse-5))
      (apply 'mwheel-scroll args)))
  (defun user/mouse-wheel-text-scale (&rest args)
    "Wraps `mouse-wheel-text-scale' for use with <mouse-4> and <mouse-5>."
    (interactive (advice-eval-interactive-spec
                  (cadr (interactive-form 'mouse-wheel-text-scale))))
    (let ((mouse-wheel-down-event 'mouse-4)
          (mouse-wheel-up-event 'mouse-5))
      (apply 'mouse-wheel-text-scale args)))
  (global-set-key (kbd "<mouse-4>") 'user/mwheel-scroll)
  (global-set-key (kbd "<mouse-5>") 'user/mwheel-scroll)
  (global-set-key (kbd "<C-mouse-4>") 'user/mouse-wheel-text-scale)
  (global-set-key (kbd "<C-mouse-5>") 'user/mouse-wheel-text-scale)
  (global-set-key (kbd "<S-mouse-4>") 'user/mwheel-scroll)
  (global-set-key (kbd "<S-mouse-5>") 'user/mwheel-scroll))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.