Subject: Re: bug#19547: Patch for this bug

From: Thierry Volpiatto <[email-masked]>
Date: Sun, 27 Nov 2016 07:52:28 +0100

Eli Zaretskii <[email-masked]> writes:

> You can do that with a 'switch' in C, or, better, with a C array that
> holds the symbols and their corresponding C event_kind values, like
> this:
>
>  struct event_value {
>    Lisp_Object event_symbol;
>    enum event_kind event_kind;
>  };
>  static struct event_value symbol_to_kind[] = {
>    { Qfocus_in, FOCUS_IN_EVENT },
>    { Qhelp, HELP_EVENT },
>    { Qiconify, ICONIFY_EVENT },
>    ...
>  };
>
> Then, for each symbol, you can find the corresponding event value by
> walking the array until you find a match.

I finally wrote a patch for keyboard.c which is compiling without error,
I used switch because I still not understanding how to use the code
above (seems that is approach is too advanced for my skills compared to
the usage of switch).
The patch seems to work fine with helm, though i didn't test with our
bug (https://github.com/emacs-helm/helm/issues/1157), but I now don't
know where to initialize our variable (while-no-input-ignore-events), I
just setq it in scratch buffer after starting helm with a minimal
installation (script emacs-helm.sh).

Here the patch (please look at it carefully this is the first C code I write):

diff --git a/src/keyboard.c b/src/keyboard.c
index 65938a5..3caf506 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3567,14 +3567,22 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
 #endif	/* subprocesses */
     }
 
+  Lisp_Object ignore_event;
+
+  switch (event->kind)
+    {
+    case FOCUS_IN_EVENT: ignore_event = Qfocus_in;
+    case FOCUS_OUT_EVENT: ignore_event = Qfocus_out;
+    case HELP_EVENT: ignore_event = Qhelp;
+    case ICONIFY_EVENT: ignore_event = Qiconify;
+    case DEICONIFY_EVENT: ignore_event = Qdeiconify;
+    case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request;
+    }
+
   /* If we're inside while-no-input, and this event qualifies
      as input, set quit-flag to cause an interrupt.  */
   if (!NILP (Vthrow_on_input)
-      && event->kind != FOCUS_IN_EVENT
-      && event->kind != FOCUS_OUT_EVENT
-      && event->kind != HELP_EVENT
-      && event->kind != ICONIFY_EVENT
-      && event->kind != DEICONIFY_EVENT)
+      && !NILP (Fmemq (ignore_event, Vwhile_no_input_ignore_events)))
     {
       Vquit_flag = Vthrow_on_input;
       /* If we're inside a function that wants immediate quits,
@@ -11164,6 +11172,10 @@ syms_of_keyboard (void)
   DEFSYM (Qiconify_frame, "iconify-frame");
   DEFSYM (Qmake_frame_visible, "make-frame-visible");
   DEFSYM (Qselect_window, "select-window");
+  DEFSYM (Qhelp, "help");
+  DEFSYM (Qiconify, "iconify");
+  DEFSYM (Qdeiconify, "deiconify");
+  DEFSYM (Qselection_request, "selection-request");
   {
     int i;
 
@@ -11822,6 +11834,12 @@ signals.  */);
 
   /* Create the initial keyboard.  Qt means 'unset'.  */
   initial_kboard = allocate_kboard (Qt);
+
+  DEFVAR_LISP ("while-no-input-ignore-events",
+               Vwhile_no_input_ignore_events,
+               doc: /* Ignored events from while-no-input.  */);
+  Vwhile_no_input_ignore_events = Qnil;
+    /* = listn (Qfocus_in, Qfocus_out, Qhelp, Qiconify, Qdeiconify, Qselection_request); */
 }
 
 void

Thanks.

-- 
Thierry