Index: gdk/win32/gdkevents-win32.c
===================================================================
--- gdk/win32/gdkevents-win32.c	(revision 17340)
+++ gdk/win32/gdkevents-win32.c	(working copy)
@@ -1,6 +1,7 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  * Copyright (C) 1998-2002 Tor Lillqvist
+ * Copyright (C) 2007 Cody Russell
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1779,7 +1780,8 @@
       append_event (event);
     }
 
-  g_main_context_iteration (NULL, FALSE);
+  if (g_main_context_pending (NULL))
+    g_main_context_iteration (NULL, FALSE);
 }
 
 GdkRegion *
@@ -2502,15 +2504,6 @@
 	    synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg);
 	}
 
-#if 0
-      if (((GdkWindowObject *) window)->extension_events != 0 &&
-	  _gdk_input_ignore_core)
-	{
-	  GDK_NOTE (EVENTS, g_print (" (ignored)"));
-	  break;
-	}
-#endif
-
       if (!propagate (&window, msg,
 		      p_grab_window, p_grab_owner_events, p_grab_mask,
 		      doesnt_want_button_release, TRUE))
@@ -2730,15 +2723,41 @@
       break;
 
      case WM_MOUSEACTIVATE:
+       impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+
        if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP 
-	   || !((GdkWindowObject *)window)->accept_focus)
+	   || !((GdkWindowObject *)window)->accept_focus
+           || (impl->transient_children != NULL && impl->num_transients))
 	 {
+           GSList *tmplist = impl->transient_children;
+
+           while (tmplist != NULL)
+             {
+               GdkWindow *child = tmplist->data;
+
+               if (child)
+                 {
+                   SetWindowPos (GDK_WINDOW_HWND (child),
+                                 HWND_TOP,
+                                 0, 0, 0, 0,
+                                 SWP_NOSIZE | SWP_NOMOVE);
+                 }
+
+               tmplist = g_slist_next (tmplist);
+             }
+
 	   *ret_valp = MA_NOACTIVATE;
 	   return_val = TRUE;
 	 }
+       else
+         {
+           *ret_valp = MA_ACTIVATE;
+         }
        break;
 
     case WM_KILLFOCUS:
+      GDK_NOTE (EVENTS, g_print (" %p", (HWND) msg->wParam));
+
       if (p_grab_window != NULL && !GDK_WINDOW_DESTROYED (p_grab_window))
 	generate_grab_broken_event (p_grab_window, FALSE, NULL);
 
@@ -2748,6 +2767,9 @@
 
       /* fallthrough */
     case WM_SETFOCUS:
+      if (msg->message == WM_SETFOCUS) {
+	GDK_NOTE (EVENTS, g_print (" %p", (HWND) msg->wParam));
+      }
       if (k_grab_window != NULL && !k_grab_owner_events)
 	break;
 
@@ -2907,7 +2929,7 @@
 		((GdkWindowObject *) window)->resize_count -= 1;
 	      
 	      handle_configure_event (msg, window);
-	      
+
 	      /* Dispatch main loop - to realize resizes... */
 	      handle_stuff_while_moving_or_resizing ();
 	      
@@ -3224,6 +3246,12 @@
       if (k_grab_window == window)
 	gdk_keyboard_ungrab (msg->time);
 
+      impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
+      if (impl->transient_children != NULL)
+        {
+          gdk_window_set_transient_for (window, NULL);
+        }
+
       if ((window != NULL) && (msg->hwnd != GetDesktopWindow ()))
 	gdk_window_destroy_notify (window);
 
@@ -3311,6 +3339,19 @@
       break;
 
     case WM_ACTIVATE:
+      impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+
+      if (msg->wParam == WA_ACTIVE || msg->wParam == WA_CLICKACTIVE)
+        {
+	  if (impl->transient_children && impl->num_transients)
+	    {
+		GdkWindow *child = impl->transient_children->data;
+                if (child)
+		  SetForegroundWindow (GDK_WINDOW_HWND (child));
+		*ret_valp = 0;
+	    }
+        }
+
       /* 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
Index: gdk/win32/gdkwindow-win32.c
===================================================================
--- gdk/win32/gdkwindow-win32.c	(revision 17340)
+++ gdk/win32/gdkwindow-win32.c	(working copy)
@@ -1,7 +1,8 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- * Copyright (C) 1998-2004 Tor Lillqvist
+ * Copyright (C) 1998-2006 Tor Lillqvist
  * Copyright (C) 2001-2004 Hans Breuer
+ * Copyright (C) 2007 Cody Russell
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -33,11 +34,6 @@
 #include "gdkprivate-win32.h"
 #include "gdkinput-win32.h"
 
-#if 0
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <stdio.h>
-#endif
-
 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
 static void         gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
 							GdkColormap *cmap);
@@ -105,6 +101,9 @@
   impl->hint_flags = 0;
   impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
   impl->extension_events_selected = FALSE;
+  impl->transient_owner = NULL;
+  impl->transient_children = NULL;
+  impl->num_transients = 0;
 }
 
 static void
@@ -137,7 +136,7 @@
 
   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
   window_impl = GDK_WINDOW_IMPL_WIN32 (object);
-  
+
   wrapper = (GdkWindowObject*) draw_impl->wrapper;
 
   if (!GDK_WINDOW_DESTROYED (wrapper))
@@ -797,16 +796,41 @@
 			       gboolean   foreign_destroy)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
+  GSList *tmp;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n",
 			   GDK_WINDOW_HWND (window)));
 
+  /* Remove all our transient children */
+  tmp = window_impl->transient_children;
+  while (tmp != NULL)
+    {
+      GdkWindow *child = tmp->data;
+      GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
+
+      child_impl->transient_owner = NULL;
+      tmp = g_slist_next (tmp);
+    }
+  g_slist_free (window_impl->transient_children);
+  window_impl->transient_children = NULL;
+
+  /* Remove ourself from our transient owner */
+  if (window_impl->transient_owner != NULL)
+    {
+      GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
+      GSList *item = g_slist_find (trans_impl->transient_children, window);
+      trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
+      trans_impl->num_transients--;
+      if (!trans_impl->num_transients)
+        trans_impl->transient_children = NULL;
+    }
+
   if (private->extension_events != 0)
     _gdk_input_window_destroy (window);
 
