Index: gdk/gdkevents.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkevents.h,v
retrieving revision 1.21
diff -u -p -r1.21 gdkevents.h
--- gdk/gdkevents.h	10 Aug 2003 23:37:29 -0000	1.21
+++ gdk/gdkevents.h	20 Nov 2003 22:21:48 -0000
@@ -34,7 +34,7 @@ typedef struct _GdkEventClient	    GdkEv
 typedef struct _GdkEventDND         GdkEventDND;
 typedef struct _GdkEventWindowState GdkEventWindowState;
 typedef struct _GdkEventSetting     GdkEventSetting;
-
+typedef struct _GdkEventTakeFocus   GdkEventTakeFocus;    
 typedef union  _GdkEvent	    GdkEvent;
 
 typedef void (*GdkEventFunc) (GdkEvent *event,
@@ -118,7 +118,8 @@ typedef enum
   GDK_NO_EXPOSE		= 30,
   GDK_SCROLL            = 31,
   GDK_WINDOW_STATE      = 32,
-  GDK_SETTING           = 33
+  GDK_SETTING           = 33,
+  GDK_TAKE_FOCUS        = 34
 } GdkEventType;
 
 /* Event masks. (Used to select what types of events a window
@@ -422,6 +423,14 @@ struct _GdkEventDND {
   gshort x_root, y_root;
 };
 
+struct _GdkEventTakeFocus 
+{
+  GdkEventType type;
+  GdkWindow   *window;      
+  gint8        send_event;
+  guint32      time;
+};
+
 union _GdkEvent
 {
   GdkEventType		    type;
@@ -443,6 +452,7 @@ union _GdkEvent
   GdkEventDND               dnd;
   GdkEventWindowState       window_state;
   GdkEventSetting           setting;
+  GdkEventTakeFocus         take_focus;
 };
 
 GType     gdk_event_get_type            (void);
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.118
diff -u -p -r1.118 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	11 Aug 2003 16:08:27 -0000	1.118
+++ gdk/x11/gdkevents-x11.c	20 Nov 2003 22:21:49 -0000
@@ -1968,16 +1968,12 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
     }
   else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
     {
-      GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
+      event->any.type = GDK_TAKE_FOCUS;
+      event->take_focus.send_event = xevent->xclient.send_event;
+      event->take_focus.time = xevent->xclient.data.l[1];  
 
-      /* There is no way of knowing reliably whether we are viewable;
-       * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
-       */
-      if (toplevel)
-	_gdk_x11_set_input_focus_safe (display, toplevel->focus_window,
-				       RevertToParent,
-				       xevent->xclient.data.l[1]);
+      return GDK_FILTER_TRANSLATE;
     }
   else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
 	   !_gdk_x11_display_is_root_window (display,
Index: gdk/x11/gdkwindow-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v
retrieving revision 1.195
diff -u -p -r1.195 gdkwindow-x11.c
--- gdk/x11/gdkwindow-x11.c	23 Oct 2003 18:50:40 -0000	1.195
+++ gdk/x11/gdkwindow-x11.c	20 Nov 2003 22:21:50 -0000
@@ -989,8 +989,8 @@ update_wm_hints (GdkWindow *window,
       private->state & GDK_WINDOW_STATE_WITHDRAWN)
     return;
 
-  wm_hints.flags = StateHint;
-  wm_hints.input = True;
+  wm_hints.flags = InputHint | StateHint;
+  wm_hints.input = False;
   wm_hints.initial_state = NormalState;
   
   if (private->state & GDK_WINDOW_STATE_ICONIFIED)
@@ -1681,6 +1681,25 @@ gdk_window_focus (GdkWindow *window,
 				     RevertToParent,
 				     timestamp);
     }
