Index: gdk/win32/gdkevents-win32.c
===================================================================
--- gdk/win32/gdkevents-win32.c	(revision 19371)
+++ gdk/win32/gdkevents-win32.c	(working copy)
@@ -2765,15 +2765,55 @@
       update_colors (window, TRUE);
       break;
 
-     case WM_MOUSEACTIVATE:
-       if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP 
-	   || !((GdkWindowObject *)window)->accept_focus)
-	 {
-	   *ret_valp = MA_NOACTIVATE;
-	   return_val = TRUE;
-	 }
-       break;
+    case WM_SYSCOMMAND:
 
+      /*
+       * On Windows, transient windows will not have their own taskbar entries.
+       * Because of this, we must hide and restore groups of transients in both
+       * directions.  That is, all transient children must be hidden or restored
+       * with this window, but if this window's transient owner also has a
+       * transient owner then this window's transient owner must be hidden/restored
+       * with this one.  And etc, up the chain until we hit an ancestor that has no
+       * transient owner.
+       *
+       * It would be a good idea if applications don't chain transient windows
+       * together.  There's a limit to how much evil GTK can try to shield you
+       * from.
+       */
+
+      if (msg->wParam == SC_MINIMIZE || msg->wParam == SC_RESTORE)
+	{
+	  GdkWindow *tmp_window = NULL;
+	  GdkWindowImplWin32 *tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+
+	  while (tmp_impl->transient_owner != NULL)
+	    {
+	      tmp_window = tmp_impl->transient_owner;
+	      tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (tmp_window)->impl);
+	    }
+
+	  if (tmp_window == NULL)
+	    {
+	      tmp_window = window;
+	    }
+
+	  if (!tmp_impl->changing_state)
+	    {
+	      show_window_recurse (tmp_window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
+	    }
+	}
+
+      break;
+
+    case WM_MOUSEACTIVATE:
+      if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP 
+	  || !((GdkWindowObject *)window)->accept_focus)
+	{
+	  *ret_valp = MA_NOACTIVATE;
+	  return_val = TRUE;
+	}
+      break;
+
     case WM_KILLFOCUS:
       if (p_grab_window != NULL && !GDK_WINDOW_DESTROYED (p_grab_window))
 	generate_grab_broken_event (p_grab_window, FALSE, NULL);
@@ -3380,33 +3420,7 @@
        * together.  There's a limit to how much evil GTK can try to shield you
        * from.
        */
-      GdkWindow *tmp_window = NULL;
-      GdkWindowImplWin32 *tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
 
-      while (tmp_impl->transient_owner != NULL)
-	{
-	  tmp_window = tmp_impl->transient_owner;
-	  tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (tmp_window)->impl);
-	}
-
-      if (tmp_window == NULL)
-	tmp_window = window;
-
-      if (LOWORD (msg->wParam) == WA_INACTIVE && HIWORD (msg->wParam))
-        {
-	  if (!tmp_impl->changing_state)
-	    {
-	      show_window_recurse (tmp_window, TRUE);
-	    }
-        }
-      else if (LOWORD (msg->wParam) == WA_ACTIVE && HIWORD (msg->wParam))
-	{
-	  if (!tmp_impl->changing_state)
-	    {
-	      show_window_recurse (tmp_window, FALSE);
-	    }
-        }
-
       /* Bring any tablet contexts to the top of the overlap order when
        * one of our windows is activated.
        * NOTE: It doesn't seem to work well if it is done in WM_ACTIVATEAPP
