]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtksocket.c
Add _gtk_toggle_action_set_active() internal function
[~andy/gtk] / gtk / gtksocket.c
index c1093481481f7ac3f4c5fb40d2df4d896218287f..08f0cd18904b4044808dfe510d5f02b35e83565e 100644 (file)
 #include "gtksocket.h"
 #include "gtksocketprivate.h"
 #include "gtkdnd.h"
-#include "gtkextendedlayout.h"
 #include "gtkintl.h"
 
-#include "gtkalias.h"
+
+/**
+ * SECTION:gtksocket
+ * @Short_description: Container for widgets from other processes
+ * @Title: GtkSocket
+ * @See_also: #GtkPlug, <ulink url="http://www.freedesktop.org/Standards/xembed-spec">XEmbed</ulink>
+ *
+ * Together with #GtkPlug, #GtkSocket provides the ability
+ * to embed widgets from one process into another process
+ * in a fashion that is transparent to the user. One
+ * process creates a #GtkSocket widget and passes
+ * that widget's window ID to the other process,
+ * which then creates a #GtkPlug with that window ID.
+ * Any widgets contained in the #GtkPlug then will appear
+ * inside the first application's window.
+ *
+ * The socket's window ID is obtained by using
+ * gtk_socket_get_id(). Before using this function,
+ * the socket must have been realized, and for hence,
+ * have been added to its parent.
+ *
+ * <example>
+ * <title>Obtaining the window ID of a socket.</title>
+ * <programlisting>
+ * GtkWidget *socket = gtk_socket_new (<!-- -->);
+ * gtk_widget_show (socket);
+ * gtk_container_add (GTK_CONTAINER (parent), socket);
+ *
+ * /<!---->* The following call is only necessary if one of
+ *  * the ancestors of the socket is not yet visible.
+ *  *<!---->/
+ * gtk_widget_realize (socket);
+ * g_print ("The ID of the sockets window is %#x\n",
+ *          gtk_socket_get_id (socket));
+ * </programlisting>
+ * </example>
+ *
+ * Note that if you pass the window ID of the socket to another
+ * process that will create a plug in the socket, you
+ * must make sure that the socket widget is not destroyed
+ * until that plug is created. Violating this rule will
+ * cause unpredictable consequences, the most likely
+ * consequence being that the plug will appear as a
+ * separate toplevel window. You can check if the plug
+ * has been created by using gtk_socket_get_plug_window(). If
+ * it returns a non-%NULL value, then the plug has been
+ * successfully created inside of the socket.
+ *
+ * When GTK+ is notified that the embedded window has been
+ * destroyed, then it will destroy the socket as well. You
+ * should always, therefore, be prepared for your sockets
+ * to be destroyed at any time when the main event loop
+ * is running. To prevent this from happening, you can
+ * connect to the #GtkSocket::plug-removed signal.
+ *
+ * The communication between a #GtkSocket and a #GtkPlug follows the
+ * <ulink url="http://www.freedesktop.org/Standards/xembed-spec">XEmbed</ulink>
+ * protocol. This protocol has also been implemented in other toolkits, e.g.
+ * <application>Qt</application>, allowing the same level of integration
+ * when embedding a <application>Qt</application> widget in GTK or vice versa.
+ *
+ * A socket can also be used to swallow arbitrary
+ * pre-existing top-level windows using gtk_socket_steal(),
+ * though the integration when this is done will not be as close
+ * as between a #GtkPlug and a #GtkSocket.
+ *
+ * <note>
+ * The #GtkPlug and #GtkSocket widgets are currently not available
+ * on all platforms supported by GTK+.
+ * </note>
+ */
 
 /* Forward declararations */
 
@@ -68,7 +137,6 @@ static void     gtk_socket_forall               (GtkContainer     *container,
                                                 GtkCallback       callback,
                                                 gpointer          callback_data);
 
-static void gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface);
 
 /* Local data */
 
@@ -100,10 +168,7 @@ _gtk_socket_get_private (GtkSocket *socket)
   return G_TYPE_INSTANCE_GET_PRIVATE (socket, GTK_TYPE_SOCKET, GtkSocketPrivate);
 }
 
-G_DEFINE_TYPE_WITH_CODE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER,
-                         G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
-                                                gtk_socket_extended_layout_interface_init))
-
+G_DEFINE_TYPE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER)
 
 static void
 gtk_socket_finalize (GObject *object)
