GNU bug report logs - #68796
xterm.c: Convert mouse-4/5/6/7 to wheel-up/down/left/right

Previous Next

Package: emacs;

Reported by: Stefan Monnier <monnier <at> iro.umontreal.ca>

Date: Mon, 29 Jan 2024 14:46:01 UTC

Severity: wishlist

Tags: patch

Done: Stefan Monnier <monnier <at> iro.umontreal.ca>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 68796 in the body.
You can then email your comments to 68796 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Mon, 29 Jan 2024 14:46:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 29 Jan 2024 14:46:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: bug-gnu-emacs <at> gnu.org
Subject: xterm.c: Convert mouse-4/5/6/7 to wheel-up/down/left/right
Date: Mon, 29 Jan 2024 09:45:01 -0500
[Message part 1 (text/plain, inline)]
Tags: patch

Following up on the `xt-mouse.el` patch (bug#68698), I now propose we do
the same for those `mouse-4/5/6/7` events generated by old-style X11 input.

IIUC Po Lu wasn't favorable to the idea, but maybe seeing the code
will make a convert?

Beside that, the patch has 2 remaining issues:
- Lack of corresponding updates to `etc/NEWS` and `doc/lispref/commands.texi`.
- Lack of testing for the left/right remapping.  This is *really*
  necessary because even after (re)reading the various parts of the code
  that handle horizontal scrolling, I'm still very much unsure if I got
  the direction right[left?], so if you have a mouse with a horizontal wheel,
  please compare the `wheel-left/right` events generated with and
  without building `--without-xinput2`.


        Stefan

 In GNU Emacs 30.0.50 (build 2, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.16.0, Xaw3d scroll bars) of 2024-01-25 built on pastel
Repository revision: 5945fab9af0b52cc55f06b2c7e911d51e34a9cdf
Repository branch: work
Windowing system distributor 'The X.Org Foundation', version 11.0.12101007
System Description: Debian GNU/Linux 12 (bookworm)

Configured using:
 'configure -C --enable-checking --enable-check-lisp-object-type --with-modules --with-cairo --with-tiff=ifavailable
 'CFLAGS=-Wall -g3 -Og -Wno-pointer-sign' --without-native-compilation
 PKG_CONFIG_PATH=/home/monnier/lib/pkgconfig'

[0001-xterm.c-Map-old-style-wheel-buttons-to-actual-wheel-.patch (text/patch, attachment)]

Severity set to 'wishlist' from 'normal' Request was from Stefan Kangas <stefankangas <at> gmail.com> to control <at> debbugs.gnu.org. (Tue, 30 Jan 2024 00:43:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Tue, 30 Jan 2024 02:01:03 GMT) Full text and rfc822 format available.

Message #10 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Tue, 30 Jan 2024 10:00:17 +0800
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

>>From 60e6903ae12546db93f149b1f184ffc7ccdc30c2 Mon Sep 17 00:00:00 2001
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Date: Mon, 29 Jan 2024 09:35:09 -0500
> Subject: [PATCH] xterm.c: Map old-style wheel buttons to actual wheel events
>
> Change the handling of the old X11 convention to use mouse-4/5/6/7
> events to represent wheel events: instead of asking downstream
> packages to use the `mouse-wheel-*-event` variables to know which events
> represent wheel events, use those variables in `xterm.c` to directly
> convert those events into the standard `wheel-up/down/left/right` events
> used everywhere else.
>
> This simplifies the work of packages which can now just bind their
> commands to `wheel-up/down/left/right`.

I'm still opposed to this for reasons I will try to communicate below.
First, there are several logic errors in this patch:

> +  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
> +#ifdef HAVE_XINPUT2
> +  if (!dpyinfo->supports_xi2)
> +#endif

dpyinfo->supports_xi2 is no guarantee that exclusively input extension
events will be received, but only indicates that the X display supports
the input extension.  There are several scenarios where it may be true
while core events are still delivered to windows, such as a combination
of GTK 3 and GDK_CORE_DEVICE_EVENTS=1's being enabled.  The correct test
of event type is whether x_construct_mouse_click is being called from
the XI_ButtonPress or XI_ButtonRelease label in handle_one_xevent.

Incidentally, servers with the input extension always assign buttons 4
through 7 to wheel movement.

> +      Lisp_Object base = base_mouse_symbol (result->code);
> +      int wheel
> +       /* BEWARE: `mouse-wheel-UP-event' corresponds to
> +          `wheel-DOWN' events and vice versa!!  */
> +        = BASE_EQ   (base, find_symbol_value (Qmouse_wheel_up_event))    ? 0
> +          : BASE_EQ (base, find_symbol_value (Qmouse_wheel_down_event))  ? 1
> +          : BASE_EQ (base, find_symbol_value (Qmouse_wheel_left_event))  ? 2
> +          : BASE_EQ (base, find_symbol_value (Qmouse_wheel_right_event)) ? 3
> +          : -1;
> +      if (wheel >= 0)
> +        {
> +          result->kind = (event->type != ButtonRelease ? NO_EVENT
> +		          : wheel & 2 ? HORIZ_WHEEL_EVENT : WHEEL_EVENT);
> +          result->code = 0;         /* Not used.  */
> +          result->modifiers &= ~(up_modifier || down_modifier);
> +          result->modifiers |= wheel & 1 ? up_modifier : down_modifier;
> +        }
> +    }

Isn't this insufficient to completely supersede mouse events by wheel
events, considering that such events will still be delivered as mouse
button events to tab bars?

Lastly, plenty of old code that binds just the button events will be
broken, and the code that keeps track of button-down and up events in
read_key_sequence and friends will cease applying to X wheel events.

This area has given me a lot of grief over the years (as it has given
you), so I'm reluctant to see any change there, as no matter how well
the argument in favor of its safety is posed, some unforeseen problem
invariably emerges afterwards.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Tue, 30 Jan 2024 03:33:02 GMT) Full text and rfc822 format available.

Message #13 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Po Lu <luangruo <at> yahoo.com>
Cc: 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Mon, 29 Jan 2024 22:32:29 -0500
[Message part 1 (text/plain, inline)]
>> +  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
>> +#ifdef HAVE_XINPUT2
>> +  if (!dpyinfo->supports_xi2)
>> +#endif
>
> dpyinfo->supports_xi2 is no guarantee that exclusively input extension
> events will be received, but only indicates that the X display supports
> the input extension.  There are several scenarios where it may be true
> while core events are still delivered to windows, such as a combination
> of GTK 3 and GDK_CORE_DEVICE_EVENTS=1's being enabled.

Hmm... so IIUC you're saying that even when `dpyinfo->supports_xi2` is
true, we may receive `mouse-4/5/6/7` events for wheel motions?
Yuck!

> The correct test of event type is whether x_construct_mouse_click is
> being called from the XI_ButtonPress or XI_ButtonRelease label in
> handle_one_xevent.

OK, that sounds fixable.  See additional patch below.

> Incidentally, servers with the input extension always assign buttons 4
> through 7 to wheel movement.

Interesting.

>> +      Lisp_Object base = base_mouse_symbol (result->code);
>> +      int wheel
>> +       /* BEWARE: `mouse-wheel-UP-event' corresponds to
>> +          `wheel-DOWN' events and vice versa!!  */
>> +        = BASE_EQ   (base, find_symbol_value (Qmouse_wheel_up_event))    ? 0
>> +          : BASE_EQ (base, find_symbol_value (Qmouse_wheel_down_event))  ? 1
>> +          : BASE_EQ (base, find_symbol_value (Qmouse_wheel_left_event))  ? 2
>> +          : BASE_EQ (base, find_symbol_value (Qmouse_wheel_right_event)) ? 3
>> +          : -1;
>> +      if (wheel >= 0)
>> +        {
>> +          result->kind = (event->type != ButtonRelease ? NO_EVENT
>> +		          : wheel & 2 ? HORIZ_WHEEL_EVENT : WHEEL_EVENT);
>> +          result->code = 0;         /* Not used.  */
>> +          result->modifiers &= ~(up_modifier || down_modifier);
>> +          result->modifiers |= wheel & 1 ? up_modifier : down_modifier;
>> +        }
>> +    }
>
> Isn't this insufficient to completely supersede mouse events by wheel
> events, considering that such events will still be delivered as mouse
> button events to tab bars?

Hmm... indeed there was a crash here, which I just fixed in the
patch below.  But with that fix, I do see `wheel-up/down` events on the
tab-tab as well.  Am I missing something?

> Lastly, plenty of old code that binds just the button events will be
> broken,

Indeed.  But that should be a disappearing breed because such bindings
never worked under non-X11 GUIs and now they don't work either under X11
builds that use XInput2, which I expect is the vast majority of Emacsā‰„29
builds in GNU/Linux distributions.

> and the code that keeps track of button-down and up events in
> read_key_sequence and friends will cease applying to X wheel events.

Hmm... the only code I can think of in `read_key_sequence` which cares
about button up/down is the code that drops the button down events and
the one that turns pairs into drag events.  Is that ever useful
currently with the `mouse-4/5/6/7` events?  No one has lamented this
under non-X11 builds so far nor under XInput2, so it seems unlikely to
be a problem.

> This area has given me a lot of grief over the years (as it has given
> you), so I'm reluctant to see any change there, as no matter how well
> the argument in favor of its safety is posed, some unforeseen problem
> invariably emerges afterwards.

There's no doubt that event representation is a delicate/nasty part of
Emacs code, but I think it's really a trade-off between possible
short-term pain and the longer term simplification of unifying all wheel
handling under `wheel-*` events.
Also, I think we *will* have go through that pain sooner or later.


        Stefan
[xterm-wheel-events.patch (text/x-diff, inline)]
diff --git a/src/keyboard.c b/src/keyboard.c
index 7c1822b3423..a881c3d6117 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6628,8 +6628,13 @@ make_lispy_event (struct input_event *event)
 
 	if (CONSP (event->arg))
 	  return list5 (head, position, make_fixnum (double_click_count),
-			XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)),
-						  XCAR (XCDR (XCDR (event->arg)))));
+			XCAR (event->arg),
+			/* FIXME: I don't know what I'm doing here.  */
+			(CONSP (XCDR (event->arg))
+			 && CONSP (XCDR (XCDR (event->arg))))
+			? Fcons (XCAR (XCDR (event->arg)),
+			         XCAR (XCDR (XCDR (event->arg))))
+			: Qnil);
         else if (NUMBERP (event->arg))
           return list4 (head, position, make_fixnum (double_click_count),
                         event->arg);
diff --git a/src/xterm.c b/src/xterm.c
index fcbe7a1ec4f..237b705b555 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -14548,7 +14548,7 @@ x_query_pointer (Display *dpy, Window w, Window *root_return,
 static Lisp_Object
 x_construct_mouse_click (struct input_event *result,
                          const XButtonEvent *event,
-                         struct frame *f)
+                         struct frame *f, bool xi2)
 {
   int x = event->x;
   int y = event->y;
@@ -14563,9 +14563,7 @@ x_construct_mouse_click (struct input_event *result,
 			  : down_modifier));
 
   /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
-#ifdef HAVE_XINPUT2
-  if (!dpyinfo->supports_xi2)
-#endif
+  if (!xi2)
     {
       Lisp_Object base = base_mouse_symbol (result->code);
       int wheel
@@ -21895,13 +21893,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 			&& event->xbutton.time > ignore_next_mouse_click_timeout)
 		      {
 			ignore_next_mouse_click_timeout = 0;
-			x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+			x_construct_mouse_click (&inev.ie, &event->xbutton,
+			                         f, false);
 		      }
 		    if (event->type == ButtonRelease)
 		      ignore_next_mouse_click_timeout = 0;
 		  }
 		else
-		  x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+		  x_construct_mouse_click (&inev.ie, &event->xbutton, f, false);
 
 		*finish = X_EVENT_DROP;
 		goto OTHER;
@@ -21971,13 +21970,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                           && event->xbutton.time > ignore_next_mouse_click_timeout)
                         {
                           ignore_next_mouse_click_timeout = 0;
-                          x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+                          x_construct_mouse_click (&inev.ie, &event->xbutton,
+                                                   f, false);
                         }
                       if (event->type == ButtonRelease)
                         ignore_next_mouse_click_timeout = 0;
                     }
                   else
-                    x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+                    x_construct_mouse_click (&inev.ie, &event->xbutton,
+                                             f, false);
 
 		  if (!NILP (tab_bar_arg))
 		    inev.ie.arg = tab_bar_arg;
@@ -23754,13 +23755,13 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 				&& xev->time > ignore_next_mouse_click_timeout)
 			      {
 				ignore_next_mouse_click_timeout = 0;
-				x_construct_mouse_click (&inev.ie, &bv, f);
+				x_construct_mouse_click (&inev.ie, &bv, f, true);
 			      }
 			    if (xev->evtype == XI_ButtonRelease)
 			      ignore_next_mouse_click_timeout = 0;
 			  }
 			else
-			  x_construct_mouse_click (&inev.ie, &bv, f);
+			  x_construct_mouse_click (&inev.ie, &bv, f, true);
 
 			if (!NILP (tab_bar_arg))
 			  inev.ie.arg = tab_bar_arg;

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Tue, 30 Jan 2024 03:55:01 GMT) Full text and rfc822 format available.

Message #16 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Tue, 30 Jan 2024 11:53:58 +0800
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

> Hmm... so IIUC you're saying that even when `dpyinfo->supports_xi2` is
> true, we may receive `mouse-4/5/6/7` events for wheel motions?
> Yuck!

Yes, and as always other clients may send whatever they want, although
Emacs is not obliged to handle those events correctly.

>> The correct test of event type is whether x_construct_mouse_click is
>> being called from the XI_ButtonPress or XI_ButtonRelease label in
>> handle_one_xevent.
>
> OK, that sounds fixable.  See additional patch below.

Thanks.  I'm short on time at the moment, but will get around to this.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Sat, 10 Feb 2024 08:56:03 GMT) Full text and rfc822 format available.

Message #19 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Po Lu <luangruo <at> yahoo.com>
Cc: monnier <at> iro.umontreal.ca, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Sat, 10 Feb 2024 10:24:32 +0200
Ping!  Can we make some progress here?

> Cc: 68796 <at> debbugs.gnu.org
> Date: Tue, 30 Jan 2024 11:53:58 +0800
> From:  Po Lu via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
> 
> > Hmm... so IIUC you're saying that even when `dpyinfo->supports_xi2` is
> > true, we may receive `mouse-4/5/6/7` events for wheel motions?
> > Yuck!
> 
> Yes, and as always other clients may send whatever they want, although
> Emacs is not obliged to handle those events correctly.
> 
> >> The correct test of event type is whether x_construct_mouse_click is
> >> being called from the XI_ButtonPress or XI_ButtonRelease label in
> >> handle_one_xevent.
> >
> > OK, that sounds fixable.  See additional patch below.
> 
> Thanks.  I'm short on time at the moment, but will get around to this.
> 
> 
> 
> 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Sat, 10 Feb 2024 09:20:01 GMT) Full text and rfc822 format available.

Message #22 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: monnier <at> iro.umontreal.ca, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Sat, 10 Feb 2024 17:09:14 +0800
Eli Zaretskii <eliz <at> gnu.org> writes:

> Ping!  Can we make some progress here?

I converted most of the Lisp code at my organization (where X servers
are configured with the input extension disabled) to use wheel events
under Emacs 30 and arranged for a modified version of Stefan's patch to
be built.  Which was incidentally not straightforward to do cleanly, as
the code in question assumed that events it received would be pairs of
button press and release events, and was very much designed around that
assumption.

Unfortunately the holidays are in full swing, and conclusions from this
cannot be drawn until once enough experience accumulates some time after
they end.  To complicate matters, users at my site don't often work with
Emacs 30, except for a few early adopters.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Sat, 10 Feb 2024 14:23:01 GMT) Full text and rfc822 format available.

Message #25 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Po Lu <luangruo <at> yahoo.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Sat, 10 Feb 2024 09:22:02 -0500
Po Lu [2024-02-10 17:09:14] wrote:
> Eli Zaretskii <eliz <at> gnu.org> writes:
>> Ping!  Can we make some progress here?
> I converted most of the Lisp code at my organization (where X servers
> are configured with the input extension disabled) to use wheel events
> under Emacs 30 and arranged for a modified version of Stefan's patch to
> be built.  Which was incidentally not straightforward to do cleanly, as
> the code in question assumed that events it received would be pairs of
> button press and release events, and was very much designed around that
> assumption.

Fascinating.  Is there any way I could get to peek at that code?
Also interested in the backstory about why your X11 servers are configured
without XInput2.

Maybe we should provide a better "reverse" story: with the current patch
users can recover their old `mouse-4/5/6/7` events by setting
`mouse-wheel-*-event` to nil, but then they lose mwheel-based scrolling
(plus a few other bindings, mostly one in completion-preview and one in
flymake), so the etc/NEWS entry should describe how to recover that
scrolling behavior.

Or maybe we should keep `mouse-wheel-*-event` untouched (tho, maybe mark
them obsolete) and instead introduce a new set of variables that control
the remapping of `mouse-4/5/6/7` to `wheel-*` events.

That would provide a smoother transition: users can set those new vars
to nil to recover the old behavior.

Another benefit is that the new var(s) could hold just the button
numbers (i.e. an integer) instead of a symbol, which should simplify the
remapping code (both in the `xterm.c` and the `xt-mouse.el` cases).


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Sat, 10 Feb 2024 15:43:01 GMT) Full text and rfc822 format available.

Message #28 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Po Lu <luangruo <at> yahoo.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Sat, 10 Feb 2024 10:33:01 -0500
[Message part 1 (text/plain, inline)]
> Or maybe we should keep `mouse-wheel-*-event` untouched (tho, maybe mark
> them obsolete) and instead introduce a new set of variables that control
> the remapping of `mouse-4/5/6/7` to `wheel-*` events.

See patch below.
It would need etc/NEWS and doc changes, of course, and probably some
warning-silencing in those packages using `mouse-wheel-*-event`s.


        Stefan