-
   if (!recursing && !foreign_destroy)
     {
       _gdk_win32_drawable_finish (private->impl);
@@ -814,7 +838,6 @@
       private->destroyed = TRUE;
       DestroyWindow (GDK_WINDOW_HWND (window));
     }
-  gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
 }
 
 void
@@ -1446,7 +1469,7 @@
 
       if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
         API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
-	                         0, 0, 0, 0,
+				 0, 0, 0, 0,
 				 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
       else if (((GdkWindowObject *)window)->accept_focus)
         API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
@@ -1735,12 +1758,17 @@
   /* XXX */
 }
 
-void          
+void
 gdk_window_set_transient_for (GdkWindow *window, 
 			      GdkWindow *parent)
 {
-  HWND window_id, parent_id;
+  GSList *item;
+  GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+  GdkWindowImplWin32 *parent_impl = NULL;
 
+  if (parent != NULL)
+    parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
+
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n",
@@ -1748,26 +1776,49 @@
 			   GDK_WINDOW_HWND (parent)));
 
   if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent))
-    return;
+    {
+      if (GDK_WINDOW_DESTROYED (window))
+	GDK_NOTE (MISC, g_print ("... destroyed!\n"));
+      else
+	GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
+      return;
+    }
 
   if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
     {
       GDK_NOTE (MISC, g_print ("... a child window!\n"));
       return;
     }
-  
-  window_id = GDK_WINDOW_HWND (window);
-  parent_id = GDK_WINDOW_HWND (parent);
+  else if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_FOREIGN)
+    {
+      GDK_NOTE (MISC, g_print ("... a foreign window!\n"));
+      return;
+    }
 
-  /* This changes the *owner* of the window, despite the misleading
-   * name. (Owner and parent are unrelated concepts.) At least that's
-   * what people who seem to know what they talk about say on
-   * USENET. Search on Google.
-   */
-  SetLastError (0);
-  if (SetWindowLong (window_id, GWL_HWNDPARENT, (long) parent_id) == 0 &&
-      GetLastError () != 0)
-    WIN32_API_FAILED ("SetWindowLong");
+  if (parent == NULL)
+    {
+      GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
+      if (trans_impl->transient_children != NULL)
+        {
+          item = g_slist_find (trans_impl->transient_children, window);
+          item->data = NULL;
+          trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
+          trans_impl->num_transients--;
+          if (!trans_impl->num_transients)
+            trans_impl->transient_children = NULL;
+
+          g_print ("item removed, transient_children.Length == %d\n", trans_impl->num_transients);
+        }
+
+        window_impl->transient_owner = NULL;
+    }
+  else
+    {
+      parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
+      parent_impl->num_transients++;
+
+      window_impl->transient_owner = parent;
+    }
 }
 
 void
@@ -2504,18 +2555,6 @@
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
-  
-#if 0
-  /* This is not the correct thing to do. We should keep both the
-   * "normal" window title, and the icon name. When the window is
-   * minimized, call SetWindowText() with the icon name, and when the
-   * window is restored, with the normal window title. Also, the name
-   * is in UTF-8, so we should do the normal conversion to either wide
-   * chars or system codepage, and use either the W or A version of
-   * SetWindowText(), depending on Windows version.
-   */
-  API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
-#endif
 }
 
 GdkWindow *
@@ -3205,12 +3244,6 @@
   private = (GdkWindowObject*) window;
 
   private->modal_hint = modal;
-
-  if (GDK_WINDOW_IS_MAPPED (window))
-    API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), 
-			     modal ? HWND_TOPMOST : HWND_NOTOPMOST,
-			     0, 0, 0, 0,
-			     SWP_NOMOVE | SWP_NOSIZE));
 }
 
 void
@@ -3239,15 +3272,6 @@
 
       SetWindowLong (GDK_WINDOW_HWND (window), GWL_HWNDPARENT,
 		     (long) GDK_WINDOW_HWND (owner));
-
-#if 0 /* Should we also turn off the minimize and maximize buttons? */
-      SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
-		     GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
-      SetWindowPos (GDK_WINDOW_HWND (window), NULL,
-		    0, 0, 0, 0,
-		    SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
-		    SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
-#endif
     }
   else
     {
Index: gdk/win32/gdkwindow-win32.h
===================================================================
--- gdk/win32/gdkwindow-win32.h	(revision 17340)
+++ gdk/win32/gdkwindow-win32.h	(working copy)
@@ -86,6 +86,10 @@
   GdkWindowTypeHint type_hint;
 
   gboolean extension_events_selected;
+
+  GdkWindow *transient_owner;
+  GSList    *transient_children;
+  gint       num_transients;
 };
  
 struct _GdkWindowImplWin32Class 
