Subject: Re: bug#61241: 29.0.60; Incoherent last_mouse_window (xterm.c) between XInput and XInput 2

From: Adrián Medraño Calvo <[email-masked]>
Date: Sun, 5 Feb 2023 20:04:42 +0100

Please see below.

> Am 04.02.2023 um 09:45 schrieb Po Lu <[email-masked]>:
> Eli Zaretskii <[email-masked]> writes:
> 
>>> From: Adrián Medraño Calvo
>>> <[email-masked]>
>>> Date: Thu, 2 Feb 2023 23:28:01 +0100
>>> For the implementation of `mouse-autoselect-window', the entered window
>>> is remembered and then compared when an mouse motion event is received.
>>> Up to Emacs 28, this value was stored in a static local variable named
>>> `last_mouse_window' in the block handling MotionNotify within
>>> `handle_one_xevent'.  With the introduction of XInput 2,
>>> `handle_one_xevent' was adjusted to account for XI_Motion events, with
>>> the oversight that a new local static `last_mouse_window' variable was
>>> declared in the new handler block for XI_Motion.  As a result, when
>>> Emacs receives motion events from XInput and XInput2 sources
>>> alternatively the value of each `last_mouse_window’ differs, leading to
>>> the window under the motion sometimes not being selected, as the
>>> value `last_mouse_window' is out-of-date for the particular XInput
>>> version.
>>> This bug impacts the GNU ELPA package EXWM.  EXWM tries to extrapolate
>>> applicable Emacs functionality to X window management; among others
>>> assigns an Emacs buffer to each managed X window, and positions the X
>>> window over the Emacs window in which the buffer is displayed.  When
>>> `mouse-autoselect-windows’ and the user moves the mouse pointer over one
>>> X window managed by EXWM, this X window receives the mouse events and not
>>> Emacs, therefore the Emacs window is not selected.  In order to overcome
>>> this, EXWM sends a synthetic MotionNotify event to Emacs.
>>> The attached patch fixes the issue.
> 
> Thanks.  But first of all, Emacs is not at all prepared to receive both
> MotionNotify events and XI_Motion events on a frame at the same time in
> other areas as well, such as focus tracking.
> 
> This is not possible under an X server.

Thank you. I thought already about fixing this in EXWM by sending the XI_Motion event when Emacs uses XInput 2 (as you propose below), but thought that other users might be in a similar situation. For example, a user using xdotool (I must say that I don't know whether xdotool relies on XInput, XInput 2, XTest or something else, but for the sake of this example please assume the former) would observe the same behaviour as us.

If I understand correctly, an XInput 2 enabled Emacs must handle regular events as well because some of its frames might be in terminals supporting only Xinput 1. If that's the case, would it be possible to drop/reject corresponding regular events (e.g. MotionNotifiy) on terminals supporting XInput 2? If that's not possible, I’d say it’s better applying the patch (or similar) so that, even while unsupported, we do a best effort in reducing inconsistency.

> So EXWM should send XI_Motion events when the X server supports XInput 2
> (they are Generic Events, and XCB lets you send them, though not Xlib
> because nobody has written a working event to wire function yet.)

I'll implement your suggestion in EXWM shortly, in any case before Emacs 29 is released. How can I detect whether Emacs uses XInput 2 in a particular terminal?

> Or alternatively, why doesn't exwm just focus the window itself?

(I’m not sure whether I understand your question, please clarify if you think I missed it.) Just focusing the X window (and selecting the related Emacs window) is not enough for integrating `mouse-autoselect-window', precisely because `last_mouse_window' gets out-of-sync, leading to the user being unable to select back the last Emacs window by moving the mouse over it. A possible solution to this would be to expose `last_mouse_window' to Lisp (e.g. `mouse-autoselect-last-window'); presumably EXWM could then set its value as part of the above steps and have focus follow the pointer. I’d say this is my preferred solution, what do you think about this?