[0001-mouse-wheel-buttons-Map-old-style-wheel-buttons-to-a.patch (text/x-diff, inline)]
From 0e94e1140a8ec72bd068648eb5ec1dc861f0884b Mon Sep 17 00:00:00 2001
From: Stefan Monnier <monnier <at> iro.umontreal.ca>
Date: Mon, 29 Jan 2024 09:35:09 -0500
Subject: [PATCH] (mouse-wheel-buttons): Map old-style wheel buttons to actual
 wheel events

Change the handling of the old X11 convention to use mouse-4/5/6/7
events to represent wheel events: instead of asking downstream
packages to use the `mouse-wheel-*-event` variables to know which events
represent wheel events, use new var `mouse-wheel-buttons` to directly
convert those events into the standard `wheel-up/down/left/right` events
used everywhere else.

This will simplify the work of packages which can thus just bind their
commands to `wheel-up/down/left/right`.

* lisp/mouse.el (mouse-wheel-buttons): New custom variable.

* src/keyboard.c (make_lispy_event): Adjust for "wheel-clicks" on the tab-bar.
* src/xterm.c (x_construct_mouse_click): Add `xi2` argument and
obey `mouse-wheel-buttons` variable.
(handle_one_xevent): Adjust calls accordingly.
(syms_of_xterm): Define the `mouse-wheel-buttons` and the
`wheel-up/down/left/right`symbols.

* lisp/xt-mouse.el: Don't require `mwheel` any more.
(xterm-mouse--same-button-p): Delete function.
(xterm-mouse--read-event-sequence): Use `mouse-wheel-buttons`.

* lisp/mwheel.el (mouse-wheel-up-event, mouse-wheel-down-event)
(mouse-wheel-left-event, mouse-wheel-right-event): Make obsolete.
(mouse-wheel-obey-old-style-wheel-buttons): Delete variable.
---
 lisp/mouse.el    | 13 ++++++++++++
 lisp/mwheel.el   | 21 ++++++++-----------
 lisp/xt-mouse.el | 20 ++++--------------
 src/keyboard.c   |  9 ++++++--
 src/xterm.c      | 53 +++++++++++++++++++++++++++++++++++++++---------
 5 files changed, 75 insertions(+), 41 deletions(-)

diff --git a/lisp/mouse.el b/lisp/mouse.el
index d1b06c2040d..585891bf699 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -133,6 +133,19 @@ mouse-drag-mode-line-buffer
   :type 'boolean
   :version "29.1")
 
+(defcustom mouse-wheel-buttons
+  '((4 . wheel-up) (5 . wheel-down) (6 . wheel-left) (7 . wheel-right))
+  "Buttons to remap to wheel events.
+This is an alist of (NUMBER . SYMBOL) used to remap old-style mouse wheel
+events represented as mouse button events.  It remaps mouse button event
+NUMBER to the event SYMBOL.  SYMBOL must be one of `wheel-up', `wheel-down',
+`wheel-left', or `wheel-right'.
+This is used only for events that come from sources known to generate such
+events, such as X11 events when XInput2 is not used, or events coming from
+a text terminal."
+  :type '(alist)
+  :version "30.1")
+
 (defvar mouse--last-down nil)
 
 (defun mouse--down-1-maybe-follows-link (&optional _prompt)
diff --git a/lisp/mwheel.el b/lisp/mwheel.el
index 66a1fa1a706..9fc922eebc9 100644
--- a/lisp/mwheel.el
+++ b/lisp/mwheel.el
@@ -56,20 +56,17 @@ mouse-wheel-change-button
              (bound-and-true-p mouse-wheel-mode))
     (mouse-wheel-mode 1)))
 
-(defvar mouse-wheel-obey-old-style-wheel-buttons t
-  "If non-nil, treat mouse-4/5/6/7 events as mouse wheel events.
-These are the event names used historically in X11 before XInput2.
-They are sometimes generated by things like text-terminals as well.")
+(make-obsolete-variable 'mouse-wheel-up-event    'mouse-wheel-buttons "30.1")
+(make-obsolete-variable 'mouse-wheel-down-event  'mouse-wheel-buttons "30.1")
+(make-obsolete-variable 'mouse-wheel-left-event  'mouse-wheel-buttons "30.1")
+(make-obsolete-variable 'mouse-wheel-right-event 'mouse-wheel-buttons "30.1")
 
-(defcustom mouse-wheel-down-event
-  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-4)
+(defcustom mouse-wheel-down-event 'mouse-4
   "Event used for scrolling down, beside `wheel-up', if any."
   :group 'mouse
   :type 'symbol
   :set #'mouse-wheel-change-button)
-
-(defcustom mouse-wheel-up-event
-  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-5)
+(defcustom mouse-wheel-up-event 'mouse-5
   "Event used for scrolling up, beside `wheel-down', if any."
   :group 'mouse
   :type 'symbol
@@ -223,12 +220,10 @@ mwheel-scroll-left-function
 (defvar mwheel-scroll-right-function 'scroll-right
   "Function that does the job of scrolling right.")
 
-(defvar mouse-wheel-left-event
-  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-6)
+(defvar mouse-wheel-left-event 'mouse-6
   "Event used for scrolling left, beside `wheel-left', if any.")
 
-(defvar mouse-wheel-right-event
-  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-7)
+(defvar mouse-wheel-right-event 'mouse-7
   "Event used for scrolling right, beside `wheel-right', if any.")
 
 (defun mouse-wheel--get-scroll-window (event)
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
index 081b8f32456..c27dee7e249 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -40,8 +40,6 @@
 
 ;;; Code:
 
-(require 'mwheel)
-
 (defvar xterm-mouse-debug-buffer nil)
 
 (defun xterm-mouse-translate (_event)
@@ -195,12 +193,6 @@ xterm-mouse--read-number-from-terminal
           (cons n c))
       (cons (- (setq c (xterm-mouse--read-coordinate)) 32) c))))
 
-(defun xterm-mouse--button-p (event btn)
-  (and (symbolp event)
-       (string-prefix-p "mouse-" (symbol-name event))
-       (eq btn (car (read-from-string (symbol-name event)
-                                      (length "mouse-"))))))
-
 ;; XTerm reports mouse events as
 ;; <EVENT-CODE> <X> <Y> in default mode, and
 ;; <EVENT-CODE> ";" <X> ";" <Y> <"M" or "m"> in extended mode.
@@ -246,14 +238,10 @@ xterm-mouse--read-event-sequence
             (if meta "M-" "")
             (if shift "S-" "")
             (if down "down-" "")
-            (cond
-             ;; BEWARE: `mouse-wheel-UP-event' corresponds to
-             ;; `wheel-DOWN' events and vice versa!!
-             ((xterm-mouse--button-p mouse-wheel-down-event btn)  "wheel-up")
-             ((xterm-mouse--button-p mouse-wheel-up-event btn)    "wheel-down")
-             ((xterm-mouse--button-p mouse-wheel-left-event btn)  "wheel-left")
-             ((xterm-mouse--button-p mouse-wheel-right-event btn) "wheel-right")
-             (t (format "mouse-%d" btn))))))))
+            (let ((remap (alist-get btn mouse-wheel-buttons)))
+              (if remap
+                  (symbol-name remap)
+                (format "mouse-%d" btn))))))))
     (list sym (1- x) (1- y))))
 
 (defun xterm-mouse--set-click-count (event click-count)
diff --git a/src/keyboard.c b/src/keyboard.c
index 1f7253a7da1..4c3e33762af 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6628,8 +6628,13 @@ make_lispy_event (struct input_event *event)
 
 	if (CONSP (event->arg))
 	  return list5 (head, position, make_fixnum (double_click_count),
-			XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)),
-						  XCAR (XCDR (XCDR (event->arg)))));
+			XCAR (event->arg),
+			/* FIXME: I don't know what I'm doing here.  */
+			(CONSP (XCDR (event->arg))
+			 && CONSP (XCDR (XCDR (event->arg))))
+			? Fcons (XCAR (XCDR (event->arg)),
+			         XCAR (XCDR (XCDR (event->arg))))
+			: Qnil);
         else if (NUMBERP (event->arg))
           return list4 (head, position, make_fixnum (double_click_count),
                         event->arg);
diff --git a/src/xterm.c b/src/xterm.c
index c8a43785564..e75b64ed3d4 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -14543,18 +14543,19 @@ x_query_pointer (Display *dpy, Window w, Window *root_return,
    `x', `y', `x_root' and `y_root'.  This function should not access
    any other fields in EVENT without also initializing the
    corresponding fields in `bv' under the XI_ButtonPress and
-   XI_ButtonRelease labels inside `handle_one_xevent'.  */
+   XI_ButtonRelease labels inside `handle_one_xevent'.
+
+   XI2 indicates that this click comes from XInput2 rather than core
+   event.   */
 
 static Lisp_Object
 x_construct_mouse_click (struct input_event *result,
                          const XButtonEvent *event,
-                         struct frame *f)
+                         struct frame *f, bool xi2)
 {
   int x = event->x;
   int y = event->y;
 
-  /* Make the event type NO_EVENT; we'll change that when we decide
-     otherwise.  */
   result->kind = MOUSE_CLICK_EVENT;
   result->code = event->button - Button1;
   result->timestamp = event->time;
@@ -14564,6 +14565,29 @@ x_construct_mouse_click (struct input_event *result,
 			  ? up_modifier
 			  : down_modifier));
 
