Index: include/allegro5/platform/aintwin.h
===================================================================
--- include/allegro5/platform/aintwin.h	(revision 15830)
+++ include/allegro5/platform/aintwin.h	(working copy)
@@ -112,6 +112,7 @@
                            bool repeated, ALLEGRO_DISPLAY_WIN *win_disp);
 void _al_win_kbd_handle_key_release(int scode, int vcode, bool extended,
                            ALLEGRO_DISPLAY_WIN *win_disp);
+void _al_win_update_key_state(void);
 
 /* mouse routines */
 void _al_win_mouse_handle_move(int x, int y, bool abs, ALLEGRO_DISPLAY_WIN *win_disp);
Index: src/win/wkeyboard.c
===================================================================
--- src/win/wkeyboard.c	(revision 15830)
+++ src/win/wkeyboard.c	(working copy)
@@ -30,6 +30,7 @@
 static bool installed = false;
 static ALLEGRO_KEYBOARD the_keyboard;
 static ALLEGRO_KEYBOARD_STATE the_state;
+static unsigned char win_key_state[256];
 static int modifiers = 0;
 
 /* lookup table for converting virtualkey VK_* codes into Allegro ALLEGRO_KEY_* codes */
@@ -108,6 +109,8 @@
 static bool init_keyboard(void);
 static void exit_keyboard(void);
 static void get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state);
+static void update_modifiers(int code, bool pressed);
+static void update_toggle_modifiers(void);
 static ALLEGRO_KEYBOARD *get_keyboard(void);
 
 
@@ -145,6 +148,7 @@
 {
    memset(&the_keyboard, 0, sizeof the_keyboard);
    memset(&the_state, 0, sizeof the_state);
+   memset(&win_key_state, 0, sizeof win_key_state);
 
    /* Initialise the keyboard object for use as an event source. */
    _al_event_source_init(&the_keyboard.es);
@@ -181,9 +185,74 @@
 }
 
 
+/* fill_windows_keyboard_state:
+ *  Copy the current keyboard state into param.
+ */
+static void fill_windows_keyboard_state(void *param)
+{
+   *(bool*)param = GetKeyboardState((PBYTE)win_key_state);
+}
 
+
+/* _al_win_update_key_state:
+ *   Update the current keyboard state.
+ *   Attempts to read the real current keyboard state.
+ */
+void _al_win_update_key_state(void)
+{
+   unsigned int i;
+   ALLEGRO_DISPLAY *disp = NULL;
+   ALLEGRO_SYSTEM *sys;
+   HWND windowHandle = NULL;
+   bool ret_val = 0;
+
+   /* Determine the current foreground window. */
+   sys = al_get_system_driver();
+   for (i = 0; i < sys->displays._size; i++) {
+      ALLEGRO_DISPLAY_WIN **d = (void*)_al_vector_ref(&sys->displays, i);
+      if ((*d)->window == GetForegroundWindow()) {
+         windowHandle = (*d)->window;
+         disp = (void*)*d;
+         break;
+      }
+   }
+   the_state.display = disp;
+
+   if (windowHandle != NULL) {
+     /* Get real most current state from Windows API call. */
+     _al_win_wnd_call_proc(windowHandle, fill_windows_keyboard_state,
+        &ret_val);
+     if (ret_val) {
+        /* Translate Windows key states to Allegro key states. */
+        for (i = 0; i < 256; i++) {
+           if (win_key_state[i] & 0x80)
+              _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, hw_to_mycode[i]);
+           else
+              _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, hw_to_mycode[i]);
+        }
+
+        /* Update toggle modifier key flags. */
+        update_toggle_modifiers();
+
+        /* Update modifier key flags. */
+        update_modifiers(ALLEGRO_KEY_LSHIFT, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_LSHIFT));
+        update_modifiers(ALLEGRO_KEY_RSHIFT, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_RSHIFT));
+        update_modifiers(ALLEGRO_KEY_LCTRL, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_LCTRL));
+        update_modifiers(ALLEGRO_KEY_RCTRL, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_RCTRL));
+        update_modifiers(ALLEGRO_KEY_ALT, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_ALT));
+        update_modifiers(ALLEGRO_KEY_ALTGR, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_ALTGR));
+        update_modifiers(ALLEGRO_KEY_LWIN, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_LWIN));
+        update_modifiers(ALLEGRO_KEY_RWIN, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_RWIN));
+        update_modifiers(ALLEGRO_KEY_MENU, _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_MENU));
+     }
+   }
+}
+
+
 /* get_keyboard_state:
- *  Copy the current keyboard state into RET_STATE.
+ *  Copy the current keyboard state into ret_state.
+ *  (it does not read the real state, it only copies the 
+ *   internal state which was asynchronously mainted by events)
  */
 static void get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state)
 {
@@ -191,6 +260,7 @@
    ALLEGRO_DISPLAY *disp = NULL;
    ALLEGRO_SYSTEM *sys;
 
+   /* Determine the current foreground window. */
    sys = al_get_system_driver();
    for (i = 0; i < sys->displays._size; i++) {
       ALLEGRO_DISPLAY_WIN **d = (void*)_al_vector_ref(&sys->displays, i);
@@ -200,6 +270,7 @@
       }
    }
    the_state.display = disp;
+
    *ret_state = the_state;
 }
 
@@ -260,6 +331,12 @@
          ON_OFF2(ALLEGRO_KEYMOD_ALT);
       case ALLEGRO_KEY_ALTGR:
          ON_OFF2(ALLEGRO_KEYMOD_ALTGR);
+      case ALLEGRO_KEY_LWIN:
+         ON_OFF2(ALLEGRO_KEYMOD_LWIN);
+      case ALLEGRO_KEY_RWIN:
+         ON_OFF2(ALLEGRO_KEYMOD_RWIN);
+      case ALLEGRO_KEY_MENU:
+         ON_OFF2(ALLEGRO_KEYMOD_MENU);
    }
 
 #undef ON_OFF2
Index: src/win/wwindow.c
===================================================================
--- src/win/wwindow.c	(revision 15830)
+++ src/win/wwindow.c	(working copy)
@@ -784,6 +784,17 @@
          if (HIWORD(wParam) && LOWORD(wParam) != WA_INACTIVE)
             break;
 
+         /* On switching in, update keyboard state once
+          * to have correct states for all keys which were pressed while
+          * switching out and which were released while the window did not
+          * have the input focus. Also fixes modifier flag from being stuck
+          * in the state they were in during switching out.
+          */
+         if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE)
+         {
+            _al_win_update_key_state();
+         }
+
          if (HIWORD(wParam))
             d->flags |= ALLEGRO_MINIMIZED;
          else
