Subject: Re: bug#69915: 30.0.50; mouse-autoselect-window has no effect in terminal

From: Jared Finder <[email-masked]>
Date: Mon, 25 Mar 2024 14:53:15 -0700

On 2024-03-24 12:27, Olaf Rogalsky wrote:
> Hi Jared,
> 
> thanks for your feedback (answering this from my gmail account and
> hope this doesn't mess up the debbugs history).
> 
>> Are you certain you need the change to window.el as well? I'd be very
>> surprised if it is necessary to change
> ...
>> Is your setup is different somehow?
> No, but I forgot to mention, that the "nil <select-window> is 
> undefined" error
> only occurred, iff mouse-autoselect-window had a numeric value.
> With my new patch, the error disappeared. I don't know why, but a
> change to window.el
> isn't necessary anymore. I still think, that the proposed change would
> be correct.

I'll defer to Eli here, but my general sentiment would be to leave 
window.el untouched unless a change is needed.  The event list returned 
was last changed in 2006 so it's reasonably stable.

>> <select-window> events shouldn't be generated while the mouse is being
>> dragged. This probably is reflected in fully by track-mouse, but I'd
>> suggest looking at the native code that generates the event to 
>> confirm.
> Truly understanding xterm.c unfortunately is beyond my expertise. 
> Nevertheless I
> tested, the behavior. Dragging the mouse from one window to the next
> (while passing over
> the modeline) gives the following sequence of events:
> 
>  ESC [ < 3 5 ; 5 5 ; 4 1 M ESC [ < 0 ; 5 5 ; 4 1 M ;; mouse-drag-region
>  ESC [ < 3 2 ; 5 5 ; 4 2 M             ;; anonymous-command
>  ESC [ < 3 2 ; 5 5 ; 4 3 M             ;; anonymous-command
>  <help-echo> ESC [ < 3 2 ; 5 5 ; 4 4 M ;; ignore
>  ESC [ < 3 2 ; 5 6 ; 4 4 M             ;; anonymous-command
>  ESC [ < 0 ; 5 6 ; 4 4 m               ;; anonymous-command
>  <drag-mouse-1>                        ;; mouse-set-region
> 
> So indeed, no select-window event is generated. As a result, dragging
> the mouse over the
> borders of the window results in a scrolling of the window. This
> matches the behavior of the
> X11 backend.

Thank you.  There's one remaining difference to handle that I highlight 
in the diff below.

>> If there is a case where two events should be generated (not sure if
>> this case exists depending on above), we'd want to return both, but 
>> you
>> can only return a single key sequence from the translate function. I
>> think this case deserves a FIXME note.
> Can't follow you here. At which occasion two events might be generated
> and which ones?

I was thinking that if both a mouse movement and select window event 
should both be returned, like if track-mouse is non-nil and you switch 
windows.  Can you test this case?

>> Did you try out switching frames? I'm not certain if <select-window> 
>> is
>> supposed to be generated when the frame is switched.
> Switching frames is not handled in xt-mouse.el. However, if you change
> the focus from another
> X11 window to the title bar of the terminal or wise-versa, no
> switch-frame event is generated. Instead,
> xterm-translate-focus-in/xterm-translate-focus-out are called via a
> binding in xterm-rxvt-function-map.
> These functions toggle the terminal parameter tty-focus-state between
> focused and defocused and then
> call after-focus-change-function, which also does not generate a
> switch-frame event.
> As far as I could find out, the X11 backend of emacs doesn't generate
> switch-frame events, either.

I was actually referring to using C-x 5 2 and C-x 5 o within a single 
terminal.  I tested this locally and it works fine.

> New patch:
> ... other parts of patch look good to me :) ...
> @@ -84,10 +89,19 @@ xterm-mouse-translate-1
>         vec)
>         (is-move
>          (xterm-mouse--handle-mouse-movement)
> -        (if track-mouse vec
> -          ;; Mouse movement events are currently supposed to be
> -          ;; suppressed.  Return no event.
> -          []))
> +       (if (and mouse-autoselect-window ; after mouse movement

Style nit: Can you please do this as a cond instead of a nested (if x y 
(if z u v))?

> autoselect the mouse window, but ...
> +                (windowp ev-window) ; ignore modeline, tab-bar,
> menu-bar and so forth ...
> +                ;;(not (posn-area (event-start event))) ; also
> ignore, if not inside of text area of window ...
> +                (not (eq ev-window last-window)) ; but only, if mouse
> is over new window ...
> +                (not (eq ev-window (selected-window)))) ; which is
> different from the selected window

Looking at xterm.c, I think you also want a test against 
window-minibuffer-p.

> +           (progn
> +             (put 'select-window 'event-kind 'switch-frame)
> +             (setf (car event) 'select-window)
> +             vec)

I think this should be an event that's just select-window and the 
window, to line up with what the select-window event looks like on other 
platforms (I tested PGTK and Windows terminal).  You can verify this by 
running M-x trace-function RET handle-select-window RET.

That would instead be something like:

(progn
   (put 'select-window 'event-kind 'switch-frame)
   (vector `(select-window (,ev-window)))

Thank you so much for making this patch!

   -- MJF