Subject: bug#76620: 30.1.50; mouse-1 mode-line bindings are unusable when point is on a button

From: Spencer Baugh <[email-masked]>
Date: Thu, 28 Aug 2025 14:22:32 -0400

Eli Zaretskii <[email-masked]> writes:

>> Cc: Jonas Bernoulli <[email-masked]>
>> Date: Thu, 27 Feb 2025 18:11:36 -0500
>> From:  Spencer Baugh via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <[email-masked]>
>> 
>> 
>> 1. emacs -Q
>> 2. Position point over a button.el button, e.g.
>>    (progn (view-emacs-news) (forward-button 1))
>> 3. mouse-2 anywhere on the mode line.
>> 4. Note that instead of the usual mouse-delete-other-windows binding,
>>    the button at point is activated.
>> 
>> This is because the local keymap for buttons is button-map, which binds
>> "<mode-line> <mouse-2>".  This is confusing, and probably a bug, but not
>> too bad of a bug.
>> 
>> Substantially worse is this:
>> 
>> 5. mouse-1 on a part of the mode-line with a mouse-1 binding; for
>>    example, mouse-1 on the buffer coding system indicator "U" at the
>>    start of the mode line.
>> 
>> 6. Instead of describing the buffer's coding system, the button at point
>>    is activated.
>> 
>> This is because mouse-1-click-follows-link translates the mouse-1 into a
>> mouse-2.  This makes all mouse-1 bindings on the mode line basically
>> broken while point is on a button.
>
> The bugs with mouse-1 are solved on the master branch (see bug#75219).
> So I can reproduce the last two items in Emacs 30, but not in Emacs
> 31.  The problems with mouse-2 are still present on the master branch.

The attached patch should fix the remaining bug, without dropping
support for button.el in the mode-line or header-line.

>From 1ebb6e8822b5fc635549be14a3d4f2dd6f2d77a4 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <[email-masked]>
Date: Thu, 28 Aug 2025 14:13:24 -0400
Subject: [PATCH] Always ignore keymaps at point when clicking mode and header
 line

In c41ea047a43, we started ignoring the keymap at point when a
position is a click on the mode line or header line.  However,
we only did this when POSN_STRING was non-nil, which isn't
always the case for clicks on the mode line and header line.
Move the check for mode line or header line outside the check
for non-nil POSN_STRING so it takes effect in that case.

* src/keymap.c (Fcurrent_active_maps): Ignore keymaps at point
for all clicks on mode and header line.  (bug#76620)
---
 src/keymap.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/keymap.c b/src/keymap.c
index 2c250578b00..263bf336a71 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1735,6 +1735,16 @@ DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps,
 		}
 	    }
 
+	  Lisp_Object pos_area = POSN_POSN (position);
+	  if (EQ (pos_area, Qmode_line) || EQ (pos_area, Qheader_line))
+	    {
+	      /* For clicks on mode line or header line, ignore the maps
+		 we found at POSITION, because properties at point are
+		 not relevant in that case.  */
+	      local_map = Qnil;
+	      keymap = Qnil;
+	    }
+
 	  /* If on a mode line string with a local keymap,
 	     or for a click on a string, i.e. overlay string or a
 	     string displayed via the `display' property,
@@ -1751,20 +1761,10 @@ DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps,
 		{
 		  Lisp_Object map = Fget_text_property (pos, Qlocal_map,
 							string);
-		  Lisp_Object pos_area = POSN_POSN (position);
-		  /* For clicks on mode line or header line, override
-		     the maps we found at POSITION unconditionally, even
-		     if the corresponding properties of the mode- or
-		     header-line string are nil, because propertries at
-		     point are not relevant in that case.  */
-		  if (!NILP (map)
-		      || EQ (pos_area, Qmode_line)
-		      || EQ (pos_area, Qheader_line))
+		  if (!NILP (map))
 		    local_map = map;
 		  map = Fget_text_property (pos, Qkeymap, string);
-		  if (!NILP (map)
-		      || EQ (pos_area, Qmode_line)
-		      || EQ (pos_area, Qheader_line))
+		  if (!NILP (map))
 		    keymap = map;
 		}
 	    }
-- 
2.43.7