changeset 15290:da73440fdb5f

(Vwin32_mouse_move_interval): New lisp variable. (syms_of_win32fns): Add Vwin32_mouse_move_interval to syms. (saved_mouse_msg): Renamed to saved_mouse_button_msg. (timer_id): Renamed to mouse_button_timer. (saved_mouse_move_msg, mouse_move_timer): New variables. (win_msg_worker): Delete WM_TIMER code. (win32_wnd_proc): Handle WM_TIMER events here. Use separate timers for mouse down and mouse move (including scroll bar drag) events. Add new handling code for WM_VSCROLL and WM_MOUSEMOVE events. Only filter WM_MOUSEMOVE events when a button is held down. Always pass on message to DefWindowProc after calling TranslateMessage. Reset keyboard modifiers when losing focus. (win32_wnd_proc): When passing modifier keystrokes back to Windows, invoke TranslateMessage on them.
author Karl Heuer <kwzh@gnu.org>
date Sat, 25 May 1996 17:49:03 +0000
parents 6caf08bd290c
children 22f9530a700e
files src/w32fns.c
diffstat 1 files changed, 114 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32fns.c	Sat May 25 17:48:23 1996 +0000
+++ b/src/w32fns.c	Sat May 25 17:49:03 1996 +0000
@@ -64,6 +64,10 @@
    be converted to a middle button down event. */
 Lisp_Object Vwin32_mouse_button_tolerance;
 
+/* Minimum interval between mouse movement (and scroll bar drag)
+   events that are passed on to the event loop. */
+Lisp_Object Vwin32_mouse_move_interval;
+
 /* The name we're using in resource queries.  */
 Lisp_Object Vx_resource_name;
 
@@ -157,8 +161,13 @@
 #define RMOUSE 4
 
 static int button_state = 0;
-static Win32Msg saved_mouse_msg;
-static unsigned timer_id;	/* non-zero when timer is active */
+static Win32Msg saved_mouse_button_msg;
+static unsigned mouse_button_timer;	/* non-zero when timer is active */
+static Win32Msg saved_mouse_move_msg;
+static unsigned mouse_move_timer;
+
+#define MOUSE_BUTTON_ID	1
+#define MOUSE_MOVE_ID	2
 
 /* The below are defined in frame.c.  */
 extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