@@ -190,8 +255,6 @@ gtk_socket_class_init (GtkSocketClass *class)
 static void
 gtk_socket_init (GtkSocket *socket)
 {
-  GtkSocketPrivate *priv;
-
   socket->request_width = 0;
   socket->request_height = 0;
   socket->current_width = 0;
@@ -206,9 +269,6 @@ gtk_socket_init (GtkSocket *socket)
 
   socket->accel_group = gtk_accel_group_new ();
   g_object_set_data (G_OBJECT (socket->accel_group), I_("gtk-socket"), socket);
-
-  priv = _gtk_socket_get_private (socket);
-  priv->have_natural_size = FALSE;
 }
 
 /**
@@ -228,32 +288,6 @@ gtk_socket_new (void)
   return GTK_WIDGET (socket);
 }
 
-/**
- * gtk_socket_steal:
- * @socket_: a #GtkSocket
- * @wid: the window ID of an existing toplevel window.
- * 
- * Reparents a pre-existing toplevel window into a #GtkSocket. This is
- * meant to embed clients that do not know about embedding into a
- * #GtkSocket, however doing so is inherently unreliable, and using
- * this function is not recommended.
- *
- * The #GtkSocket must have already be added into a toplevel window
- *  before you can make this call.
- **/
-void           
-gtk_socket_steal (GtkSocket      *socket,
-                 GdkNativeWindow wid)
-{
-  g_return_if_fail (GTK_IS_SOCKET (socket));
-  g_return_if_fail (GTK_WIDGET_ANCHORED (socket));
-
-  if (!GTK_WIDGET_REALIZED (socket))
-    gtk_widget_realize (GTK_WIDGET (socket));
-
-  _gtk_socket_add_window (socket, wid, TRUE);
-}
-
 /**
  * gtk_socket_add_id:
  * @socket_: a #GtkSocket
@@ -279,7 +313,7 @@ gtk_socket_add_id (GtkSocket      *socket,
   g_return_if_fail (GTK_IS_SOCKET (socket));
   g_return_if_fail (GTK_WIDGET_ANCHORED (socket));
 
-  if (!GTK_WIDGET_REALIZED (socket))
+  if (!gtk_widget_get_realized (GTK_WIDGET (socket)))
     gtk_widget_realize (GTK_WIDGET (socket));
 
   _gtk_socket_add_window (socket, window_id, TRUE);
@@ -304,7 +338,7 @@ gtk_socket_get_id (GtkSocket *socket)
   g_return_val_if_fail (GTK_IS_SOCKET (socket), 0);
   g_return_val_if_fail (GTK_WIDGET_ANCHORED (socket), 0);
 
-  if (!GTK_WIDGET_REALIZED (socket))
+  if (!gtk_widget_get_realized (GTK_WIDGET (socket)))
     gtk_widget_realize (GTK_WIDGET (socket));
 
   return _gtk_socket_windowing_get_id (socket);
@@ -336,7 +370,7 @@ gtk_socket_realize (GtkWidget *widget)
   GdkWindowAttr attributes;
   gint attributes_mask;
 
-  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  gtk_widget_set_realized (widget, TRUE);
 
   attributes.window_type = GDK_WINDOW_CHILD;
   attributes.x = widget->allocation.x;
@@ -400,7 +434,7 @@ gtk_socket_unrealize (GtkWidget *widget)
 {
   GtkSocket *socket = GTK_SOCKET (widget);
 
-  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
+  gtk_widget_set_realized (widget, FALSE);
 
   if (socket->plug_widget)
     {
@@ -449,7 +483,7 @@ gtk_socket_size_allocate (GtkWidget     *widget,
   GtkSocket *socket = GTK_SOCKET (widget);
 
   widget->allocation = *allocation;
-  if (GTK_WIDGET_REALIZED (widget))
+  if (gtk_widget_get_realized (widget))
     {
       gdk_window_move_resize (widget->window,
                              allocation->x, allocation->y,
@@ -523,7 +557,7 @@ activate_key (GtkAccelGroup  *accel_group,
 
   if (gdk_event && gdk_event->type == GDK_KEY_PRESS && socket->plug_window)
     {
-      _gtk_socket_windowing_send_key_event (socket, gdk_event, TRUE);
+      _gtk_socket_windowing_send_key_event (socket, gdk_event, FALSE);
       retval = TRUE;
     }
 
@@ -612,7 +646,7 @@ socket_update_focus_in (GtkSocket *socket)
     {
       GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
 
-      if (GTK_WIDGET_TOPLEVEL (toplevel) &&
+      if (gtk_widget_is_toplevel (toplevel) &&
          GTK_WINDOW (toplevel)->has_toplevel_focus &&
          gtk_widget_is_focus (GTK_WIDGET (socket)))
        focus_in = TRUE;
@@ -635,7 +669,7 @@ socket_update_active (GtkSocket *socket)
     {
       GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
 
-      if (GTK_WIDGET_TOPLEVEL (toplevel) &&
+      if (gtk_widget_is_toplevel (toplevel) &&
          GTK_WINDOW (toplevel)->is_active)
        active = TRUE;
     }
@@ -703,7 +737,7 @@ gtk_socket_key_event (GtkWidget   *widget,
 {
   GtkSocket *socket = GTK_SOCKET (widget);
   
-  if (GTK_WIDGET_HAS_FOCUS (socket) && socket->plug_window && !socket->plug_widget)
+  if (gtk_widget_has_focus (widget) && socket->plug_window && !socket->plug_widget)
     {
       _gtk_socket_windowing_send_key_event (socket, (GdkEvent *) event, FALSE);
 
@@ -734,14 +768,16 @@ void
 _gtk_socket_claim_focus (GtkSocket *socket,
                         gboolean   send_event)
 {
+  GtkWidget *widget = GTK_WIDGET (socket);
+
   if (!send_event)
     socket->focus_in = TRUE;   /* Otherwise, our notify handler will send FOCUS_IN  */
       
   /* Oh, the trickery... */
   