+  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
+  if (!xi2)
+    {
+      Lisp_Object base
+        = Fcdr_safe (Fassq (make_fixnum (result->code + 1),
+                            Fsymbol_value (Qmouse_wheel_buttons)));
+      int wheel
+        = NILP (base) ? -1
+          : BASE_EQ (base, Qwheel_down)  ? 0
+          : BASE_EQ (base, Qwheel_up)    ? 1
+          : BASE_EQ (base, Qwheel_left)  ? 2
+          : BASE_EQ (base, Qwheel_right) ? 3
+          : -1;
+      if (wheel >= 0)
+        {
+          result->kind = (event->type != ButtonRelease ? NO_EVENT
+		          : wheel & 2 ? HORIZ_WHEEL_EVENT : WHEEL_EVENT);
+          result->code = 0;         /* Not used.  */
+          result->modifiers &= ~(up_modifier || down_modifier);
+          result->modifiers |= wheel & 1 ? up_modifier : down_modifier;
+        }
+    }
+
   /* If result->window is not the frame's edit widget (which can
      happen with GTK+ scroll bars, for example), translate the
      coordinates so they appear at the correct position.  */
@@ -21873,13 +21897,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 			&& event->xbutton.time > ignore_next_mouse_click_timeout)
 		      {
 			ignore_next_mouse_click_timeout = 0;
-			x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+			x_construct_mouse_click (&inev.ie, &event->xbutton,
+			                         f, false);
 		      }
 		    if (event->type == ButtonRelease)
 		      ignore_next_mouse_click_timeout = 0;
 		  }
 		else
-		  x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+		  x_construct_mouse_click (&inev.ie, &event->xbutton, f, false);
 
 		*finish = X_EVENT_DROP;
 		goto OTHER;
@@ -21949,13 +21974,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                           && event->xbutton.time > ignore_next_mouse_click_timeout)
                         {
                           ignore_next_mouse_click_timeout = 0;
-                          x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+                          x_construct_mouse_click (&inev.ie, &event->xbutton,
+                                                   f, false);
                         }
                       if (event->type == ButtonRelease)
                         ignore_next_mouse_click_timeout = 0;
                     }
                   else
-                    x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+                    x_construct_mouse_click (&inev.ie, &event->xbutton,
+                                             f, false);
 
 		  if (!NILP (tab_bar_arg))
 		    inev.ie.arg = tab_bar_arg;
@@ -23732,13 +23759,13 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 				&& xev->time > ignore_next_mouse_click_timeout)
 			      {
 				ignore_next_mouse_click_timeout = 0;
-				x_construct_mouse_click (&inev.ie, &bv, f);
+				x_construct_mouse_click (&inev.ie, &bv, f, true);
 			      }
 			    if (xev->evtype == XI_ButtonRelease)
 			      ignore_next_mouse_click_timeout = 0;
 			  }
 			else
-			  x_construct_mouse_click (&inev.ie, &bv, f);
+			  x_construct_mouse_click (&inev.ie, &bv, f, true);
 
 			if (!NILP (tab_bar_arg))
 			  inev.ie.arg = tab_bar_arg;
@@ -32444,6 +32471,12 @@ syms_of_xterm (void)
   DEFSYM (Qexpose, "expose");
   DEFSYM (Qdont_save, "dont-save");
 
+  DEFSYM (Qmouse_wheel_buttons, "mouse-wheel-buttons");
+  DEFSYM (Qwheel_up,    "wheel-up");
+  DEFSYM (Qwheel_down,  "wheel-down");
+  DEFSYM (Qwheel_left,  "wheel-left");
+  DEFSYM (Qwheel_right, "wheel-right");
+
 #ifdef USE_GTK
   xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
   staticpro (&xg_default_icon_file);
-- 
2.43.0


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Sun, 03 Mar 2024 16:24:01 GMT) Full text and rfc822 format available.

Message #31 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Po Lu <luangruo <at> yahoo.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Sun, 03 Mar 2024 11:22:39 -0500
Ping?

I believe this patch should be much less controversial since it allows
users to get the old behavior back and still keeps the same semantics
for existing `mouse-wheel-*-event` variables in case some other code
still generates such events.  It's basically a half-way step between
what I proposed at first and the status quot.

