GNU bug report logs - #75219
31.0.50; mouse-2 mode-line binding overridden by mouse-1-click-follows-link

Previous Next

Package: emacs;

Reported by: Visuwesh <visuweshm <at> gmail.com>

Date: Tue, 31 Dec 2024 05:40:02 UTC

Severity: normal

Found in version 31.0.50

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Visuwesh <visuweshm <at> gmail.com>, Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 75219 <at> debbugs.gnu.org
Subject: Re: bug#75219: 31.0.50;
 mouse-2 mode-line binding overridden by mouse-1-click-follows-link
Date: Sun, 05 Jan 2025 17:17:45 +0200
> From: Visuwesh <visuweshm <at> gmail.com>
> Date: Tue, 31 Dec 2024 11:07:05 +0530
> 
> When the point is over a character with a keymap that has `follow-link',
> mode-line mouse-1 binding is translated to mode-line mouse-2 binding.
> 
> To reproduce,
> 
>     1. emacs -Q
>     2. M-: (define-key mode-line-buffer-identification-keymap [mode-line mouse-2] #'mouse-buffer-menu) RET
>     3. M-s M-w something RET
>     4. Move the point over to any link
>     5. Click the buffer name in the mode-line with mouse-1
>     6. Observe how mouse-buffer-menu is executed instead of changing the
>        buffer

This happens because key-binding considers the local keymap at point
even if its POSITION argument specifies a mouse click in a completely
different location (in this case: on the mode line).  For example, try

  M-: (key-binding [follow-link] nil t (list (selected-window) 'mode-line '(82 . 549) 10000)) RET

Evaluate this in EWW buffer, once with point on a link and another
time with point on a regular character.  In the second case this will
return nil, but in the first case it will return 'mouse-face', an
indication that the click should follow a link.  The result of this
is that mouse-on-link-p returns non-nil, and
mouse--click-1-maybe-follows-link decides we need to follow the link.

The reason why key-binding considers the local keymap at point is this
part of current-active-maps (which key-binding calls):

      ptrdiff_t pt = click_position (position);  <<<<<<<<<<<<<<<<<<<<<
      /* This usually returns the buffer's local map,
	 but that can be overridden by a `local-map' property.  */
      Lisp_Object local_map = get_local_map (pt, current_buffer, Qlocal_map);
      /* This returns nil unless there is a `keymap' property.  */
      Lisp_Object keymap = get_local_map (pt, current_buffer, Qkeymap);
      Lisp_Object otlp = KVAR (current_kboard, Voverriding_terminal_local_map);

and click_position does this:

  static ptrdiff_t
  click_position (Lisp_Object position)
  {
    EMACS_INT pos = (FIXNUMP (position) ? XFIXNUM (position)
		     : MARKERP (position) ? marker_position (position)
		     : PT);
    if (! (BEGV <= pos && pos <= ZV))
      args_out_of_range (Fcurrent_buffer (), position);
    return pos;
  }

So if POSITION is a mouse click event, click_position will always
return the position of point.

It is easy to prevent this strange result from click_position by
ignoring local map at POSITION which is a list, but I don't know how
much code out there relies on this "fallback" to point.

Stefan, any ideas or suggestions?




This bug report was last modified 186 days ago.

Previous Next


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