]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtksocket.c
Add _gtk_toggle_action_set_active() internal function
[~andy/gtk] / gtk / gtksocket.c
index e64f30801117a4e73513de1f33d61646a41ff40a..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,13 +137,6 @@ static void     gtk_socket_forall               (GtkContainer     *container,
                                                 GtkCallback       callback,
                                                 gpointer          callback_data);
 
-static void gtk_socket_extended_layout_init     (GtkExtendedLayoutIface *iface);
-static void gtk_socket_get_desired_width        (GtkExtendedLayout      *layout,
-                                                gint                   *minimum_size,
-                                                gint                   *natural_size);
-static void gtk_socket_get_desired_height       (GtkExtendedLayout      *layout,
-                                                gint                   *minimum_size,
-                                                gint                   *natural_size);
 
 /* Local data */
 
@@ -106,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_init))
-
+G_DEFINE_TYPE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER)
 
 static void
 gtk_socket_finalize (GObject *object)
@@ -196,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;
@@ -212,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;
 }
 
 /**
@@ -234,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_get_realized (GTK_WIDGET (socket)))
-    gtk_widget_realize (GTK_WIDGET (socket));
-
-  _gtk_socket_add_window (socket, wid, TRUE);
-}
-
 /**
  * gtk_socket_add_id:
  * @socket_: a #GtkSocket
@@ -529,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;
     }
 
@@ -960,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;
@@ -981,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)
     {
@@ -1011,90 +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_init (GtkExtendedLayoutIface *iface)
-{
-  iface->get_desired_width  = gtk_socket_get_desired_width;
-  iface->get_desired_height = gtk_socket_get_desired_height;
-}
-
-static void
-gtk_socket_get_desired_size (GtkExtendedLayout *layout,
-                            GtkOrientation     orientation,
-                            gint              *minimum_size,
-                            gint              *natural_size)
-{
-  GtkSocket *socket = GTK_SOCKET (layout);
-  GtkSocketPrivate *priv;
-
-  if (socket->plug_widget)
-    {
-      if (orientation == GTK_ORIENTATION_HORIZONTAL)
-       gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (socket->plug_widget),
-                                              minimum_size, natural_size); 
-      else
-       gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (socket->plug_widget),
-                                               minimum_size, natural_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 (minimum_size)
-            {
-              *minimum_size = 
-               (orientation == GTK_ORIENTATION_HORIZONTAL) ? 
-               MAX (socket->request_width, 1) : MAX (socket->request_height, 1);
-            }
-          if (natural_size)
-            {
-              *natural_size = 
-               (orientation == GTK_ORIENTATION_HORIZONTAL) ? 
-               MAX (priv->natural_width, 1) : MAX (priv->natural_height, 1);
-            }
-        }
-      else
-       {
-          if (minimum_size)
-           *minimum_size = 1;
-         
-          if (natural_size)
-           *natural_size = 1;
-        }
-    }
-}
-
-static void
-gtk_socket_get_desired_width (GtkExtendedLayout *layout,
-                             gint              *minimum_size,
-                             gint              *natural_size)
-{
-  gtk_socket_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
-}
-
-static void
-gtk_socket_get_desired_height (GtkExtendedLayout *layout,
-                              gint              *minimum_size,
-                              gint              *natural_size)
-{
-  gtk_socket_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
-}
-
-
-#define __GTK_SOCKET_C__
-#include "gtkaliasdef.c"