But I'd like some confirmation that you think it's acceptable, and maybe
if you could comment on the FIXME included in there (I needed it for
clicks on the tab-bar, but I don't understand that code).


        Stefan


Stefan Monnier [2024-02-10 10:33:01] wrote:

>> Or maybe we should keep `mouse-wheel-*-event` untouched (tho, maybe mark
>> them obsolete) and instead introduce a new set of variables that control
>> the remapping of `mouse-4/5/6/7` to `wheel-*` events.
>
> See patch below.
> It would need etc/NEWS and doc changes, of course, and probably some
> warning-silencing in those packages using `mouse-wheel-*-event`s.
>
>
>         Stefan
>
> From 0e94e1140a8ec72bd068648eb5ec1dc861f0884b Mon Sep 17 00:00:00 2001
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Date: Mon, 29 Jan 2024 09:35:09 -0500
> Subject: [PATCH] (mouse-wheel-buttons): Map old-style wheel buttons to actual
>  wheel events
>
> Change the handling of the old X11 convention to use mouse-4/5/6/7
> events to represent wheel events: instead of asking downstream
> packages to use the `mouse-wheel-*-event` variables to know which events
> represent wheel events, use new var `mouse-wheel-buttons` to directly
> convert those events into the standard `wheel-up/down/left/right` events
> used everywhere else.
>
> This will simplify the work of packages which can thus just bind their
> commands to `wheel-up/down/left/right`.
>
> * lisp/mouse.el (mouse-wheel-buttons): New custom variable.
>
> * src/keyboard.c (make_lispy_event): Adjust for "wheel-clicks" on the tab-bar.
> * src/xterm.c (x_construct_mouse_click): Add `xi2` argument and
> obey `mouse-wheel-buttons` variable.
> (handle_one_xevent): Adjust calls accordingly.
> (syms_of_xterm): Define the `mouse-wheel-buttons` and the
> `wheel-up/down/left/right`symbols.
>
> * lisp/xt-mouse.el: Don't require `mwheel` any more.
> (xterm-mouse--same-button-p): Delete function.
> (xterm-mouse--read-event-sequence): Use `mouse-wheel-buttons`.
>
> * lisp/mwheel.el (mouse-wheel-up-event, mouse-wheel-down-event)
> (mouse-wheel-left-event, mouse-wheel-right-event): Make obsolete.
> (mouse-wheel-obey-old-style-wheel-buttons): Delete variable.
> ---
>  lisp/mouse.el    | 13 ++++++++++++
>  lisp/mwheel.el   | 21 ++++++++-----------
>  lisp/xt-mouse.el | 20 ++++--------------
>  src/keyboard.c   |  9 ++++++--
>  src/xterm.c      | 53 +++++++++++++++++++++++++++++++++++++++---------
>  5 files changed, 75 insertions(+), 41 deletions(-)
>
> diff --git a/lisp/mouse.el b/lisp/mouse.el
> index d1b06c2040d..585891bf699 100644
> --- a/lisp/mouse.el
> +++ b/lisp/mouse.el
> @@ -133,6 +133,19 @@ mouse-drag-mode-line-buffer
>    :type 'boolean
>    :version "29.1")
>  
> +(defcustom mouse-wheel-buttons
> +  '((4 . wheel-up) (5 . wheel-down) (6 . wheel-left) (7 . wheel-right))
> +  "Buttons to remap to wheel events.
> +This is an alist of (NUMBER . SYMBOL) used to remap old-style mouse wheel
> +events represented as mouse button events.  It remaps mouse button event
> +NUMBER to the event SYMBOL.  SYMBOL must be one of `wheel-up', `wheel-down',
> +`wheel-left', or `wheel-right'.
> +This is used only for events that come from sources known to generate such
> +events, such as X11 events when XInput2 is not used, or events coming from
> +a text terminal."
> +  :type '(alist)
> +  :version "30.1")
> +
>  (defvar mouse--last-down nil)
>  
>  (defun mouse--down-1-maybe-follows-link (&optional _prompt)
> diff --git a/lisp/mwheel.el b/lisp/mwheel.el
> index 66a1fa1a706..9fc922eebc9 100644
> --- a/lisp/mwheel.el
> +++ b/lisp/mwheel.el
> @@ -56,20 +56,17 @@ mouse-wheel-change-button
>               (bound-and-true-p mouse-wheel-mode))
>      (mouse-wheel-mode 1)))
>  
> -(defvar mouse-wheel-obey-old-style-wheel-buttons t
> -  "If non-nil, treat mouse-4/5/6/7 events as mouse wheel events.
> -These are the event names used historically in X11 before XInput2.
> -They are sometimes generated by things like text-terminals as well.")
> +(make-obsolete-variable 'mouse-wheel-up-event    'mouse-wheel-buttons "30.1")
> +(make-obsolete-variable 'mouse-wheel-down-event  'mouse-wheel-buttons "30.1")
> +(make-obsolete-variable 'mouse-wheel-left-event  'mouse-wheel-buttons "30.1")
> +(make-obsolete-variable 'mouse-wheel-right-event 'mouse-wheel-buttons "30.1")
>  
> -(defcustom mouse-wheel-down-event
> -  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-4)
> +(defcustom mouse-wheel-down-event 'mouse-4
>    "Event used for scrolling down, beside `wheel-up', if any."
>    :group 'mouse
>    :type 'symbol
>    :set #'mouse-wheel-change-button)
> -
> -(defcustom mouse-wheel-up-event
> -  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-5)
> +(defcustom mouse-wheel-up-event 'mouse-5
>    "Event used for scrolling up, beside `wheel-down', if any."
>    :group 'mouse
>    :type 'symbol
> @@ -223,12 +220,10 @@ mwheel-scroll-left-function
>  (defvar mwheel-scroll-right-function 'scroll-right
>    "Function that does the job of scrolling right.")
>  
> -(defvar mouse-wheel-left-event
> -  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-6)
> +(defvar mouse-wheel-left-event 'mouse-6
>    "Event used for scrolling left, beside `wheel-left', if any.")
>  
> -(defvar mouse-wheel-right-event
> -  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-7)
> +(defvar mouse-wheel-right-event 'mouse-7
>    "Event used for scrolling right, beside `wheel-right', if any.")
>  
>  (defun mouse-wheel--get-scroll-window (event)
> diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
> index 081b8f32456..c27dee7e249 100644
> --- a/lisp/xt-mouse.el
> +++ b/lisp/xt-mouse.el
> @@ -40,8 +40,6 @@
>  
>  ;;; Code:
>  
> -(require 'mwheel)
> -
>  (defvar xterm-mouse-debug-buffer nil)
>  
>  (defun xterm-mouse-translate (_event)
> @@ -195,12 +193,6 @@ xterm-mouse--read-number-from-terminal
>            (cons n c))
>        (cons (- (setq c (xterm-mouse--read-coordinate)) 32) c))))
>  
> -(defun xterm-mouse--button-p (event btn)
> -  (and (symbolp event)
> -       (string-prefix-p "mouse-" (symbol-name event))
> -       (eq btn (car (read-from-string (symbol-name event)
> -                                      (length "mouse-"))))))
> -
>  ;; XTerm reports mouse events as
>  ;; <EVENT-CODE> <X> <Y> in default mode, and
>  ;; <EVENT-CODE> ";" <X> ";" <Y> <"M" or "m"> in extended mode.
> @@ -246,14 +238,10 @@ xterm-mouse--read-event-sequence
>              (if meta "M-" "")
>              (if shift "S-" "")
>              (if down "down-" "")
> -            (cond
> -             ;; BEWARE: `mouse-wheel-UP-event' corresponds to
> -             ;; `wheel-DOWN' events and vice versa!!
> -             ((xterm-mouse--button-p mouse-wheel-down-event btn)  "wheel-up")
> -             ((xterm-mouse--button-p mouse-wheel-up-event btn)    "wheel-down")
> -             ((xterm-mouse--button-p mouse-wheel-left-event btn)  "wheel-left")
> -             ((xterm-mouse--button-p mouse-wheel-right-event btn) "wheel-right")
> -             (t (format "mouse-%d" btn))))))))
> +            (let ((remap (alist-get btn mouse-wheel-buttons)))
> +              (if remap
> +                  (symbol-name remap)
> +                (format "mouse-%d" btn))))))))
>      (list sym (1- x) (1- y))))
>  
>  (defun xterm-mouse--set-click-count (event click-count)
> diff --git a/src/keyboard.c b/src/keyboard.c
> index 1f7253a7da1..4c3e33762af 100644
> --- a/src/keyboard.c
> +++ b/src/keyboard.c
> @@ -6628,8 +6628,13 @@ make_lispy_event (struct input_event *event)
>  
>  	if (CONSP (event->arg))
>  	  return list5 (head, position, make_fixnum (double_click_count),
> -			XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)),
> -						  XCAR (XCDR (XCDR (event->arg)))));
> +			XCAR (event->arg),
> +			/* FIXME: I don't know what I'm doing here.  */
> +			(CONSP (XCDR (event->arg))
> +			 && CONSP (XCDR (XCDR (event->arg))))
> +			? Fcons (XCAR (XCDR (event->arg)),
> +			         XCAR (XCDR (XCDR (event->arg))))
> +			: Qnil);
>          else if (NUMBERP (event->arg))
>            return list4 (head, position, make_fixnum (double_click_count),
>                          event->arg);
> diff --git a/src/xterm.c b/src/xterm.c
> index c8a43785564..e75b64ed3d4 100644
> --- a/src/xterm.c
> +++ b/src/xterm.c
> @@ -14543,18 +14543,19 @@ x_query_pointer (Display *dpy, Window w, Window *root_return,
>     `x', `y', `x_root' and `y_root'.  This function should not access
>     any other fields in EVENT without also initializing the
>     corresponding fields in `bv' under the XI_ButtonPress and
> -   XI_ButtonRelease labels inside `handle_one_xevent'.  */
> +   XI_ButtonRelease labels inside `handle_one_xevent'.
> +
> +   XI2 indicates that this click comes from XInput2 rather than core
> +   event.   */
>  
>  static Lisp_Object
>  x_construct_mouse_click (struct input_event *result,
>                           const XButtonEvent *event,
> -                         struct frame *f)
> +                         struct frame *f, bool xi2)
>  {
>    int x = event->x;
>    int y = event->y;
>  
> -  /* Make the event type NO_EVENT; we'll change that when we decide
> -     otherwise.  */
>    result->kind = MOUSE_CLICK_EVENT;
>    result->code = event->button - Button1;
>    result->timestamp = event->time;
> @@ -14564,6 +14565,29 @@ x_construct_mouse_click (struct input_event *result,
>  			  ? up_modifier
>  			  : down_modifier));
>  
> +  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
> +  if (!xi2)
> +    {
> +      Lisp_Object base
> +        = Fcdr_safe (Fassq (make_fixnum (result->code + 1),
> +                            Fsymbol_value (Qmouse_wheel_buttons)));
> +      int wheel
> +        = NILP (base) ? -1
> +          : BASE_EQ (base, Qwheel_down)  ? 0
> +          : BASE_EQ (base, Qwheel_up)    ? 1
> +          : BASE_EQ (base, Qwheel_left)  ? 2
> +          : BASE_EQ (base, Qwheel_right) ? 3
> +          : -1;
> +      if (wheel >= 0)
> +        {
> +          result->kind = (event->type != ButtonRelease ? NO_EVENT
> +		          : wheel & 2 ? HORIZ_WHEEL_EVENT : WHEEL_EVENT);
> +          result->code = 0;         /* Not used.  */
> +          result->modifiers &= ~(up_modifier || down_modifier);
> +          result->modifiers |= wheel & 1 ? up_modifier : down_modifier;
> +        }
> +    }
> +
>    /* If result->window is not the frame's edit widget (which can
>       happen with GTK+ scroll bars, for example), translate the
>       coordinates so they appear at the correct position.  */
> @@ -21873,13 +21897,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
>  			&& event->xbutton.time > ignore_next_mouse_click_timeout)
>  		      {
>  			ignore_next_mouse_click_timeout = 0;
> -			x_construct_mouse_click (&inev.ie, &event->xbutton, f);
> +			x_construct_mouse_click (&inev.ie, &event->xbutton,
> +			                         f, false);
>  		      }
>  		    if (event->type == ButtonRelease)
>  		      ignore_next_mouse_click_timeout = 0;
>  		  }
>  		else
> -		  x_construct_mouse_click (&inev.ie, &event->xbutton, f);
> +		  x_construct_mouse_click (&inev.ie, &event->xbutton, f, false);
>  
>  		*finish = X_EVENT_DROP;
>  		goto OTHER;
> @@ -21949,13 +21974,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
>                            && event->xbutton.time > ignore_next_mouse_click_timeout)
>                          {
>                            ignore_next_mouse_click_timeout = 0;
> -                          x_construct_mouse_click (&inev.ie, &event->xbutton, f);
> +                          x_construct_mouse_click (&inev.ie, &event->xbutton,
> +                                                   f, false);
>                          }
>                        if (event->type == ButtonRelease)
>                          ignore_next_mouse_click_timeout = 0;
>                      }
>                    else
> -                    x_construct_mouse_click (&inev.ie, &event->xbutton, f);
> +                    x_construct_mouse_click (&inev.ie, &event->xbutton,
> +                                             f, false);
>  
>  		  if (!NILP (tab_bar_arg))
>  		    inev.ie.arg = tab_bar_arg;
> @@ -23732,13 +23759,13 @@ handle_one_xevent (struct x_display_info *dpyinfo,
>  				&& xev->time > ignore_next_mouse_click_timeout)
>  			      {
>  				ignore_next_mouse_click_timeout = 0;
> -				x_construct_mouse_click (&inev.ie, &bv, f);
> +				x_construct_mouse_click (&inev.ie, &bv, f, true);
>  			      }
>  			    if (xev->evtype == XI_ButtonRelease)
>  			      ignore_next_mouse_click_timeout = 0;
>  			  }
>  			else
> -			  x_construct_mouse_click (&inev.ie, &bv, f);
> +			  x_construct_mouse_click (&inev.ie, &bv, f, true);
>  
>  			if (!NILP (tab_bar_arg))
>  			  inev.ie.arg = tab_bar_arg;
> @@ -32444,6 +32471,12 @@ syms_of_xterm (void)
>    DEFSYM (Qexpose, "expose");
>    DEFSYM (Qdont_save, "dont-save");
>  
> +  DEFSYM (Qmouse_wheel_buttons, "mouse-wheel-buttons");
> +  DEFSYM (Qwheel_up,    "wheel-up");
> +  DEFSYM (Qwheel_down,  "wheel-down");
> +  DEFSYM (Qwheel_left,  "wheel-left");
> +  DEFSYM (Qwheel_right, "wheel-right");
> +
>  #ifdef USE_GTK
>    xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
>    staticpro (&xg_default_icon_file);





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Mon, 04 Mar 2024 01:50:02 GMT) Full text and rfc822 format available.

