Subject: 28.0.50; feature/pgtk: cannot scroll with xterm-mouse-mode
From: Henri Menke <[email-masked]>
To: [email-masked]
Date: Wed, 01 Sep 2021 09:28:24 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

The easiest reproducer is to launch Emacs like this and then scroll
using the mouse wheel

   $ emacs -Q
   $ emacs -nw -Q --eval '(xterm-mouse-mode t)'

It works fine in GUI Emacs but terminal Emacs will report

   <mouse-5> is undefined
   <mouse-4> is undefined

This is due to

https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/mwheel.el?h=feature/pgtk&id=13a9a5e836cbe6e64aadaba40fe1f7eb83320d08#n53

which unconditionally maps the scroll events to `'wheel-up` and
`'wheel-down` when `pgtk` is active.

A quick fix would be something like

   $ emacs -nw -Q --load test.el

with

   ;; test.el
   (unless window-system
     (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)))

Unfortuantely, it is not as simple because the user could have Emacs
running as a daemon, connecting with both GUI and terminal clients in
which case one of them won't work. In fact, using the above command to
start a daemon and then connecting with a GUI client will cause `Bad
binding in mwheel-scroll` upon scrolling.

I tried fixing this by changing `mouse-wheel-(down|up)-event` in
`focus-in-hook` depending on the `(window-system (selected-frame))` but
this crashes Emacs with segmentation fault upon switching between
frames.

   ;; test.el
   (when (featurep 'pgtk)
     (add-hook 'focus-in-hook
               (lambda ()
                 (if (window-system (selected-frame))
                     (setq mouse-wheel-down-event 'mouse-4
   			mouse-wheel-up-event 'mouse-5)
                   (setq mouse-wheel-down-event 'wheel-up
                         mouse-wheel-up-event 'wheel-down)))))
   (unless window-system
     (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)))

Related thread on Emacs Stack Exchange:
https://emacs.stackexchange.com/questions/64935/mwheel-scroll-bindings-between-gui-and-terminal

;;===================
In GNU Emacs 28.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.27, cairo version 1.16.0)
Repository revision: 74d017edb6717ad76d38edc02ad3210d4ad66b96
Repository branch: nixos-21.05
Windowing system distributor 'System Description: NixOS 21.05 (Okapi)

Configured using:
 'configure
 --prefix=/nix/store/p2yxdx48mqgvaflygysqz5b7p7q2bbpw-emacs-pgtkgcc-20210725.0
 --disable-build-details --with-modules --with-x-toolkit=gtk3
 --with-cairo --with-native-compilation --with-pgtk'

Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY
PDUMPER PGTK PNG RSVG SECCOMP SOUND THREADS TIFF TOOLKIT_SCROLL_BARS XIM
GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix