emacs-devel
[Top][All Lists]
Advanced

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

Re: storing mouse-movement events in recent-keys and keyboard macros


From: Kim F. Storm
Subject: Re: storing mouse-movement events in recent-keys and keyboard macros
Date: 23 Dec 2001 02:59:49 +0100
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.1

Richard Stallman <address@hidden> writes:

>     I'm working on a small patch which will store only the first and the
>     last in a series of mouse movements (in the same window) in the
>     list, i.e. it would tell you where the move started, where it ended,
>     but not how it got there :-)
> 
> That seems like a good change.  Also, maybe arrange to notice
> when help-echo events are separated only by mouse-movement events
> and discard the excess help-echo event anyway.

Yes, it should do that too.  Below is a patch which does this.
I'll install it if you think it is ok.


Index: keyboard.c
===================================================================
RCS file: /cvs/emacs/src/keyboard.c,v
retrieving revision 1.644
diff -u -r1.644 keyboard.c
--- keyboard.c  18 Dec 2001 06:25:27 -0000      1.644
+++ keyboard.c  23 Dec 2001 01:49:26 -0000
@@ -2982,43 +2982,101 @@
 record_char (c)
      Lisp_Object c;
 {
-  /* Don't record `help-echo' in recent_keys unless it shows some help
-     message, and a different help than the previoiusly recorded
-     event.  */
-  if (CONSP (c) && EQ (XCAR (c), Qhelp_echo))
+  int recorded = 0;
+
+  if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), 
Qmouse_movement)))
     {
-      Lisp_Object help;
+      /* To avoid filling recent_keys with help-echo and mouse-movement
+        events, we filter out repeated help-echo events, only store the
+        first and last in a series of mouse-movement events, and don't
+        store repeated help-echo events which are only separated by
+        mouse-movement events.  */
 
-      help = Fcar (Fcdr (XCDR (c)));
-      if (STRINGP (help))
+      Lisp_Object ev1, ev2, ev3;
+      int ix1, ix2, ix3;
+      
+      if ((ix1 = recent_keys_index - 1) < 0)
+       ix1 = NUM_RECENT_KEYS - 1;
+      ev1 = AREF (recent_keys, ix1);
+      
+      if ((ix2 = ix1 - 1) < 0)
+       ix2 = NUM_RECENT_KEYS - 1;
+      ev2 = AREF (recent_keys, ix2);
+      
+      if ((ix3 = ix2 - 1) < 0)
+       ix3 = NUM_RECENT_KEYS - 1;
+      ev3 = AREF (recent_keys, ix3);
+     
+      if (EQ (XCAR (c), Qhelp_echo))
+       {
+         /* Don't record `help-echo' in recent_keys unless it shows some help
+            message, and a different help than the previoiusly recorded
+            event.  */
+         Lisp_Object help, last_help;
+
+         help = Fcar (Fcdr (XCDR (c)));
+         if (!STRINGP (help))
+           recorded = 1;
+         else if (CONSP (ev1) && EQ (XCAR (ev1), Qhelp_echo)
+                  && (last_help = Fcar (Fcdr (XCDR (ev1))), EQ (last_help, 
help)))
+           recorded = 1;
+         else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
+                  && CONSP (ev2) && EQ (XCAR (ev2), Qhelp_echo)
+                  && (last_help = Fcar (Fcdr (XCDR (ev2))), EQ (last_help, 
help)))
+           recorded = -1;
+         else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
+                  && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
+                  && CONSP (ev3) && EQ (XCAR (ev3), Qhelp_echo)
+                  && (last_help = Fcar (Fcdr (XCDR (ev3))), EQ (last_help, 
help)))
+           recorded = -2;
+       }
+      else if (EQ (XCAR (c), Qmouse_movement))
        {
-         int last_idx;
-         Lisp_Object last_c, last_help;
-         
-         last_idx = recent_keys_index - 1;
-         if (last_idx < 0)
-           last_idx = NUM_RECENT_KEYS - 1;
-         last_c = AREF (recent_keys, last_idx);
-         
-         if (!CONSP (last_c)
-             || !EQ (XCAR (last_c), Qhelp_echo)
-             || (last_help = Fcar (Fcdr (XCDR (last_c))),
-                 !EQ (last_help, help)))
+         /* Only record one pair of `mouse-movement' on a window in 
recent_keys.
+            So additional mouse movement events replace the last element.  */
+         Lisp_Object last_window, window;
+
+         window = Fcar (Fcar (XCDR (c)));
+         if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
+             && (last_window = Fcar (Fcar (XCDR (ev1))), EQ (last_window, 
window))
+             && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
+             && (last_window = Fcar (Fcar (XCDR (ev2))), EQ (last_window, 
window)))
            {
-             total_keys++;
-             ASET (recent_keys, recent_keys_index, c);
-             if (++recent_keys_index >= NUM_RECENT_KEYS)
-               recent_keys_index = 0;
+             ASET (recent_keys, ix1, c);
+             recorded = 1;
            }
        }
     }
   else
+    store_kbd_macro_char (c);
+
+  if (!recorded)
     {
       total_keys++;
       ASET (recent_keys, recent_keys_index, c);
       if (++recent_keys_index >= NUM_RECENT_KEYS)
        recent_keys_index = 0;
     }
+  else if (recorded < 0)
+    {
+      /* We need to remove one or two events from recent_keys.
+         To do this, we simply put nil at those events and move the
+        recent_keys_index backwards over those events.  Usually,
+        users will never see those nil events, as they will be
+        overwritten by the command keys entered to see recent_keys
+        (e.g. C-h l).  */
+
+      while (recorded++ < 0 && total_keys > 0)
+       {
+         if (total_keys < NUM_RECENT_KEYS)
+           total_keys--;
+         if (--recent_keys_index < 0)
+           recent_keys_index = NUM_RECENT_KEYS - 1;
+         ASET (recent_keys, recent_keys_index, Qnil);
+       }
+    }
+
+  num_nonmacro_input_events++;
       
   /* Write c to the dribble file.  If c is a lispy event, write
      the event's symbol to the dribble file, in <brackets>.  Bleaugh.
@@ -3051,11 +3109,6 @@
 
       fflush (dribble);
     }
-
-  if (!CONSP (c) || !EQ (Qhelp_echo, XCAR (c)))
-    store_kbd_macro_char (c);
-
-  num_nonmacro_input_events++;
 }
 
 Lisp_Object




reply via email to

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