Message #34 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Mon, 04 Mar 2024 09:47:54 +0800
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

> Ping?
>
> I believe this patch should be much less controversial since it allows
> users to get the old behavior back and still keeps the same semantics
> for existing `mouse-wheel-*-event` variables in case some other code
> still generates such events.  It's basically a half-way step between
> what I proposed at first and the status quot.
>
> But I'd like some confirmation that you think it's acceptable, and maybe
> if you could comment on the FIXME included in there (I needed it for
> clicks on the tab-bar, but I don't understand that code).

That would be simple if I could find the FIXME, but it doesn't appear to
be present anywhere in that patch...

>> +  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
>> +  if (!xi2)
>> +    {
>> +      Lisp_Object base
>> +        = Fcdr_safe (Fassq (make_fixnum (result->code + 1),
>> +                            Fsymbol_value (Qmouse_wheel_buttons)));
>> +      int wheel
>> +        = NILP (base) ? -1
>> +          : BASE_EQ (base, Qwheel_down)  ? 0
>> +          : BASE_EQ (base, Qwheel_up)    ? 1
>> +          : BASE_EQ (base, Qwheel_left)  ? 2
>> +          : BASE_EQ (base, Qwheel_right) ? 3
>> +          : -1;

This should be surrounded by parentheses.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Mon, 04 Mar 2024 03:09:01 GMT) Full text and rfc822 format available.

Message #37 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Po Lu <luangruo <at> yahoo.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: xterm.c: Convert mouse-4/5/6/7 to
 wheel-up/down/left/right
Date: Sun, 03 Mar 2024 22:07:40 -0500
> That would be simple if I could find the FIXME, but it doesn't appear to
> be present anywhere in that patch...

[ Hmm... not sure what happened: `C-s FIXME` finds it for me:  ]

diff --git a/src/keyboard.c b/src/keyboard.c
index 1f7253a7da1..4c3e33762af 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6628,8 +6628,13 @@ make_lispy_event (struct input_event *event)
 
 	if (CONSP (event->arg))
 	  return list5 (head, position, make_fixnum (double_click_count),
-			XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)),
-						  XCAR (XCDR (XCDR (event->arg)))));
+			XCAR (event->arg),
+			/* FIXME: I don't know what I'm doing here.  */
+			(CONSP (XCDR (event->arg))
+			 && CONSP (XCDR (XCDR (event->arg))))
+			? Fcons (XCAR (XCDR (event->arg)),
+			         XCAR (XCDR (XCDR (event->arg))))
+			: Qnil);
         else if (NUMBERP (event->arg))
           return list4 (head, position, make_fixnum (double_click_count),
                         event->arg);

>>> +  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
>>> +  if (!xi2)
>>> +    {
>>> +      Lisp_Object base
>>> +        = Fcdr_safe (Fassq (make_fixnum (result->code + 1),
>>> +                            Fsymbol_value (Qmouse_wheel_buttons)));
>>> +      int wheel
>>> +        = NILP (base) ? -1
>>> +          : BASE_EQ (base, Qwheel_down)  ? 0
>>> +          : BASE_EQ (base, Qwheel_up)    ? 1
>>> +          : BASE_EQ (base, Qwheel_left)  ? 2
>>> +          : BASE_EQ (base, Qwheel_right) ? 3
>>> +          : -1;
>
> This should be surrounded by parentheses.

Ah, it might be need for CC-mode, indeed, thanks.
`sm-c-mode` gets this right without the parens :-)


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Wed, 03 Apr 2024 19:31:02 GMT) Full text and rfc822 format available.

Message #40 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Po Lu <luangruo <at> yahoo.com>
Cc: 68796 <at> debbugs.gnu.org
Subject: Re: Stefan's wheel event change
Date: Wed, 03 Apr 2024 15:27:54 -0400
[Message part 1 (text/plain, inline)]
> I'm now satisfied that Stefan's change to return wheel events on all
> platforms does not produce the adverse effects I feared, but I have also
> misplaced the number of the bug report where it was discussed, so,
> Stefan, please post your version of the patch again before it is
> installed.  Thanks in advance.

Here it is, with a brand new etc/NEWS,


        Stefan
[0001-mouse-wheel-buttons-Map-old-style-wheel-buttons-to-a.patch (text/x-diff, inline)]
From 56559400277d5535713349431ca0cda967e8e281 Mon Sep 17 00:00:00 2001
From: Stefan Monnier <monnier <at> iro.umontreal.ca>
Date: Mon, 29 Jan 2024 09:35:09 -0500
Subject: [PATCH] (mouse-wheel-buttons): Map old-style wheel buttons to actual
 wheel events

Change the handling of the old X11 convention to use mouse-4/5/6/7
events to represent wheel events: instead of asking downstream
packages to use the `mouse-wheel-*-event` variables to know which events
represent wheel events, use new var `mouse-wheel-buttons` to directly
convert those events into the standard `wheel-up/down/left/right` events
used everywhere else.

This will simplify the work of packages which can thus just bind their
commands to `wheel-up/down/left/right`.

* lisp/mouse.el (mouse-wheel-buttons): New custom variable.

* src/keyboard.c (make_lispy_event): Adjust for "wheel-clicks" on the tab-bar.
* src/xterm.c (x_construct_mouse_click): Add `xi2` argument and
obey `mouse-wheel-buttons` variable.
(handle_one_xevent): Adjust calls accordingly.
(syms_of_xterm): Define the `mouse-wheel-buttons` and the
`wheel-up/down/left/right`symbols.

* lisp/xt-mouse.el: Don't require `mwheel` any more.
(xterm-mouse--same-button-p): Delete function.
(xterm-mouse--read-event-sequence): Use `mouse-wheel-buttons`.

* lisp/mwheel.el (mouse-wheel-up-event, mouse-wheel-down-event)
(mouse-wheel-left-event, mouse-wheel-right-event): Make obsolete.
(mouse-wheel-obey-old-style-wheel-buttons): Delete variable.
---
 etc/NEWS         | 16 ++++++++++-----
 lisp/mouse.el    | 13 ++++++++++++
 lisp/mwheel.el   | 21 ++++++++-----------
 lisp/xt-mouse.el | 20 ++++--------------
 src/keyboard.c   | 13 ++++++++++--
 src/xterm.c      | 53 +++++++++++++++++++++++++++++++++++++++---------
 6 files changed, 90 insertions(+), 46 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 2654d9d7995..d1054d4337b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -68,6 +68,12 @@ more details.
 
 * Incompatible Changes in Emacs 30.1
 
+** Mouse wheel events should now always be 'wheel-up/down/left/right'.
+At those places where the old 'mouse-4/5/6/7' events could still occur
+(i.e. X11 input in the absence of XInput2, and `xterm-mouse-mode`),
+we remap them to the corresponding 'wheel-up/down/left/right' event,
+according to the new variable 'mouse-wheel-buttons'.
+
 ** Tree-Sitter modes are now declared as submodes of the non-TS modes.
 In order to help the use of those Tree-Sitter modes, they are now
 declared to have the corresponding non-Tree-Sitter mode as an
@@ -520,15 +526,15 @@ In batch mode, tracing now sends the trace to stdout.
 ** Mwheel
 The 'wheel-up/down/left/right' events are now bound unconditionally,
 and the 'mouse-wheel-up/down/left/right-event' variables are thus used
-only to specify the 'mouse-4/5/6/7' events generated by older
-configurations such as X11 when the X server does not support at least
-version 2.1 of the X Input Extension, and 'xterm-mouse-mode'.
+only to specify the 'mouse-4/5/6/7' events that might still
+happen to be generated by some old packages (or if 'mouse-wheel-buttons'
+has been set to nil).
 
 ** 'xterm-mouse-mode'
 This mode now emits 'wheel-up/down/right/left' events instead of
 'mouse-4/5/6/7' events for the mouse wheel.
