--- xc/programs/Xserver/hw/xwin/win.h.orig	Wed Nov 21 08:51:24 2001
+++ xc/programs/Xserver/hw/xwin/win.h	Thu Jun  6 09:40:05 2002
@@ -740,7 +740,7 @@
 winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam);
 
 void
-winKeybdReleaseModifierKeys ();
+winKeybdReleaseKeys ();
 
 void
 winSendKeyEvent (DWORD dwKey, Bool fDown);
--- xc/programs/Xserver/hw/xwin/winkeybd.c.orig	Mon Nov 12 08:47:53 2001
+++ xc/programs/Xserver/hw/xwin/winkeybd.c	Thu Jun  6 20:57:03 2002
@@ -73,6 +73,14 @@
   int			i;
   KeySym		*pKeySym = map;
 
+  /* Set the key state tracking buffer to show all keys as up.  This might
+   * no be strictly true - but it's a good enough guess
+   */
+  for(i=0;i<NUM_KEYCODES;i++) 
+    {
+      winKeyState[i]=FALSE;
+    }
+
   /* MAP_LENGTH is defined in Xserver/include/input.h to be 256 */
   for (i = 0; i < MAP_LENGTH; i++)
     pModMap[i] = NoSymbol;  /* make sure it is restored */
@@ -397,18 +405,18 @@
  */
 
 void
-winKeybdReleaseModifierKeys ()
+winKeybdReleaseKeys ()
 {
+  int i;
+
   /* Verify that the mi input system has been initialized */
   if (g_fdMessageQueue == WIN_FD_INVALID)
     return;
 
-  winSendKeyEvent (KEY_Alt, FALSE);
-  winSendKeyEvent (KEY_AltLang, FALSE);
-  winSendKeyEvent (KEY_LCtrl, FALSE);
-  winSendKeyEvent (KEY_RCtrl, FALSE);
-  winSendKeyEvent (KEY_ShiftL, FALSE);
-  winSendKeyEvent (KEY_ShiftR, FALSE);
+  for(i=0;i<NUM_KEYCODES;i++)
+    {
+      if(winKeyState[i]) winSendKeyEvent (i,FALSE);
+    }
 }
 
 
@@ -424,6 +432,13 @@
   xEvent			xCurrentEvent;
   
   ZeroMemory (&xCurrentEvent, sizeof (xCurrentEvent));
+
+  /* When alt-tabing between screens we can get phantom key up messages
+   * Here we only pass them through it we think we should!
+   */
+  if(winKeyState[dwKey]==FALSE && fDown==FALSE) return;
+  /* Update the keyState map */
+  winKeyState[dwKey]=fDown;
 
   xCurrentEvent.u.u.type = fDown ? KeyPress : KeyRelease;
   xCurrentEvent.u.keyButtonPointer.time =
--- xc/programs/Xserver/hw/xwin/winkeybd.h.orig	Wed Sep 26 14:00:34 2001
+++ xc/programs/Xserver/hw/xwin/winkeybd.h	Thu Jun  6 09:27:34 2002
@@ -44,6 +44,8 @@
 
 #define		WIN_KEYMAP_COLS		3
 
+Bool winKeyState[NUM_KEYCODES];
+
 const int
 g_iKeyMap [] = {
   /* count	Windows VK,	ASCII,		ASCII when extended VK */
--- xc/programs/Xserver/hw/xwin/winwndproc.c.orig	Wed Nov 21 08:51:24 2001
+++ xc/programs/Xserver/hw/xwin/winwndproc.c	Thu Jun  6 23:00:25 2002
@@ -333,8 +333,8 @@
       /* Store the state of all mode keys */
       winStoreModeKeyStates (pScreen);
 
-      /* Release any pressed modifiers */
-      winKeybdReleaseModifierKeys ();
+      /* Release any pressed keys */
+      winKeybdReleaseKeys ();
       return 0;
 
     case WM_SYSKEYDOWN:
