Subject: bug#50067: Context menus

From: Juri Linkov <[email-masked]>
Date: Thu, 25 Nov 2021 21:28:47 +0200

>> @@ -367,7 +367,7 @@ DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
>>       event with parameters.  */
>>    ptrdiff_t next_event;
>>    for (next_event = 0; next_event < key_count; next_event++)
>> -    if (EVENT_HAS_PARAMETERS (AREF (keys, next_event)))
>> +    if (inhibit_mouse_event_check || EVENT_HAS_PARAMETERS (AREF (keys, next_event)))
>>        break;
>>  
>>    /* Handle special starting chars `*' and `@'.  Also `-'.  */
>> @@ -618,6 +618,7 @@ DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
>>  	  do
>>  	    next_event++;
>>  	  while (next_event < key_count
>> +		 && ! inhibit_mouse_event_check
>>  		 && ! EVENT_HAS_PARAMETERS (AREF (keys, next_event)));
>>  
>>  	  break;
>
> Why check this condition inside the loops, rather than avoid entering
> the loops when the condition is right, in the first place?

I thought that checking the condition inside the loops
would be less risky for the emacs-28 release branch.

> And please add comments there explaining the meaning of the
> inhibit_mouse_event_check test.

This patch also adds comments, and removes one condition
that is not unnecessary when event with parameters
is not searched when inhibit_mouse_event_check is non-nil:

diff --git a/src/callint.c b/src/callint.c
index 44dae361c1..68f103759a 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -364,11 +364,14 @@ DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
 
   /* The index of the next element of this_command_keys to examine for
      the 'e' interactive code.  Initialize it to point to the first
-     event with parameters.  */
-  ptrdiff_t next_event;
-  for (next_event = 0; next_event < key_count; next_event++)
-    if (EVENT_HAS_PARAMETERS (AREF (keys, next_event)))
-      break;
+     event with parameters.  When `inhibit_mouse_event_check' is non-nil,
+     the command can accept an event without parameters,
+     so don't search for the event with parameters in this case.  */
+  ptrdiff_t next_event = 0;
+  if (!inhibit_mouse_event_check)
+    for (; next_event < key_count; next_event++)
+      if (EVENT_HAS_PARAMETERS (AREF (keys, next_event)))
+	break;
 
   /* Handle special starting chars `*' and `@'.  Also `-'.  */
   /* Note that `+' is reserved for user extensions.  */
@@ -606,7 +609,7 @@ DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
 	  break;
 
 	case 'e':		/* The invoking event.  */
-	  if (!inhibit_mouse_event_check && next_event >= key_count)
+	  if (next_event >= key_count)
 	    error ("%s must be bound to an event with parameters",
 		   (SYMBOLP (function)
 		    ? SSDATA (SYMBOL_NAME (function))
@@ -614,11 +617,15 @@ DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
 	  args[i] = AREF (keys, next_event);
 	  varies[i] = -1;
 
-	  /* Find the next parameterized event.  */
-	  do
+	  /* `inhibit_mouse_event_check' allows non-parameterized events.  */
+	  if (inhibit_mouse_event_check)
 	    next_event++;
-	  while (next_event < key_count
-		 && ! EVENT_HAS_PARAMETERS (AREF (keys, next_event)));
+	  else
+	    /* Find the next parameterized event.  */
+	    do
+	      next_event++;
+	    while (next_event < key_count
+		   && ! EVENT_HAS_PARAMETERS (AREF (keys, next_event)));
 
 	  break;