-It uses the 'mouse-wheel-up/down/left/right-event'
-variables to decide which button maps to which wheel event (if any).
+It uses the new variable 'mouse-wheel-buttons' to decide which button
+maps to which wheel event (if any).
 
 ** Info
 
diff --git a/lisp/mouse.el b/lisp/mouse.el
index cef88dede8a..ae5a6455566 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -133,6 +133,19 @@ mouse-drag-mode-line-buffer
   :type 'boolean
   :version "29.1")
 
+(defcustom mouse-wheel-buttons
+  '((4 . wheel-up) (5 . wheel-down) (6 . wheel-left) (7 . wheel-right))
+  "Buttons to remap to wheel events.
+This is an alist of (NUMBER . SYMBOL) used to remap old-style mouse wheel
+events represented as mouse button events.  It remaps mouse button event
+NUMBER to the event SYMBOL.  SYMBOL must be one of `wheel-up', `wheel-down',
+`wheel-left', or `wheel-right'.
+This is used only for events that come from sources known to generate such
+events, such as X11 events when XInput2 is not used, or events coming from
+a text terminal."
+  :type '(alist)
+  :version "30.1")
+
 (defvar mouse--last-down nil)
 
 (defun mouse--down-1-maybe-follows-link (&optional _prompt)
diff --git a/lisp/mwheel.el b/lisp/mwheel.el
index 66a1fa1a706..9fc922eebc9 100644
--- a/lisp/mwheel.el
+++ b/lisp/mwheel.el
@@ -56,20 +56,17 @@ mouse-wheel-change-button
              (bound-and-true-p mouse-wheel-mode))
     (mouse-wheel-mode 1)))
 
-(defvar mouse-wheel-obey-old-style-wheel-buttons t
-  "If non-nil, treat mouse-4/5/6/7 events as mouse wheel events.
-These are the event names used historically in X11 before XInput2.
-They are sometimes generated by things like text-terminals as well.")
+(make-obsolete-variable 'mouse-wheel-up-event    'mouse-wheel-buttons "30.1")
+(make-obsolete-variable 'mouse-wheel-down-event  'mouse-wheel-buttons "30.1")
+(make-obsolete-variable 'mouse-wheel-left-event  'mouse-wheel-buttons "30.1")
+(make-obsolete-variable 'mouse-wheel-right-event 'mouse-wheel-buttons "30.1")
 
-(defcustom mouse-wheel-down-event
-  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-4)
+(defcustom mouse-wheel-down-event 'mouse-4
   "Event used for scrolling down, beside `wheel-up', if any."
   :group 'mouse
   :type 'symbol
   :set #'mouse-wheel-change-button)
-
-(defcustom mouse-wheel-up-event
-  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-5)
+(defcustom mouse-wheel-up-event 'mouse-5
   "Event used for scrolling up, beside `wheel-down', if any."
   :group 'mouse
   :type 'symbol
@@ -223,12 +220,10 @@ mwheel-scroll-left-function
 (defvar mwheel-scroll-right-function 'scroll-right
   "Function that does the job of scrolling right.")
 
-(defvar mouse-wheel-left-event
-  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-6)
+(defvar mouse-wheel-left-event 'mouse-6
   "Event used for scrolling left, beside `wheel-left', if any.")
 
-(defvar mouse-wheel-right-event
-  (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-7)
+(defvar mouse-wheel-right-event 'mouse-7
   "Event used for scrolling right, beside `wheel-right', if any.")
 
 (defun mouse-wheel--get-scroll-window (event)
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
index 081b8f32456..c27dee7e249 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -40,8 +40,6 @@
 
 ;;; Code:
 
-(require 'mwheel)
-
 (defvar xterm-mouse-debug-buffer nil)
 
 (defun xterm-mouse-translate (_event)
@@ -195,12 +193,6 @@ xterm-mouse--read-number-from-terminal
           (cons n c))
       (cons (- (setq c (xterm-mouse--read-coordinate)) 32) c))))
 
-(defun xterm-mouse--button-p (event btn)
-  (and (symbolp event)
-       (string-prefix-p "mouse-" (symbol-name event))
-       (eq btn (car (read-from-string (symbol-name event)
-                                      (length "mouse-"))))))
-
 ;; XTerm reports mouse events as
 ;; <EVENT-CODE> <X> <Y> in default mode, and
 ;; <EVENT-CODE> ";" <X> ";" <Y> <"M" or "m"> in extended mode.
@@ -246,14 +238,10 @@ xterm-mouse--read-event-sequence
             (if meta "M-" "")
             (if shift "S-" "")
             (if down "down-" "")
-            (cond
-             ;; BEWARE: `mouse-wheel-UP-event' corresponds to
-             ;; `wheel-DOWN' events and vice versa!!
-             ((xterm-mouse--button-p mouse-wheel-down-event btn)  "wheel-up")
-             ((xterm-mouse--button-p mouse-wheel-up-event btn)    "wheel-down")
-             ((xterm-mouse--button-p mouse-wheel-left-event btn)  "wheel-left")
-             ((xterm-mouse--button-p mouse-wheel-right-event btn) "wheel-right")
-             (t (format "mouse-%d" btn))))))))
+            (let ((remap (alist-get btn mouse-wheel-buttons)))
+              (if remap
+                  (symbol-name remap)
+                (format "mouse-%d" btn))))))))
     (list sym (1- x) (1- y))))
 
 (defun xterm-mouse--set-click-count (event click-count)
diff --git a/src/keyboard.c b/src/keyboard.c
index 91faf4582fa..a06c9116d24 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6639,8 +6639,17 @@ make_lispy_event (struct input_event *event)
 
 	if (CONSP (event->arg))
 	  return list5 (head, position, make_fixnum (double_click_count),
-			XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)),
-						  XCAR (XCDR (XCDR (event->arg)))));
+			XCAR (event->arg),
+			/* FIXME: When a mouse-click on a tab-bar is
+                           converted into a wheel-event we get here something
+                           of an unexpected shape...  */
+			(CONSP (XCDR (event->arg))
+			 && CONSP (XCDR (XCDR (event->arg))))
+			? Fcons (XCAR (XCDR (event->arg)),
+			         XCAR (XCDR (XCDR (event->arg))))
+			/* ... not knowing what this "unexpected shape" means,
+			   we just use nil.  */
+			: Qnil);
         else if (NUMBERP (event->arg))
           return list4 (head, position, make_fixnum (double_click_count),
                         event->arg);
diff --git a/src/xterm.c b/src/xterm.c
index c0aef65ab66..5e5eb6269e4 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -14551,18 +14551,19 @@ x_query_pointer (Display *dpy, Window w, Window *root_return,
    `x', `y', `x_root' and `y_root'.  This function should not access
    any other fields in EVENT without also initializing the
    corresponding fields in `bv' under the XI_ButtonPress and
-   XI_ButtonRelease labels inside `handle_one_xevent'.  */
+   XI_ButtonRelease labels inside `handle_one_xevent'.
+
+   XI2 indicates that this click comes from XInput2 rather than core
+   event.   */
 
 static Lisp_Object
 x_construct_mouse_click (struct input_event *result,
                          const XButtonEvent *event,
-                         struct frame *f)
+                         struct frame *f, bool xi2)
 {
   int x = event->x;
   int y = event->y;
 
-  /* Make the event type NO_EVENT; we'll change that when we decide
-     otherwise.  */
   result->kind = MOUSE_CLICK_EVENT;
   result->code = event->button - Button1;
   result->timestamp = event->time;
@@ -14572,6 +14573,29 @@ x_construct_mouse_click (struct input_event *result,
 			  ? up_modifier
 			  : down_modifier));
 
+  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
+  if (!xi2)
+    {
+      Lisp_Object base
+        = Fcdr_safe (Fassq (make_fixnum (result->code + 1),
+                            Fsymbol_value (Qmouse_wheel_buttons)));
+      int wheel
+        = (NILP (base) ? -1
+           : BASE_EQ (base, Qwheel_down)  ? 0
+           : BASE_EQ (base, Qwheel_up)    ? 1
+           : BASE_EQ (base, Qwheel_left)  ? 2
+           : BASE_EQ (base, Qwheel_right) ? 3
+           : -1);
+      if (wheel >= 0)
+        {
+          result->kind = (event->type != ButtonRelease ? NO_EVENT
+		          : wheel & 2 ? HORIZ_WHEEL_EVENT : WHEEL_EVENT);
+          result->code = 0;         /* Not used.  */
+          result->modifiers &= ~(up_modifier || down_modifier);
+          result->modifiers |= wheel & 1 ? up_modifier : down_modifier;
+        }
+    }
+
   /* If result->window is not the frame's edit widget (which can
      happen with GTK+ scroll bars, for example), translate the
      coordinates so they appear at the correct position.  */
@@ -21881,13 +21905,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 			&& event->xbutton.time > ignore_next_mouse_click_timeout)
 		      {
 			ignore_next_mouse_click_timeout = 0;
-			x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+			x_construct_mouse_click (&inev.ie, &event->xbutton,
+			                         f, false);
 		      }
 		    if (event->type == ButtonRelease)
 		      ignore_next_mouse_click_timeout = 0;
 		  }
 		else
