]> Pileus Git - ~andy/gtk/commitdiff
Add a "is_focus" property indicating whether a widget is the focus widget
authorOwen Taylor <otaylor@redhat.com>
Thu, 6 Jun 2002 15:38:39 +0000 (15:38 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 6 Jun 2002 15:38:39 +0000 (15:38 +0000)
Fri May 17 17:27:21 2002  Owen Taylor  <otaylor@redhat.com>

        * gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
        property indicating whether a widget is the focus
        widget within the toplevel.

        * gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
        properties to indicate (separately) the idea of
        being the part of the toplevel with the input focus
        and being the active widget. (Needed for full XEMBED
        compliance.)

        * gtk/gtkplug.c gtk/gtksocket.c: Update to work
        in terms of is_active/has_toplevel_focus, and thus
        handle the active/focused XEMBED distinction
        correctly.

        * gtk/gtkplug.c (gtk_plug_realize): Remove
        FOCUS_CHANGE_MASK, since we don't need it.

Fri May 17 18:07:34 2002  Owen Taylor  <otaylor@redhat.com>

        * gtk/gtksocket.c (gtk_socket_add_window): Send
        XEMBED_EMBEDDED_NOTIFY.

        * gtk/gtksocket.c: Assume windows without _XEMBED_INFO
        property want to be mapped, for better
        current-Qt compatibility.

12 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkplug.c
gtk/gtksocket.c
gtk/gtksocket.h
gtk/gtkwidget.c
gtk/gtkwindow.c
gtk/gtkwindow.h

index e80822f585da033978ab93fab665c10c53cb9005..6c1a587639ea59f608403712de9213ef64ca3d5e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+Fri May 17 17:27:21 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
+       property indicating whether a widget is the focus
+       widget within the toplevel.
+
+       * gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
+       properties to indicate (separately) the idea of
+       being the part of the toplevel with the input focus
+       and being the active widget. (Needed for full XEMBED
+       compliance.)
+
+       * gtk/gtkplug.c gtk/gtksocket.c: Update to work
+       in terms of is_active/has_toplevel_focus, and thus
+       handle the active/focused XEMBED distinction
+       correctly.
+
+       * gtk/gtkplug.c (gtk_plug_realize): Remove
+       FOCUS_CHANGE_MASK, since we don't need it.
+
+Fri May 17 18:07:34 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksocket.c (gtk_socket_add_window): Send
+       XEMBED_EMBEDDED_NOTIFY.
+
+       * gtk/gtksocket.c: Assume windows without _XEMBED_INFO 
+       property want to be mapped, for better 
+       current-Qt compatibility.
+
 Thu Jun  6 17:27:01 2002  Kristian Rietveld  <kris@gtk.org>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
index e80822f585da033978ab93fab665c10c53cb9005..6c1a587639ea59f608403712de9213ef64ca3d5e 100644 (file)
@@ -1,3 +1,32 @@
+Fri May 17 17:27:21 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
+       property indicating whether a widget is the focus
+       widget within the toplevel.
+
+       * gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
+       properties to indicate (separately) the idea of
+       being the part of the toplevel with the input focus
+       and being the active widget. (Needed for full XEMBED
+       compliance.)
+
+       * gtk/gtkplug.c gtk/gtksocket.c: Update to work
+       in terms of is_active/has_toplevel_focus, and thus
+       handle the active/focused XEMBED distinction
+       correctly.
+
+       * gtk/gtkplug.c (gtk_plug_realize): Remove
+       FOCUS_CHANGE_MASK, since we don't need it.
+
+Fri May 17 18:07:34 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksocket.c (gtk_socket_add_window): Send
+       XEMBED_EMBEDDED_NOTIFY.
+
+       * gtk/gtksocket.c: Assume windows without _XEMBED_INFO 
+       property want to be mapped, for better 
+       current-Qt compatibility.
+
 Thu Jun  6 17:27:01 2002  Kristian Rietveld  <kris@gtk.org>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
index e80822f585da033978ab93fab665c10c53cb9005..6c1a587639ea59f608403712de9213ef64ca3d5e 100644 (file)
@@ -1,3 +1,32 @@
+Fri May 17 17:27:21 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
+       property indicating whether a widget is the focus
+       widget within the toplevel.
+
+       * gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
+       properties to indicate (separately) the idea of
+       being the part of the toplevel with the input focus
+       and being the active widget. (Needed for full XEMBED
+       compliance.)
+
+       * gtk/gtkplug.c gtk/gtksocket.c: Update to work
+       in terms of is_active/has_toplevel_focus, and thus
+       handle the active/focused XEMBED distinction
+       correctly.
+
+       * gtk/gtkplug.c (gtk_plug_realize): Remove
+       FOCUS_CHANGE_MASK, since we don't need it.
+
+Fri May 17 18:07:34 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksocket.c (gtk_socket_add_window): Send
+       XEMBED_EMBEDDED_NOTIFY.
+
+       * gtk/gtksocket.c: Assume windows without _XEMBED_INFO 
+       property want to be mapped, for better 
+       current-Qt compatibility.
+
 Thu Jun  6 17:27:01 2002  Kristian Rietveld  <kris@gtk.org>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
index e80822f585da033978ab93fab665c10c53cb9005..6c1a587639ea59f608403712de9213ef64ca3d5e 100644 (file)
@@ -1,3 +1,32 @@
+Fri May 17 17:27:21 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
+       property indicating whether a widget is the focus
+       widget within the toplevel.
+
+       * gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
+       properties to indicate (separately) the idea of
+       being the part of the toplevel with the input focus
+       and being the active widget. (Needed for full XEMBED
+       compliance.)
+
+       * gtk/gtkplug.c gtk/gtksocket.c: Update to work
+       in terms of is_active/has_toplevel_focus, and thus
+       handle the active/focused XEMBED distinction
+       correctly.
+
+       * gtk/gtkplug.c (gtk_plug_realize): Remove
+       FOCUS_CHANGE_MASK, since we don't need it.
+
+Fri May 17 18:07:34 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksocket.c (gtk_socket_add_window): Send
+       XEMBED_EMBEDDED_NOTIFY.
+
+       * gtk/gtksocket.c: Assume windows without _XEMBED_INFO 
+       property want to be mapped, for better 
+       current-Qt compatibility.
+
 Thu Jun  6 17:27:01 2002  Kristian Rietveld  <kris@gtk.org>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
index e80822f585da033978ab93fab665c10c53cb9005..6c1a587639ea59f608403712de9213ef64ca3d5e 100644 (file)
@@ -1,3 +1,32 @@
+Fri May 17 17:27:21 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
+       property indicating whether a widget is the focus
+       widget within the toplevel.
+
+       * gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
+       properties to indicate (separately) the idea of
+       being the part of the toplevel with the input focus
+       and being the active widget. (Needed for full XEMBED
+       compliance.)
+
+       * gtk/gtkplug.c gtk/gtksocket.c: Update to work
+       in terms of is_active/has_toplevel_focus, and thus
+       handle the active/focused XEMBED distinction
+       correctly.
+
+       * gtk/gtkplug.c (gtk_plug_realize): Remove
+       FOCUS_CHANGE_MASK, since we don't need it.
+
+Fri May 17 18:07:34 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksocket.c (gtk_socket_add_window): Send
+       XEMBED_EMBEDDED_NOTIFY.
+
+       * gtk/gtksocket.c: Assume windows without _XEMBED_INFO 
+       property want to be mapped, for better 
+       current-Qt compatibility.
+
 Thu Jun  6 17:27:01 2002  Kristian Rietveld  <kris@gtk.org>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
index e80822f585da033978ab93fab665c10c53cb9005..6c1a587639ea59f608403712de9213ef64ca3d5e 100644 (file)
@@ -1,3 +1,32 @@
+Fri May 17 17:27:21 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwindow.c gtk/gtkwidget.c: Add a "is_focus"
+       property indicating whether a widget is the focus
+       widget within the toplevel.
+
+       * gtk/gtkwindow.[ch]: Add "is_active" "has_toplevel_focus"
+       properties to indicate (separately) the idea of
+       being the part of the toplevel with the input focus
+       and being the active widget. (Needed for full XEMBED
+       compliance.)
+
+       * gtk/gtkplug.c gtk/gtksocket.c: Update to work
+       in terms of is_active/has_toplevel_focus, and thus
+       handle the active/focused XEMBED distinction
+       correctly.
+
+       * gtk/gtkplug.c (gtk_plug_realize): Remove
+       FOCUS_CHANGE_MASK, since we don't need it.
+
+Fri May 17 18:07:34 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksocket.c (gtk_socket_add_window): Send
+       XEMBED_EMBEDDED_NOTIFY.
+
+       * gtk/gtksocket.c: Assume windows without _XEMBED_INFO 
+       property want to be mapped, for better 
+       current-Qt compatibility.
+
 Thu Jun  6 17:27:01 2002  Kristian Rietveld  <kris@gtk.org>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): don't leak the GArray