-  GTK_WIDGET_SET_FLAGS (socket, GTK_CAN_FOCUS);
-  gtk_widget_grab_focus (GTK_WIDGET (socket));
-  GTK_WIDGET_UNSET_FLAGS (socket, GTK_CAN_FOCUS);
+  gtk_widget_set_can_focus (widget, TRUE);
+  gtk_widget_grab_focus (widget);
+  gtk_widget_set_can_focus (widget, FALSE);
 }
 
 static gboolean
@@ -952,6 +988,7 @@ _gtk_socket_advance_toplevel_focus (GtkSocket        *socket,
   GtkBin *bin;
   GtkWindow *window;
   GtkContainer *container;
+  GtkWidget *child;
   GtkWidget *toplevel;
   GtkWidget *old_focus_child;
   GtkWidget *parent;
@@ -960,7 +997,7 @@ _gtk_socket_advance_toplevel_focus (GtkSocket        *socket,
   if (!toplevel)
     return;
 
-  if (!GTK_WIDGET_TOPLEVEL (toplevel) || GTK_IS_PLUG (toplevel))
+  if (!gtk_widget_is_toplevel (toplevel) || GTK_IS_PLUG (toplevel))
     {
       gtk_widget_child_focus (toplevel,direction);
       return;
@@ -973,7 +1010,7 @@ _gtk_socket_advance_toplevel_focus (GtkSocket        *socket,
   /* This is a copy of gtk_window_focus(), modified so that we
    * can detect wrap-around.
    */
-  old_focus_child = container->focus_child;
+  old_focus_child = gtk_container_get_focus_child (container);
   
   if (old_focus_child)
     {
@@ -1003,72 +1040,10 @@ _gtk_socket_advance_toplevel_focus (GtkSocket        *socket,
     }
 
   /* Now try to focus the first widget in the window */
-  if (bin->child)
+  child = gtk_bin_get_child (bin);
+  if (child)
     {
-      if (gtk_widget_child_focus (bin->child, direction))
+      if (gtk_widget_child_focus (child, direction))
         return;
     }
 }
-
-static void
-gtk_socket_extended_layout_get_desired_size (GtkExtendedLayout *layout,
-                                             GtkRequisition    *minimal_size,
-                                             GtkRequisition    *desired_size)
-{
-  GtkSocket *socket = GTK_SOCKET (layout);
-  GtkSocketPrivate *priv;
-
-  if (socket->plug_widget)
-    {
-      gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (socket->plug_widget),
-                                                                 minimal_size,
-                                                                 desired_size); 
-    }
-  else
-    {
-      priv = _gtk_socket_get_private (socket);
-
-      if (socket->is_mapped && !priv->have_natural_size && socket->plug_window)
-        {
-           _gtk_socket_windowing_size_request (socket);
-           _gtk_socket_windowing_get_natural_size (socket);
-        }
-
-      if (socket->is_mapped && priv->have_natural_size)
-       {
-          if (minimal_size)
-            {
-              minimal_size->width = MAX (socket->request_width, 1);
-              minimal_size->height = MAX (socket->request_height, 1);
-            }
-          if (desired_size)
-            {
-              desired_size->width = MAX (priv->natural_width, 1);
-              desired_size->height = MAX (priv->natural_height, 1);
-            }
-        }
-      else
-       {
-          if (minimal_size)
-            {
-              minimal_size->width = 1;
-              minimal_size->height = 1;
-            }
-          if (desired_size)
-            {
-              desired_size->width = 1;
-              desired_size->height = 1;
-            }
-        }
-    }
-}
-
-static void
-gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
-{
-  iface->get_desired_size = gtk_socket_extended_layout_get_desired_size;
-}
-
-
-#define __GTK_SOCKET_C__
-#include "gtkaliasdef.c"