-		  x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+		  x_construct_mouse_click (&inev.ie, &event->xbutton, f, false);
 
 		*finish = X_EVENT_DROP;
 		goto OTHER;
@@ -21957,13 +21982,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                           && event->xbutton.time > ignore_next_mouse_click_timeout)
                         {
                           ignore_next_mouse_click_timeout = 0;
-                          x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+                          x_construct_mouse_click (&inev.ie, &event->xbutton,
+                                                   f, false);
                         }
                       if (event->type == ButtonRelease)
                         ignore_next_mouse_click_timeout = 0;
                     }
                   else
-                    x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+                    x_construct_mouse_click (&inev.ie, &event->xbutton,
+                                             f, false);
 
 		  if (!NILP (tab_bar_arg))
 		    inev.ie.arg = tab_bar_arg;
@@ -23740,13 +23767,13 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 				&& xev->time > ignore_next_mouse_click_timeout)
 			      {
 				ignore_next_mouse_click_timeout = 0;
-				x_construct_mouse_click (&inev.ie, &bv, f);
+				x_construct_mouse_click (&inev.ie, &bv, f, true);
 			      }
 			    if (xev->evtype == XI_ButtonRelease)
 			      ignore_next_mouse_click_timeout = 0;
 			  }
 			else
-			  x_construct_mouse_click (&inev.ie, &bv, f);
+			  x_construct_mouse_click (&inev.ie, &bv, f, true);
 
 			if (!NILP (tab_bar_arg))
 			  inev.ie.arg = tab_bar_arg;
@@ -32452,6 +32479,12 @@ syms_of_xterm (void)
   DEFSYM (Qexpose, "expose");
   DEFSYM (Qdont_save, "dont-save");
 
+  DEFSYM (Qmouse_wheel_buttons, "mouse-wheel-buttons");
+  DEFSYM (Qwheel_up,    "wheel-up");
+  DEFSYM (Qwheel_down,  "wheel-down");
+  DEFSYM (Qwheel_left,  "wheel-left");
+  DEFSYM (Qwheel_right, "wheel-right");
+
 #ifdef USE_GTK
   xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
   staticpro (&xg_default_icon_file);
-- 
2.43.0


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Thu, 04 Apr 2024 05:23:01 GMT) Full text and rfc822 format available.

Message #43 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: luangruo <at> yahoo.com, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: Stefan's wheel event change
Date: Thu, 04 Apr 2024 08:21:43 +0300
> Cc: 68796 <at> debbugs.gnu.org
> Date: Wed, 03 Apr 2024 15:27:54 -0400
> From:  Stefan Monnier via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> > I'm now satisfied that Stefan's change to return wheel events on all
> > platforms does not produce the adverse effects I feared, but I have also
> > misplaced the number of the bug report where it was discussed, so,
> > Stefan, please post your version of the patch again before it is
> > installed.  Thanks in advance.
> 
> Here it is, with a brand new etc/NEWS,

Thanks, a few minor comments below.

> Change the handling of the old X11 convention to use mouse-4/5/6/7
> events to represent wheel events: instead of asking downstream
> packages to use the `mouse-wheel-*-event` variables to know which events
> represent wheel events, use new var `mouse-wheel-buttons` to directly
> convert those events into the standard `wheel-up/down/left/right` events
> used everywhere else.
> 
> This will simplify the work of packages which can thus just bind their
> commands to `wheel-up/down/left/right`.
> 
> * lisp/mouse.el (mouse-wheel-buttons): New custom variable.
> 
> * src/keyboard.c (make_lispy_event): Adjust for "wheel-clicks" on the tab-bar.
> * src/xterm.c (x_construct_mouse_click): Add `xi2` argument and
> obey `mouse-wheel-buttons` variable.
> (handle_one_xevent): Adjust calls accordingly.
> (syms_of_xterm): Define the `mouse-wheel-buttons` and the
> `wheel-up/down/left/right`symbols.
> 
> * lisp/xt-mouse.el: Don't require `mwheel` any more.
> (xterm-mouse--same-button-p): Delete function.
> (xterm-mouse--read-event-sequence): Use `mouse-wheel-buttons`.

Nit-picking: can we please NOT use Markdown-style quoting `like this`
in our docs and change logs?

> +** Mouse wheel events should now always be 'wheel-up/down/left/right'.
> +At those places where the old 'mouse-4/5/6/7' events could still occur
> +(i.e. X11 input in the absence of XInput2, and `xterm-mouse-mode`),
> +we remap them to the corresponding 'wheel-up/down/left/right' event,
> +according to the new variable 'mouse-wheel-buttons'.

Likewise here.

> +(defcustom mouse-wheel-buttons
> +  '((4 . wheel-up) (5 . wheel-down) (6 . wheel-left) (7 . wheel-right))
> +  "Buttons to remap to wheel events.

Suggest to rephrase:

  "How to remap mouse button numbers to wheel events."

> +This is an alist of (NUMBER . SYMBOL) used to remap old-style mouse wheel
> +events represented as mouse button events.  It remaps mouse button event
> +NUMBER to the event SYMBOL.  SYMBOL must be one of `wheel-up', `wheel-down',

Not "mouse event NUMBER", but "mouse button NUMBER", I think.
Alternatively, you could say "mouse button event 'mouse-NUMBER'".
IOW, NUMBER is not a mouse event, it's a number.

> +  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
> +  if (!xi2)
> +    {
> +      Lisp_Object base
> +        = Fcdr_safe (Fassq (make_fixnum (result->code + 1),
> +                            Fsymbol_value (Qmouse_wheel_buttons)));

Should this test mouse-wheel-buttons for being bound and have a list
value, before calling assq?  mouse.el is preloaded relatively late in
loadup, so I think we had better played it safe, no?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Fri, 05 Apr 2024 21:25:03 GMT) Full text and rfc822 format available.

Message #46 received at 68796 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: luangruo <at> yahoo.com, 68796 <at> debbugs.gnu.org
Subject: Re: bug#68796: Stefan's wheel event change
Date: Fri, 05 Apr 2024 17:22:05 -0400
>> +** Mouse wheel events should now always be 'wheel-up/down/left/right'.
>> +At those places where the old 'mouse-4/5/6/7' events could still occur
>> +(i.e. X11 input in the absence of XInput2, and `xterm-mouse-mode`),
>> +we remap them to the corresponding 'wheel-up/down/left/right' event,
>> +according to the new variable 'mouse-wheel-buttons'.
>
> Likewise here.

Fixed.

>> +(defcustom mouse-wheel-buttons
>> +  '((4 . wheel-up) (5 . wheel-down) (6 . wheel-left) (7 . wheel-right))
>> +  "Buttons to remap to wheel events.
>
> Suggest to rephrase:
>
>   "How to remap mouse button numbers to wheel events."

Thanks.

>> +This is an alist of (NUMBER . SYMBOL) used to remap old-style mouse wheel
>> +events represented as mouse button events.  It remaps mouse button event
>> +NUMBER to the event SYMBOL.  SYMBOL must be one of `wheel-up', `wheel-down',
>
> Not "mouse event NUMBER", but "mouse button NUMBER", I think.
> Alternatively, you could say "mouse button event 'mouse-NUMBER'".
> IOW, NUMBER is not a mouse event, it's a number.

Indeed.

>> +  /* Convert pre-XInput2 wheel events represented as mouse-clicks.  */
>> +  if (!xi2)
>> +    {
>> +      Lisp_Object base
>> +        = Fcdr_safe (Fassq (make_fixnum (result->code + 1),
>> +                            Fsymbol_value (Qmouse_wheel_buttons)));
>
> Should this test mouse-wheel-buttons for being bound and have a list
> value, before calling assq?  mouse.el is preloaded relatively late in
> loadup, so I think we had better played it safe, no?

AFAIK we can't get such events until *much* later, after the dump, so
I don't see any need for that.  Especially since it only affects mouse
clicks, so it wouldn't render Emacs unusable.

`Fassq` can also signal an error if `mouse-wheel-buttons` contains
something else than an alist, but in my tests, this simply results in
error messages when you use the mouse buttons/wheel, which is about as
good as it gets, IMO.


        Stefan





Reply sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
You have taken responsibility. (Tue, 09 Apr 2024 14:32:02 GMT) Full text and rfc822 format available.

Notification sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
bug acknowledged by developer. (Tue, 09 Apr 2024 14:32:02 GMT) Full text and rfc822 format available.

Message #51 received at 68796-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: luangruo <at> yahoo.com, 68796-done <at> debbugs.gnu.org
Subject: Re: bug#68796: Stefan's wheel event change
Date: Tue, 09 Apr 2024 10:31:03 -0400
Pushed to `master, closing,


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#68796; Package emacs. (Wed, 10 Apr 2024 01:17:02 GMT) Full text and rfc822 format available.

Message #54 received at 68796-done <at> debbugs.gnu.org (full text, mbox):

From: Po Lu <luangruo <at> yahoo.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 68796-done <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: bug#68796: Stefan's wheel event change
Date: Wed, 10 Apr 2024 09:15:53 +0800
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

> Pushed to `master, closing,

Thanks.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 08 May 2024 11:24:13 GMT) Full text and rfc822 format available.

This bug report was last modified 7 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.