index c74c7c47148c79278113f284bb2845909e100e05..25f572dd74f58128aede72187897bed6d3f4d639 100644 (file)
@@ -504,7 +504,6 @@ gtk_plug_realize (GtkWidget *widget)
                            GDK_KEY_RELEASE_MASK |
                            GDK_ENTER_NOTIFY_MASK |
                            GDK_LEAVE_NOTIFY_MASK |
-                           GDK_FOCUS_CHANGE_MASK |
                            GDK_STRUCTURE_MASK);
 
   attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
@@ -681,7 +680,7 @@ gtk_plug_set_focus (GtkWindow *window,
   /* Ask for focus from embedder
    */
 
-  if (focus && !window->has_focus)
+  if (focus && !window->has_toplevel_focus)
     {
       send_xembed_message (plug, XEMBED_REQUEST_FOCUS, 0, 0, 0,
                           gtk_get_current_event_time ());
@@ -885,6 +884,9 @@ send_xembed_message (GtkPlug *plug,
       GdkDisplay *display = gdk_drawable_get_display (plug->socket_window);
       XEvent xevent;
 
+      GTK_NOTE(PLUGSOCKET,
+              g_message ("GtkPlug: Sending XEMBED message of type %ld", message));
+
       xevent.xclient.window = GDK_WINDOW_XWINDOW (plug->socket_window);
       xevent.xclient.type = ClientMessage;
       xevent.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED");
@@ -977,20 +979,20 @@ handle_xembed_message (GtkPlug   *plug,
                       glong      data2,
                       guint32    time)
 {
+  GtkWindow *window = GTK_WINDOW (plug);
+  
   GTK_NOTE (PLUGSOCKET,
-           g_message ("Message of type %ld received", message));
+           g_message ("GtkPlug: Message of type %ld received", message));
   
   switch (message)
     {
     case XEMBED_EMBEDDED_NOTIFY:
       break;
     case XEMBED_WINDOW_ACTIVATE:
-      GTK_NOTE(PLUGSOCKET,
-              g_message ("GtkPlug: ACTIVATE received"));
+      _gtk_window_set_is_active (window, TRUE);
       break;
     case XEMBED_WINDOW_DEACTIVATE:
-      GTK_NOTE(PLUGSOCKET,
-              g_message ("GtkPlug: DEACTIVATE received"));
+      _gtk_window_set_is_active (window, FALSE);
       break;
       
     case XEMBED_MODALITY_ON:
@@ -1001,6 +1003,7 @@ handle_xembed_message (GtkPlug   *plug,
       break;
 
     case XEMBED_FOCUS_IN:
+      _gtk_window_set_has_toplevel_focus (window, TRUE);
       switch (detail)
        {
        case XEMBED_FOCUS_FIRST:
@@ -1010,31 +1013,13 @@ handle_xembed_message (GtkPlug   *plug,
          focus_first_last (plug, GTK_DIR_TAB_BACKWARD);
          break;
        case XEMBED_FOCUS_CURRENT:
-         /* fall through */;
+         break;
        }
-      
-    case XEMBED_FOCUS_OUT:
-      {
-       GtkWidget *widget = GTK_WIDGET (plug);
-       GdkEvent event;
-
-       event.focus_change.type = GDK_FOCUS_CHANGE;
-       event.focus_change.window = widget->window;
-       event.focus_change.send_event = TRUE;
+      break;
 
-       if (message == XEMBED_FOCUS_IN)
-         {
-           event.focus_change.in = TRUE;
-           GTK_WIDGET_CLASS (parent_class)->focus_in_event (widget, (GdkEventFocus *)&event);
-         }
-       else
-         {
-           event.focus_change.in = FALSE;
-           GTK_WIDGET_CLASS (parent_class)->focus_out_event (widget, (GdkEventFocus *)&event);
-         }
-       
-       break;
-      }
+    case XEMBED_FOCUS_OUT:
+      _gtk_window_set_has_toplevel_focus (window, FALSE);
+      break;
       
     case XEMBED_GRAB_KEY:
     case XEMBED_UNGRAB_KEY:
index 7496ef01c79b6925cf46fad3f3c5bec42d3f18dd..53a10bae8c67861e3285ccff5a059e8bbdefe84f 100644 (file)
@@ -25,6 +25,8 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <string.h>
+
 #include "gdk/gdkkeysyms.h"
 #include "gtkmain.h"
 #include "gtkmarshalers.h"
@@ -51,6 +53,8 @@ struct _GtkSocketPrivate
 static void     gtk_socket_class_init           (GtkSocketClass   *klass);
 static void     gtk_socket_init                 (GtkSocket        *socket);
 static void     gtk_socket_finalize             (GObject          *object);
+static void     gtk_socket_notify               (GObject          *object,
+                                                GParamSpec       *pspec);
 static void     gtk_socket_realize              (GtkWidget        *widget);
 static void     gtk_socket_unrealize            (GtkWidget        *widget);
 static void     gtk_socket_size_request         (GtkWidget        *widget,
@@ -63,11 +67,8 @@ static void     gtk_socket_grab_notify          (GtkWidget        *widget,
                                                 gboolean          was_grabbed);
 static gboolean gtk_socket_key_press_event      (GtkWidget        *widget,
                                                 GdkEventKey      *event);
-static gboolean gtk_socket_focus_in_event       (GtkWidget        *widget,
-                                                GdkEventFocus    *event);
-static void     gtk_socket_claim_focus          (GtkSocket        *socket);
-static gboolean gtk_socket_focus_out_event      (GtkWidget        *widget,
-                                                GdkEventFocus    *event);
+static void     gtk_socket_claim_focus          (GtkSocket        *socket,
+                                                gboolean          send_event);
 static void     gtk_socket_send_configure_event (GtkSocket        *socket);
 static gboolean gtk_socket_focus                (GtkWidget        *widget,
                                                 GtkDirectionType  direction);
@@ -125,6 +126,8 @@ gtk_socket_get_private (GtkSocket *socket)
   if (!private)
     {
       private = g_new0 (GtkSocketPrivate, 1);
+      private->resize_count = 0;
+      
       g_object_set_qdata_full (G_OBJECT (socket), private_quark,
                               private, (GDestroyNotify) g_free);
     }
@@ -183,6 +186,7 @@ gtk_socket_class_init (GtkSocketClass *class)
   parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
 
   gobject_class->finalize = gtk_socket_finalize;
+  gobject_class->notify = gtk_socket_notify;
 
   widget_class->realize = gtk_socket_realize;
   widget_class->unrealize = gtk_socket_unrealize;
@@ -191,8 +195,6 @@ gtk_socket_class_init (GtkSocketClass *class)
   widget_class->hierarchy_changed = gtk_socket_hierarchy_changed;
   widget_class->grab_notify = gtk_socket_grab_notify;
   widget_class->key_press_event = gtk_socket_key_press_event;
-  widget_class->focus_in_event = gtk_socket_focus_in_event;
-  widget_class->focus_out_event = gtk_socket_focus_out_event;
   widget_class->focus = gtk_socket_focus;
   
   container_class->remove = gtk_socket_remove;
@@ -229,6 +231,7 @@ gtk_socket_init (GtkSocket *socket)
   socket->focus_in = FALSE;
   socket->have_size = FALSE;
   socket->need_map = FALSE;
+  socket->active = FALSE;
 
   socket->accel_group = gtk_accel_group_new ();
   g_object_set_data (G_OBJECT (socket->accel_group), "gtk-socket", socket);
@@ -660,32 +663,60 @@ remove_grabbed_key (GtkSocket      *socket,
             keyval, modifiers);
 }
 
-static gboolean
-toplevel_focus_in_handler (GtkWidget     *toplevel,
-                          GdkEventFocus *event,
-                          GtkSocket     *socket)
+static void
+socket_update_focus_in (GtkSocket *socket)
 {
-  /* It appears spurious focus in events can occur when
-   *  the window is hidden. So we'll just check to see if
-   *  the window is visible before actually handling the
-   *  event. (Comment from gtkwindow.c)
-   */
-  if (GTK_WIDGET_VISIBLE (toplevel))
-    send_xembed_message (socket, XEMBED_WINDOW_ACTIVATE, 0, 0, 0,
-                        gtk_get_current_event_time ()); /* Will be GDK_CURRENT_TIME */
+  gboolean focus_in = FALSE;
+
+  if (socket->plug_window)
+    {
+      GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
+      if (GTK_WIDGET_TOPLEVEL (toplevel) &&
+         GTK_WINDOW (toplevel)->has_toplevel_focus &&
+         gtk_widget_is_focus (GTK_WIDGET (socket)))
+       focus_in = TRUE;
+    }
+
+  if (focus_in != socket->focus_in)
+    {
+      socket->focus_in = focus_in;
 
-  return FALSE;
+      if (focus_in)
+       {
+         send_xembed_message (socket, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0,
+                              gtk_get_current_event_time ());
+       }
+      else
+       {
+         send_xembed_message (socket, XEMBED_FOCUS_OUT, 0, 0, 0,
+                              gtk_get_current_event_time ());
+      
+       }
+    }
 }
 
-static gboolean
-toplevel_focus_out_handler (GtkWidget     *toplevel,
-                           GdkEventFocus *event,
-                           GtkSocket     *socket)
+static void
+socket_update_active (GtkSocket *socket)
 {
-  send_xembed_message (socket, XEMBED_WINDOW_DEACTIVATE, 0, 0, 0,
-                      gtk_get_current_event_time ()); /* Will be GDK_CURRENT_TIME */
+  gboolean active = FALSE;
 
-  return FALSE;
+  if (socket->plug_window)
+    {
+      GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
+      if (GTK_WIDGET_TOPLEVEL (toplevel) &&
+         GTK_WINDOW (toplevel)->is_active)
+       active = TRUE;
+    }
+
+  if (active != socket->active)
+    {
+      socket->active = active;
+
+      send_xembed_message (socket,
+                          active ? XEMBED_WINDOW_ACTIVATE : XEMBED_WINDOW_DEACTIVATE,
+                          0, 0, 0,
+                          gtk_get_current_event_time ());
+    }
 }
 
 static void
@@ -703,8 +734,10 @@ gtk_socket_hierarchy_changed (GtkWidget *widget,
       if (socket->toplevel)
        {
          gtk_window_remove_accel_group (GTK_WINDOW (socket->toplevel), socket->accel_group);
-         gtk_signal_disconnect_by_func (GTK_OBJECT (socket->toplevel), GTK_SIGNAL_FUNC (toplevel_focus_in_handler), socket);
-         gtk_signal_disconnect_by_func (GTK_OBJECT (socket->toplevel), GTK_SIGNAL_FUNC (toplevel_focus_out_handler), socket);
+         g_signal_handlers_disconnect_by_func (socket->toplevel,
+                                               (gpointer) socket_update_focus_in, socket);
+         g_signal_handlers_disconnect_by_func (socket->toplevel,
+                                               (gpointer) socket_update_active, socket);
        }
 
       socket->toplevel = toplevel;
@@ -712,11 +745,14 @@ gtk_socket_hierarchy_changed (GtkWidget *widget,
       if (toplevel)
        {
          gtk_window_add_accel_group (GTK_WINDOW (socket->toplevel), socket->accel_group);
-         gtk_signal_connect (GTK_OBJECT (socket->toplevel), "focus_in_event",
-                             GTK_SIGNAL_FUNC (toplevel_focus_in_handler), socket);
-         gtk_signal_connect (GTK_OBJECT (socket->toplevel), "focus_out_event",
-                             GTK_SIGNAL_FUNC (toplevel_focus_out_handler), socket);
+         g_signal_connect_swapped (socket->toplevel, "notify::has_toplevel_focus",
+                                   G_CALLBACK (socket_update_focus_in), socket);
+         g_signal_connect_swapped (socket->toplevel, "notify::is_active",
+                                   G_CALLBACK (socket_update_active), socket);
        }
+
+      socket_update_focus_in (socket);
+      socket_update_active (socket);
     }
 }
 
@@ -769,39 +805,23 @@ gtk_socket_key_press_event (GtkWidget   *widget,
     return FALSE;
 }
 
-static gboolean
-gtk_socket_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
-{
-  GtkSocket *socket = GTK_SOCKET (widget);
-
-  if (socket->plug_window)
-    send_xembed_message (socket, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0,
-                        gtk_get_current_event_time ());
-  
-  return TRUE;
-}
-
-static gboolean
-gtk_socket_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
+static void
+gtk_socket_notify (GObject    *object,
+                  GParamSpec *pspec)
 {
-  GtkSocket *socket = GTK_SOCKET (widget);
-  if (socket->plug_window)
-    {
-      send_xembed_message (socket, XEMBED_FOCUS_OUT, 0, 0, 0,
-                          gtk_get_current_event_time ());
-    }
+  if (!strcmp (pspec->name, "is_focus"))
+    return;
 
-  socket->focus_in = FALSE;
-  
-  return TRUE;
+  socket_update_focus_in (GTK_SOCKET (object));
 }
 
 static void
-gtk_socket_claim_focus (GtkSocket *socket)
+gtk_socket_claim_focus (GtkSocket *socket,
+                       gboolean   send_event)
 {
+  if (!send_event)
+    socket->focus_in = TRUE;   /* Otherwise, our notify handler will send FOCUS_IN  */
       
-  socket->focus_in = TRUE;
-  
   /* Oh, the trickery... */
   
   GTK_WIDGET_SET_FLAGS (socket, GTK_CAN_FOCUS);
@@ -841,8 +861,7 @@ gtk_socket_focus (GtkWidget *widget, GtkDirectionType direction)
       send_xembed_message (socket, XEMBED_FOCUS_IN, detail, 0, 0,
                           gtk_get_current_event_time ());
 
-      GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
-      gtk_widget_grab_focus (widget);
+      gtk_socket_claim_focus (socket, FALSE);
  
       return TRUE;
     }
@@ -916,7 +935,6 @@ gtk_socket_add_window (GtkSocket        *socket,
                       GdkNativeWindow   xid,
                       gboolean          need_reparent)
 {
-
   GtkWidget *widget = GTK_WIDGET (socket);
   GdkDisplay *display = gtk_widget_get_display (widget);
   gpointer user_data = NULL;
@@ -996,7 +1014,7 @@ gtk_socket_add_window (GtkSocket        *socket,
        {
          /* FIXME, we should probably actually check the state before we started */
          
-         socket->is_mapped = need_reparent ? TRUE : FALSE;
+         socket->is_mapped = TRUE;
        }
       
       socket->need_map = socket->is_mapped;
@@ -1017,6 +1035,11 @@ gtk_socket_add_window (GtkSocket        *socket,
       if (toplevel && GTK_IS_WINDOW (toplevel))
        gtk_window_add_embedded_xid (GTK_WINDOW (toplevel), xid);
 
+      send_xembed_message (socket, XEMBED_EMBEDDED_NOTIFY, 0, 0, 0,
+                          gtk_get_current_event_time ());
+      socket_update_active (socket);
+      socket_update_focus_in (socket);
+
       gtk_widget_queue_resize (GTK_WIDGET (socket));
     }
 
@@ -1120,6 +1143,9 @@ handle_xembed_message (GtkSocket *socket,
                       glong      data2,
                       guint32    time)
 {
+  GTK_NOTE (PLUGSOCKET,
+           g_message ("GtkSocket: Message of type %ld received", message));
+  
   switch (message)
     {
     case XEMBED_EMBEDDED_NOTIFY:
@@ -1133,7 +1159,7 @@ handle_xembed_message (GtkSocket *socket,
       break;
       
     case XEMBED_REQUEST_FOCUS:
-      gtk_socket_claim_focus (socket);
+      gtk_socket_claim_focus (socket, TRUE);
       break;
 
     case XEMBED_FOCUS_NEXT:
@@ -1309,7 +1335,7 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
     case FocusIn:
       if (xevent->xfocus.mode == EMBEDDED_APP_WANTS_FOCUS)
        {
-         gtk_socket_claim_focus (socket);
+         gtk_socket_claim_focus (socket, TRUE);
        }
       return_val = GDK_FILTER_REMOVE;
       break;
index b6859cc8a9067c888b6a4e486acaf2d2c6ea99a3..bdc4baecf4273c8e800461f6158b605cef4601f1 100644 (file)
@@ -62,7 +62,8 @@ struct _GtkSocket
   guint have_size : 1;
   guint need_map : 1;
   guint is_mapped : 1;
-
+  guint active : 1;
+  
   GtkAccelGroup *accel_group;
   GtkWidget *toplevel;
 };
index e8a93780e722025bbcf8bf6da62469e20639a29c..379877932d592c1c39081f254b50686cffdc8473 100644 (file)
@@ -131,6 +131,7 @@ enum {
   PROP_APP_PAINTABLE,
   PROP_CAN_FOCUS,
   PROP_HAS_FOCUS,
+  PROP_IS_FOCUS,
   PROP_CAN_DEFAULT,
   PROP_HAS_DEFAULT,
   PROP_RECEIVES_DEFAULT,
@@ -453,6 +454,13 @@ gtk_widget_class_init (GtkWidgetClass *klass)
                                                         _("Whether the widget has the input focus"),
                                                         FALSE,
                                                         G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class,
+                                  PROP_HAS_FOCUS,
+                                  g_param_spec_boolean ("is_focus",
+                                                        _("Is focus"),
+                                                        _("Whether the widget is the focus widget within the toplevel"),
+                                                        FALSE,
+                                                        G_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                   PROP_CAN_DEFAULT,
                                   g_param_spec_boolean ("can_default",
@@ -1142,6 +1150,10 @@ gtk_widget_set_property (GObject         *object,
       if (g_value_get_boolean (value))
        gtk_widget_grab_focus (widget);
       break;
+    case PROP_IS_FOCUS:
+      if (g_value_get_boolean (value))
+       gtk_widget_grab_focus (widget);
+      break;
     case PROP_CAN_DEFAULT:
       saved_flags = GTK_WIDGET_FLAGS (widget);
       if (g_value_get_boolean (value))
@@ -1230,6 +1242,9 @@ gtk_widget_get_property (GObject         *object,
     case PROP_HAS_FOCUS:
       g_value_set_boolean (value, (GTK_WIDGET_HAS_FOCUS (widget) != FALSE));
       break;
+    case PROP_IS_FOCUS:
+      g_value_set_boolean (value, (gtk_widget_is_focus (widget)));
+      break;
     case PROP_CAN_DEFAULT:
       g_value_set_boolean (value, (GTK_WIDGET_CAN_DEFAULT (widget) != FALSE));
       break;
index 78822c462b04b451a8732b4c9141b4d7a3b01061..70ff43b46c8ccf50f03dd658defab28fcb009efd 100644 (file)
@@ -70,6 +70,10 @@ enum {
   PROP_DESTROY_WITH_PARENT,
   PROP_ICON,
   PROP_SCREEN,
+
+  /* Readonly properties */
+  PROP_IS_ACTIVE,
+  PROP_HAS_TOPLEVEL_FOCUS,
   
   LAST_ARG
 };
@@ -504,6 +508,22 @@ gtk_window_class_init (GtkWindowClass *klass)
                                                        GDK_TYPE_SCREEN,
                                                        G_PARAM_READWRITE));
 
+  g_object_class_install_property (gobject_class,
+                                   PROP_IS_ACTIVE,
+                                   g_param_spec_boolean ("is_active",
+                                                        _("Is Active"),
+                                                        _("Whether the toplevel is the current active window"),
+                                                        FALSE,
+                                                        G_PARAM_READABLE));
+  
+  g_object_class_install_property (gobject_class,
+                                   PROP_HAS_TOPLEVEL_FOCUS,
+                                   g_param_spec_boolean ("has_toplevel_focus",
+                                                        _("Focus in Toplevel"),
+                                                        _("Whether the input focus is within this GtkWindow"),
+                                                        FALSE,
+                                                        G_PARAM_READABLE));
+  
   window_signals[SET_FOCUS] =
     g_signal_new ("set_focus",
                   G_TYPE_FROM_CLASS (object_class),
@@ -770,6 +790,12 @@ gtk_window_get_property (GObject      *object,
     case PROP_SCREEN:
       g_value_set_object (value, window->screen);
       break;
+    case PROP_IS_ACTIVE:
+      g_value_set_boolean (value, window->is_active);
+      break;
+    case PROP_HAS_TOPLEVEL_FOCUS:
+      g_value_set_boolean (value, window->has_toplevel_focus);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3772,14 +3798,10 @@ gtk_window_focus_in_event (GtkWidget     *widget,
    */
   if (GTK_WIDGET_VISIBLE (widget))
     {
-      window->has_focus = TRUE;
-      
-      if (window->focus_widget &&
-         window->focus_widget != widget &&
-         !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
-       do_focus_change (window->focus_widget, TRUE);   
+      _gtk_window_set_has_toplevel_focus (window, TRUE);
+      _gtk_window_set_is_active (window, TRUE);
     }
-
+      
   return FALSE;
 }
 
@@ -3789,12 +3811,8 @@ gtk_window_focus_out_event (GtkWidget     *widget,
 {
   GtkWindow *window = GTK_WINDOW (widget);
 
-  window->has_focus = FALSE;
-  
-  if (window->focus_widget &&
-      window->focus_widget != widget &&
-      GTK_WIDGET_HAS_FOCUS (window->focus_widget))
-    do_focus_change (window->focus_widget, FALSE);
+  _gtk_window_set_has_toplevel_focus (window, FALSE);
+  _gtk_window_set_is_active (window, FALSE);
 
   return FALSE;
 }
@@ -3934,6 +3952,8 @@ gtk_window_real_set_focus (GtkWindow *window,
 
       if (window->has_focus)
        do_focus_change (window->focus_widget, FALSE);
+
+      g_object_notify (G_OBJECT (window->focus_widget), "is_focus");
     }
   
   window->focus_widget = focus;
@@ -3952,6 +3972,8 @@ gtk_window_real_set_focus (GtkWindow *window,
 
       if (window->has_focus)
        do_focus_change (window->focus_widget, TRUE);
+
+      g_object_notify (G_OBJECT (window->focus_widget), "is_focus");
     }
   
   if (window->default_widget &&
@@ -6084,3 +6106,81 @@ _gtk_window_activate_key (GtkWindow   *window,
   else
     return FALSE;
 }
+
+static void
+window_update_has_focus (GtkWindow *window)
+{
+  GtkWidget *widget = GTK_WIDGET (window);
+  gboolean has_focus = window->has_toplevel_focus && window->is_active;
+  
+  if (has_focus != window->has_focus)
+    {
+      window->has_focus = has_focus;
+      
+      if (has_focus)
+       {
+         if (window->focus_widget &&
+             window->focus_widget != widget &&
+             !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
+           do_focus_change (window->focus_widget, TRUE);       
+       }
+      else
+       {
+         if (window->focus_widget &&
+             window->focus_widget != widget &&
+             GTK_WIDGET_HAS_FOCUS (window->focus_widget))
+           do_focus_change (window->focus_widget, FALSE);
+       }
+    }
+}
+
+/**
+ * _gtk_window_set_is_active:
+ * @window: a #GtkWindow
+ * @is_active: %TRUE if the window is in the currently active toplevel
+ * 
+ * Internal function that sets whether the #GtkWindow is part
+ * of the currently active toplevel window (taking into account inter-process
+ * embedding.)
+ **/
+void
+_gtk_window_set_is_active (GtkWindow *window,
+                          gboolean   is_active)
+{
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  is_active = is_active != FALSE;
+
+  if (is_active != window->is_active)
+    {
+      window->is_active = is_active;
+      window_update_has_focus (window);
+
+      g_object_notify (G_OBJECT (window), "is_active");
+    }
+}
+
+/**
+ * _gtk_window_set_has_toplevel_focus:
+ * @window: a #GtkWindow
+ * @has_toplevel_focus: %TRUE if the in
+ * 
+ * Internal function that sets whether the keyboard focus for the
+ * toplevel window (taking into account inter-process embedding.)
+ **/
+void
+_gtk_window_set_has_toplevel_focus (GtkWindow *window,
+                                  gboolean   has_toplevel_focus)
+{
+  g_return_if_fail (GTK_IS_WINDOW (window));
+  
+  has_toplevel_focus = has_toplevel_focus != FALSE;
+
+  if (has_toplevel_focus != window->has_toplevel_focus)
+    {
+      window->has_toplevel_focus = has_toplevel_focus;
+      window_update_has_focus (window);
+
+      g_object_notify (G_OBJECT (window), "has_toplevel_focus");
+    }
+}
index 0251131be37daa067dbe32864cfc80dbc82281dd..9dff5d72053f71fabdf2c19248cc48cc7155d0b4 100644 (file)
@@ -98,7 +98,10 @@ struct _GtkWindow
   guint decorated : 1;
   
   guint type_hint : 3; /* GdkWindowTypeHint */ 
-  guint gravity : 5; /* GdkGravity */ 
+  guint gravity : 5; /* GdkGravity */
+
+  guint is_active : 1;
+  guint has_toplevel_focus : 1;
   
   guint frame_left;
   guint frame_top;
@@ -344,6 +347,11 @@ GtkWindowGroup *_gtk_window_get_group          (GtkWindow *window);
 gboolean        _gtk_window_activate_key       (GtkWindow   *window,
                                                GdkEventKey *event);
 
+void            _gtk_window_set_has_toplevel_focus (GtkWindow *window,
+                                                   gboolean   has_toplevel_focus);
+void            _gtk_window_set_is_active          (GtkWindow *window,
+                                                   gboolean   is_active);
+
 typedef void (*GtkWindowKeysForeachFunc) (GtkWindow      *window,
                                          guint           keyval,
                                          GdkModifierType modifiers,