+}
+
+void 
+gdk_window_take_focus (GdkWindow *window,
+		       guint32    timestamp) 
+{
+  GdkDisplay *display;
+  
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  display = GDK_WINDOW_DISPLAY (window);
+
+  _gdk_x11_set_input_focus_safe (display, 
+				 GDK_WINDOW_XID (window),
+				 RevertToParent,
+				 timestamp);
 }
 
 /**
Index: gtk/gtkwidget.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.h,v
retrieving revision 1.145
diff -u -p -r1.145 gtkwidget.h
--- gtk/gtkwidget.h	21 Sep 2003 22:04:47 -0000	1.145
+++ gtk/gtkwidget.h	20 Nov 2003 22:21:50 -0000
@@ -403,6 +403,10 @@ struct _GtkWidgetClass
 
   void (* screen_changed) (GtkWidget *widget,
 			   GdkScreen *previous_screen);
+  
+  gboolean (* take_focus_event) (GtkWidget         *widget,
+				 GdkEventTakeFocus *event);
+  
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
@@ -410,7 +414,6 @@ struct _GtkWidgetClass
   void (*_gtk_reserved4) (void);
   void (*_gtk_reserved5) (void);
   void (*_gtk_reserved6) (void);
-  void (*_gtk_reserved7) (void);
 };
 
 struct _GtkWidgetAuxInfo
Index: gtk/gtkwidget.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.c,v
retrieving revision 1.360
diff -u -p -r1.360 gtkwidget.c
--- gtk/gtkwidget.c	7 Nov 2003 21:57:20 -0000	1.360
+++ gtk/gtkwidget.c	20 Nov 2003 22:21:52 -0000
@@ -117,6 +117,7 @@ enum {
   SHOW_HELP,
   ACCEL_CLOSURES_CHANGED,
   SCREEN_CHANGED,
+  TAKE_FOCUS_EVENT,
   LAST_SIGNAL
 };
 
@@ -388,6 +389,7 @@ gtk_widget_class_init (GtkWidgetClass *k
   klass->drag_drop = NULL;
   klass->drag_data_received = NULL;
   klass->screen_changed = NULL;
+  klass->take_focus_event = NULL;
 
   klass->show_help = gtk_widget_real_show_help;
   
@@ -1309,6 +1311,15 @@ gtk_widget_class_init (GtkWidgetClass *k
 		  _gtk_marshal_VOID__OBJECT,
 		  G_TYPE_NONE, 1,
 		  GDK_TYPE_SCREEN);
+  widget_signals[TAKE_FOCUS_EVENT] =
+    g_signal_new ("take_focus_event",
+		  G_TYPE_FROM_CLASS (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GtkWidgetClass, take_focus_event),
+		  _gtk_boolean_handled_accumulator, NULL,
+		  _gtk_marshal_BOOLEAN__BOXED,
+		  G_TYPE_BOOLEAN, 1,
+		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
   
   binding_set = gtk_binding_set_by_class (klass);
   gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
@@ -3475,6 +3486,9 @@ gtk_widget_event_internal (GtkWidget *wi
 	case GDK_VISIBILITY_NOTIFY:
 	  signal_num = VISIBILITY_NOTIFY_EVENT;
 	  break;
+	case GDK_TAKE_FOCUS:
+	  signal_num = TAKE_FOCUS_EVENT;
+	  break;
 	default:
 	  g_warning ("gtk_widget_event(): unhandled event type: %d", event->type);
 	  signal_num = -1;
@@ -7284,3 +7298,4 @@ gtk_widget_set_no_show_all (GtkWidget *w
   
   g_object_notify (G_OBJECT (widget), "no_show_all");
 }
+
Index: gtk/gtkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.h,v
retrieving revision 1.72
diff -u -p -r1.72 gtkwindow.h
--- gtk/gtkwindow.h	3 Nov 2003 19:41:03 -0000	1.72
+++ gtk/gtkwindow.h	20 Nov 2003 22:21:52 -0000
@@ -350,6 +350,8 @@ void             gtk_window_group_add_wi
 						 GtkWindow          *window);
 void             gtk_window_group_remove_window (GtkWindowGroup     *window_group,
 					         GtkWindow          *window);
+void             gtk_window_take_focus          (GtkWindow          *window,
+						 guint32             timestamp);
 
 /* --- internal functions --- */
 void            _gtk_window_internal_set_focus (GtkWindow *window,
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.255
diff -u -p -r1.255 gtkwindow.c
--- gtk/gtkwindow.c	7 Nov 2003 21:57:20 -0000	1.255
+++ gtk/gtkwindow.c	20 Nov 2003 22:21:54 -0000
@@ -7134,3 +7134,16 @@ gtk_window_set_auto_startup_notification
 {
   disable_startup_notification = !setting;
 }
+
+
+void
+gtk_window_take_focus (GtkWindow *window,
+		       guint32    timestamp)
+{
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (GTK_WIDGET_REALIZED (window))
+    {
+      gdk_window_take_focus (GTK_WIDGET (window)->window, timestamp);
+    }
+}
Index: gtk/gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.228
diff -u -p -r1.228 gtkmain.c
--- gtk/gtkmain.c	28 Oct 2003 14:23:26 -0000	1.228
+++ gtk/gtkmain.c	20 Nov 2003 22:21:55 -0000
@@ -1498,6 +1498,12 @@ gtk_main_do_event (GdkEvent *event)
     case GDK_NOTHING:
       break;
       
+    case GDK_TAKE_FOCUS:
+      if (!gtk_widget_event (event_widget, event))
+	gtk_window_take_focus (GTK_WINDOW (event_widget),
+			       event->take_focus.time);
+      break;
+
     case GDK_DELETE:
       g_object_ref (event_widget);
       if ((!window_group->grabs || gtk_widget_get_toplevel (window_group->grabs->data) == event_widget) &&