@@ -2841,14 +2850,6 @@
 	{
 	  switch (msg.message)
 	    {
-	    case WM_TIMER:
-	      if (saved_mouse_msg.msg.hwnd)
-		{
-		  post_msg (&saved_mouse_msg);
-		  saved_mouse_msg.msg.hwnd = 0;
-		}
-	      timer_id = 0;
-	      break;
 	    case WM_EMACS_CREATEWINDOW:
 	      win32_createwindow ((struct frame *) msg.wParam);
 	      PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
@@ -2888,7 +2889,8 @@
   LRESULT ret = 1;
   struct win32_display_info *dpyinfo = &one_win32_display_info;
   Win32Msg wmsg;
-  
+  int windows_translate;
+
   switch (msg) 
     {
     case WM_ERASEBKGND:
@@ -2930,25 +2932,26 @@
       record_keydown (wParam, lParam);
 
       wParam = map_keypad_keys (wParam, lParam);
-      
+
+      windows_translate = 0;
       switch (wParam) {
       case VK_LWIN:
       case VK_RWIN:
       case VK_APPS:
 	/* More support for these keys will likely be necessary.  */
 	if (!NILP (Vwin32_pass_optional_keys_to_system))
-	  goto dflt;
+	  windows_translate = 1;
 	break;
       case VK_MENU:
 	if (NILP (Vwin32_pass_alt_to_system)) 
 	  return 0;
-	else 
-	  goto dflt;
+	windows_translate = 1;
+	break;
       case VK_CONTROL: 
       case VK_CAPITAL: 
       case VK_SHIFT:
-	/* Pass on to Windows.  */
-	goto dflt;
+	windows_translate = 1;
+	break;
       default:
 	/* If not defined as a function key, change it to a WM_CHAR message. */
 	if (lispy_function_keys[wParam] == 0)
@@ -2956,6 +2959,15 @@
 	break;
       }
 
+      if (windows_translate)
+	{
+	  MSG winmsg = { hwnd, msg, wParam, lParam, 0, {0,0} };
+
+	  winmsg.time = GetMessageTime ();
+	  TranslateMessage (&winmsg);
+	  goto dflt;
+	}
+
       /* Fall through */
       
     case WM_SYSCHAR:
@@ -3003,10 +3015,10 @@
 
 	if (button_state & other)
 	  {
-	    if (timer_id)
+	    if (mouse_button_timer)
 	      {
-		KillTimer (NULL, timer_id);
-		timer_id = 0;
+		KillTimer (hwnd, mouse_button_timer);
+		mouse_button_timer = 0;
 
 		/* Generate middle mouse event instead. */
 		msg = WM_MBUTTONDOWN;
@@ -3023,25 +3035,25 @@
 	    else
 	      {
 		/* Flush out saved message. */
-		post_msg (&saved_mouse_msg);
+		post_msg (&saved_mouse_button_msg);
 	      }
 	    wmsg.dwModifiers = win32_get_modifiers ();
 	    my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
 
 	    /* Clear message buffer. */
-	    saved_mouse_msg.msg.hwnd = 0;
+	    saved_mouse_button_msg.msg.hwnd = 0;
 	  }
 	else
 	  {
 	    /* Hold onto message for now. */
-	    timer_id =
-	      SetTimer (NULL, 0, XINT (Vwin32_mouse_button_tolerance), NULL);
-	    saved_mouse_msg.msg.hwnd = hwnd;
-	    saved_mouse_msg.msg.message = msg;
-	    saved_mouse_msg.msg.wParam = wParam;
-	    saved_mouse_msg.msg.lParam = lParam;
-	    saved_mouse_msg.msg.time = GetMessageTime ();
-	    saved_mouse_msg.dwModifiers = win32_get_modifiers ();
+	    mouse_button_timer =
+	      SetTimer (hwnd, MOUSE_BUTTON_ID, XINT (Vwin32_mouse_button_tolerance), NULL);
+	    saved_mouse_button_msg.msg.hwnd = hwnd;
+	    saved_mouse_button_msg.msg.message = msg;
+	    saved_mouse_button_msg.msg.wParam = wParam;
+	    saved_mouse_button_msg.msg.lParam = lParam;
+	    saved_mouse_button_msg.msg.time = GetMessageTime ();
+	    saved_mouse_button_msg.dwModifiers = win32_get_modifiers ();
 	  }
       }
       return 0;
@@ -3076,18 +3088,18 @@
 	else
 	  {
 	    /* Flush out saved message if necessary. */
-	    if (saved_mouse_msg.msg.hwnd)
+	    if (saved_mouse_button_msg.msg.hwnd)
 	      {
-		post_msg (&saved_mouse_msg);
+		post_msg (&saved_mouse_button_msg);
 	      }
 	  }
 	wmsg.dwModifiers = win32_get_modifiers ();
 	my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
 
 	/* Always clear message buffer and cancel timer. */
-	saved_mouse_msg.msg.hwnd = 0;
-	KillTimer (NULL, timer_id);
-	timer_id = 0;
+	saved_mouse_button_msg.msg.hwnd = 0;
+	KillTimer (hwnd, mouse_button_timer);
+	mouse_button_timer = 0;
 
 	if (button_state == 0)
 	  ReleaseCapture ();
@@ -3111,33 +3123,73 @@
       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
       return 0;
 
-#if 0
+    case WM_VSCROLL:
     case WM_MOUSEMOVE:
-      /* Flush out saved message if necessary. */
-      if (saved_mouse_msg.msg.hwnd)
+      if (XINT (Vwin32_mouse_move_interval) <= 0
+	  || (msg == WM_MOUSEMOVE && button_state == 0))
+  	{
+	  wmsg.dwModifiers = win32_get_modifiers ();
+	  my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+	  return 0;
+  	}
+  
+      /* Hang onto mouse move and scroll messages for a bit, to avoid
+	 sending such events to Emacs faster than it can process them.
+	 If we get more events before the timer from the first message
+	 expires, we just replace the first message. */
+
+      if (saved_mouse_move_msg.msg.hwnd == 0)
+	mouse_move_timer =
+	  SetTimer (hwnd, MOUSE_MOVE_ID, XINT (Vwin32_mouse_move_interval), NULL);
+
+      /* Hold onto message for now. */
+      saved_mouse_move_msg.msg.hwnd = hwnd;
+      saved_mouse_move_msg.msg.message = msg;
+      saved_mouse_move_msg.msg.wParam = wParam;
+      saved_mouse_move_msg.msg.lParam = lParam;
+      saved_mouse_move_msg.msg.time = GetMessageTime ();
+      saved_mouse_move_msg.dwModifiers = win32_get_modifiers ();
+  
+      return 0;
+
+    case WM_TIMER:
+      /* Flush out saved messages if necessary. */
+      if (wParam == mouse_button_timer)
 	{
-	  wmsg = saved_mouse_msg;
-	  my_post_msg (&wmsg, wmsg.msg.hwnd, wmsg.msg.message,
-		       wmsg.msg.wParam, wmsg.msg.lParam);
+	  if (saved_mouse_button_msg.msg.hwnd)
+	    {
+	      post_msg (&saved_mouse_button_msg);
+	      saved_mouse_button_msg.msg.hwnd = 0;
+	    }
+	  KillTimer (hwnd, mouse_button_timer);
+	  mouse_button_timer = 0;
 	}
-      wmsg.dwModifiers = win32_get_modifiers ();
-      my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
-
-      /* Always clear message buffer and cancel timer. */
-      saved_mouse_msg.msg.hwnd = 0;
-      KillTimer (NULL, timer_id);
-      timer_id = 0;
-
+      else if (wParam == mouse_move_timer)
+	{
+	  if (saved_mouse_move_msg.msg.hwnd)
+	    {
+	      post_msg (&saved_mouse_move_msg);
+	      saved_mouse_move_msg.msg.hwnd = 0;
+	    }
+	  KillTimer (hwnd, mouse_move_timer);
+	  mouse_move_timer = 0;
+	}
       return 0;
-#endif
-
+  
+    case WM_NCACTIVATE:
+      /* Windows doesn't send us focus messages when putting up and
+	 taking down a system popup dialog as for Ctrl-Alt-Del on Win95.
+	 The only indication we get that something happened is receiving
+	 this message afterwards.  So this is a good time to reset our
+	 keyboard modifiers' state. */
+      reset_modifiers ();
+      goto dflt;
+
+    case WM_KILLFOCUS:
     case WM_SETFOCUS:
       reset_modifiers ();
-    case WM_MOUSEMOVE:
     case WM_MOVE:
     case WM_SIZE:
-    case WM_KILLFOCUS:
-    case WM_VSCROLL:
     case WM_SYSCOMMAND:
     case WM_COMMAND:
       wmsg.dwModifiers = win32_get_modifiers ();
@@ -4927,6 +4979,14 @@
 button down event is generated instead.");
   XSETINT (Vwin32_mouse_button_tolerance, GetDoubleClickTime () / 2);
 
+  DEFVAR_INT ("win32-mouse-move-interval",
+	      &Vwin32_mouse_move_interval,
+	      "Minimum interval between mouse move events.\n\
+The value is the minimum time in milliseconds that must elapse between\n\
+successive mouse move (or scroll bar drag) events before they are\n\
+reported as lisp events.");
+  XSETINT (Vwin32_mouse_move_interval, 50);
+
   init_x_parm_symbols ();
 
   DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,