emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master bc092fc: For help commands, ensure all keys of a mo


From: Alan Mackenzie
Subject: [Emacs-diffs] master bc092fc: For help commands, ensure all keys of a mouse sequence are reported.
Date: Sat, 2 Dec 2017 05:10:15 -0500 (EST)

branch: master
commit bc092fcaea7268f2339f0e92720a37e62cdca5b2
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>

    For help commands, ensure all keys of a mouse sequence are reported.
    
    This solves the problem where read_key_sequence initializes and uses a 
global
    buffer raw_keybuf, yet is called recusrsively.  The initialization is now 
done
    elsewhere, avoiding the reinitialization of that global buffer.
    
    * src/keyboard.c (command_loop_1, read_key_sequence_vs): Initialize
    raw_event_count before calling read_key_sequence.
    (read_char_x_menu_prompt): Call x_popup_menu_1 in place of Fx_popup_menu.
    (init_raw_keybuf_count): New function.
    (read_key_sequence): Remove initialization of raw_event_count.  Add a 
missing
    GROW_RAW_KEYBUF invocation.
    
    * src/keyboard.h: (init_raw_keybuf_count): New declaration.
    
    * src/menu.c: (x_popup_menu_1): New function with the functionality of the
    former Fx_popup_menu.
    (Fx_popup_menu): Replace with function which initializes raw_event_count 
then
    calls x_popup_menu_1.
    
    * src/menu.h: (x_popup_menu_1): New declaration.
---
 src/keyboard.c | 76 ++++++++++++++++++++--------------------------
 src/keyboard.h |  1 +
 src/menu.c     | 96 +++++++++++++++++++++++++++++++---------------------------
 src/menu.h     |  1 +
 4 files changed, 85 insertions(+), 89 deletions(-)

diff --git a/src/keyboard.c b/src/keyboard.c
index b18dc1a..375aa4f 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -43,6 +43,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "systime.h"
 #include "atimer.h"
 #include "process.h"
+#include "menu.h"
 #include <errno.h>
 
 #ifdef HAVE_PTHREAD
@@ -121,17 +122,12 @@ ptrdiff_t this_command_key_count;
 
 /* This vector is used as a buffer to record the events that were actually read
    by read_key_sequence.  */
-static Lisp_Object raw_keybuf_buffer;
-static int raw_keybuf_count_buffer;
-static Lisp_Object *raw_keybuf = &raw_keybuf_buffer;
-static int *raw_keybuf_count = &raw_keybuf_count_buffer;
-
-#define GROW_RAW_KEYBUF(inc)                                            \
-  if (*raw_keybuf_count > ASIZE (*raw_keybuf) - (inc))                  \
-    *raw_keybuf =                                                       \
-      larger_vector (*raw_keybuf,                                       \
-                     (inc) + *raw_keybuf_count - ASIZE (*raw_keybuf),   \
-                     -1)
+static Lisp_Object raw_keybuf;
+static int raw_keybuf_count;
+
+#define GROW_RAW_KEYBUF                                                        
\
+ if (raw_keybuf_count == ASIZE (raw_keybuf))                           \
+   raw_keybuf = larger_vector (raw_keybuf, 1, -1)
 
 /* Number of elements of this_command_keys
    that precede this key sequence.  */
@@ -1370,8 +1366,7 @@ command_loop_1 (void)
       Vthis_command_keys_shift_translated = Qnil;
 
       /* Read next key sequence; i gets its length.  */
-      raw_keybuf_count = &raw_keybuf_count_buffer; /* For safety */
-      raw_keybuf = &raw_keybuf_buffer;             /* Ditto */
+      raw_keybuf_count = 0;
       i = read_key_sequence (keybuf, ARRAYELTS (keybuf),
                             Qnil, 0, 1, 1, 0);
 
@@ -8460,7 +8455,7 @@ read_char_x_menu_prompt (Lisp_Object map,
       /* Display the menu and get the selection.  */
       Lisp_Object value;
 
-      value = Fx_popup_menu (prev_event, get_keymap (map, 0, 1));
+      value = x_popup_menu_1 (prev_event, get_keymap (map, 0, 1));
       if (CONSP (value))
        {
          Lisp_Object tem;
@@ -8870,6 +8865,11 @@ test_undefined (Lisp_Object binding)
              && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
 }
 
+void init_raw_keybuf_count (void)
+{
+  raw_keybuf_count = 0;
+}
+
 /* Read a sequence of keys that ends with a non prefix character,
    storing it in KEYBUF, a buffer of size BUFSIZE.
    Prompt with PROMPT.
@@ -8920,11 +8920,6 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, 
Lisp_Object prompt,
   /* How many keys there are in the current key sequence.  */
   int t;
 
-  int *outer_raw_keybuf_count;
-  Lisp_Object *outer_raw_keybuf;
-  int inner_raw_keybuf_count_buffer;
-  Lisp_Object inner_raw_keybuf_buffer = Fmake_vector (make_number (30), Qnil);
-
   /* The length of the echo buffer when we started reading, and
      the length of this_command_keys when we started reading.  */
   ptrdiff_t echo_start UNINIT;
@@ -8985,7 +8980,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, 
Lisp_Object prompt,
   /* List of events for which a fake prefix key has been generated.  */
   Lisp_Object fake_prefixed_keys = Qnil;
 
-  *raw_keybuf_count = 0;
+  /* raw_keybuf_count is now initialized in (most of) the callers of
+     read_key_sequence.  This is so that in a recursive call (for
+     mouse menus) a spurious initialization doesn't erase the contents
+     of raw_keybuf created by the outer call.  */
+  /* raw_keybuf_count = 0; */
 
   last_nonmenu_event = Qnil;
 
@@ -9157,23 +9156,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, 
Lisp_Object prompt,
          {
            KBOARD *interrupted_kboard = current_kboard;
            struct frame *interrupted_frame = SELECTED_FRAME ();
-            int i;
-            outer_raw_keybuf_count = raw_keybuf_count;
-            outer_raw_keybuf = raw_keybuf;
-            inner_raw_keybuf_count_buffer = 0;
-            raw_keybuf_count = &inner_raw_keybuf_count_buffer;
-            raw_keybuf = &inner_raw_keybuf_buffer;
            /* Calling read_char with COMMANDFLAG = -2 avoids
               redisplay in read_char and its subroutines.  */
            key = read_char (prevent_redisplay ? -2 : NILP (prompt),
                             current_binding, last_nonmenu_event,
                              &used_mouse_menu, NULL);
-            raw_keybuf_count = outer_raw_keybuf_count;
-            raw_keybuf = outer_raw_keybuf;
-            GROW_RAW_KEYBUF (inner_raw_keybuf_count_buffer);
-            for (i = 0; i < inner_raw_keybuf_count_buffer; i++)
-              ASET (*raw_keybuf, (*raw_keybuf_count)++,
-                    AREF (inner_raw_keybuf_buffer, i));
            if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
                /* When switching to a new tty (with a new keyboard),
                   read_char returns the new buffer, rather than -2
@@ -9281,9 +9268,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, 
Lisp_Object prompt,
              && XINT (key) == quit_char
              && current_buffer != starting_buffer)
            {
-             GROW_RAW_KEYBUF (1);
-             ASET (*raw_keybuf, *raw_keybuf_count, key);
-             (*raw_keybuf_count)++;
+             GROW_RAW_KEYBUF;
+             ASET (raw_keybuf, raw_keybuf_count, key);
+             raw_keybuf_count++;
              keybuf[t++] = key;
              mock_input = t;
              Vquit_flag = Qnil;
@@ -9322,9 +9309,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, 
Lisp_Object prompt,
              current_binding = active_maps (first_event);
            }
 
-         GROW_RAW_KEYBUF (1);
-         ASET (*raw_keybuf, *raw_keybuf_count, key);
-         (*raw_keybuf_count)++;
+         GROW_RAW_KEYBUF;
+         ASET (raw_keybuf, raw_keybuf_count, key);
+         raw_keybuf_count++;
        }
 
       /* Clicks in non-text areas get prefixed by the symbol
@@ -9370,9 +9357,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, 
Lisp_Object prompt,
                      && BUFFERP (XWINDOW (window)->contents)
                      && XBUFFER (XWINDOW (window)->contents) != current_buffer)
                    {
-                     GROW_RAW_KEYBUF (1);
-                      ASET (*raw_keybuf, *raw_keybuf_count, key);
-                     (*raw_keybuf_count)++;
+                     GROW_RAW_KEYBUF;
+                     ASET (raw_keybuf, raw_keybuf_count, key);
+                     raw_keybuf_count++;
                      keybuf[t] = key;
                      mock_input = t + 1;
 
@@ -9865,6 +9852,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object 
continue_echo,
     cancel_hourglass ();
 #endif
 
+  raw_keybuf_count = 0;
   i = read_key_sequence (keybuf, ARRAYELTS (keybuf),
                         prompt, ! NILP (dont_downcase_last),
                         ! NILP (can_return_switch_frame), 0, 0);
@@ -10145,7 +10133,7 @@ shows the events before all translations (except for 
input methods).
 The value is always a vector.  */)
   (void)
 {
-  return Fvector (*raw_keybuf_count, XVECTOR (*raw_keybuf)->contents);
+  return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents);
 }
 
 DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
@@ -11290,8 +11278,8 @@ syms_of_keyboard (void)
   this_command_keys = Fmake_vector (make_number (40), Qnil);
   staticpro (&this_command_keys);
 
-  raw_keybuf_buffer = Fmake_vector (make_number (30), Qnil);
-  staticpro (raw_keybuf);
+  raw_keybuf = Fmake_vector (make_number (30), Qnil);
+  staticpro (&raw_keybuf);
 
   DEFSYM (Qcommand_execute, "command-execute");
   DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix");
diff --git a/src/keyboard.h b/src/keyboard.h
index 662d8e4..c232e77 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -438,6 +438,7 @@ extern unsigned int timers_run;
 extern bool menu_separator_name_p (const char *);
 extern bool parse_menu_item (Lisp_Object, int);
 
+extern void init_raw_keybuf_count (void);
 extern KBOARD *allocate_kboard (Lisp_Object);
 extern void delete_kboard (KBOARD *);
 extern void not_single_kboard_state (KBOARD *);
diff --git a/src/menu.c b/src/menu.c
index d569b4b..b40c2c0 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1112,51 +1112,8 @@ into menu items.  */)
   return Qnil;
 }
 
-
-DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
-       doc: /* Pop up a deck-of-cards menu and return user's selection.
-POSITION is a position specification.  This is either a mouse button event
-or a list ((XOFFSET YOFFSET) WINDOW)
-where XOFFSET and YOFFSET are positions in pixels from the top left
-corner of WINDOW.  (WINDOW may be a window or a frame object.)
-This controls the position of the top left of the menu as a whole.
-If POSITION is t, it means to use the current mouse position.
-
-MENU is a specifier for a menu.  For the simplest case, MENU is a keymap.
-The menu items come from key bindings that have a menu string as well as
-a definition; actually, the "definition" in such a key binding looks like
-\(STRING . REAL-DEFINITION).  To give the menu a title, put a string into
-the keymap as a top-level element.
-
-If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
-Otherwise, REAL-DEFINITION should be a valid key binding definition.
-
-You can also use a list of keymaps as MENU.
-  Then each keymap makes a separate pane.
-
-When MENU is a keymap or a list of keymaps, the return value is the
-list of events corresponding to the user's choice. Note that
-`x-popup-menu' does not actually execute the command bound to that
-sequence of events.
-
-Alternatively, you can specify a menu of multiple panes
-  with a list of the form (TITLE PANE1 PANE2...),
-where each pane is a list of form (TITLE ITEM1 ITEM2...).
-Each ITEM is normally a cons cell (STRING . VALUE);
-but a string can appear as an item--that makes a nonselectable line
-in the menu.
-With this form of menu, the return value is VALUE from the chosen item.
-
-If POSITION is nil, don't display the menu at all, just precalculate the
-cached information about equivalent key sequences.
-
-If the user gets rid of the menu without making a valid choice, for
-instance by clicking the mouse away from a valid choice or by typing
-keyboard input, then this normally results in a quit and
-`x-popup-menu' does not return.  But if POSITION is a mouse button
-event (indicating that the user invoked the menu with the mouse) then
-no quit occurs and `x-popup-menu' returns nil.  */)
-  (Lisp_Object position, Lisp_Object menu)
+Lisp_Object
+x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
 {
   Lisp_Object keymap, tem, tem2;
   int xpos = 0, ypos = 0;
@@ -1443,6 +1400,55 @@ no quit occurs and `x-popup-menu' returns nil.  */)
   return selection;
 }
 
+DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
+       doc: /* Pop up a deck-of-cards menu and return user's selection.
+POSITION is a position specification.  This is either a mouse button event
+or a list ((XOFFSET YOFFSET) WINDOW)
+where XOFFSET and YOFFSET are positions in pixels from the top left
+corner of WINDOW.  (WINDOW may be a window or a frame object.)
+This controls the position of the top left of the menu as a whole.
+If POSITION is t, it means to use the current mouse position.
+
+MENU is a specifier for a menu.  For the simplest case, MENU is a keymap.
+The menu items come from key bindings that have a menu string as well as
+a definition; actually, the "definition" in such a key binding looks like
+\(STRING . REAL-DEFINITION).  To give the menu a title, put a string into
+the keymap as a top-level element.
+
+If REAL-DEFINITION is nil, that puts a nonselectable string in the menu.
+Otherwise, REAL-DEFINITION should be a valid key binding definition.
+
+You can also use a list of keymaps as MENU.
+  Then each keymap makes a separate pane.
+
+When MENU is a keymap or a list of keymaps, the return value is the
+list of events corresponding to the user's choice. Note that
+`x-popup-menu' does not actually execute the command bound to that
+sequence of events.
+
+Alternatively, you can specify a menu of multiple panes
+  with a list of the form (TITLE PANE1 PANE2...),
+where each pane is a list of form (TITLE ITEM1 ITEM2...).
+Each ITEM is normally a cons cell (STRING . VALUE);
+but a string can appear as an item--that makes a nonselectable line
+in the menu.
+With this form of menu, the return value is VALUE from the chosen item.
+
+If POSITION is nil, don't display the menu at all, just precalculate the
+cached information about equivalent key sequences.
+
+If the user gets rid of the menu without making a valid choice, for
+instance by clicking the mouse away from a valid choice or by typing
+keyboard input, then this normally results in a quit and
+`x-popup-menu' does not return.  But if POSITION is a mouse button
+event (indicating that the user invoked the menu with the mouse) then
+no quit occurs and `x-popup-menu' returns nil.  */)
+  (Lisp_Object position, Lisp_Object menu)
+{
+  init_raw_keybuf_count ();
+  return x_popup_menu_1 (position, menu);
+}
+
 /* If F's terminal is not capable of displaying a popup dialog,
    emulate it with a menu.  */
 
diff --git a/src/menu.h b/src/menu.h
index 1469cc8..3335616 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -60,4 +60,5 @@ extern Lisp_Object ns_menu_show (struct frame *, int, int, 
int,
 extern Lisp_Object tty_menu_show (struct frame *, int, int, int,
                                  Lisp_Object, const char **);
 extern ptrdiff_t menu_item_width (const unsigned char *);
+extern Lisp_Object x_popup_menu_1 (Lisp_Object position, Lisp_Object menu);
 #endif /* MENU_H */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]