#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 */
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 */
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)
static void
gtk_socket_init (GtkSocket *socket)
{
- GtkSocketPrivate *priv;
-
socket->request_width = 0;
socket->request_height = 0;
socket->current_width = 0;
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;
}
/**
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
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;
}
GtkBin *bin;
GtkWindow *window;
GtkContainer *container;
+ GtkWidget *child;
GtkWidget *toplevel;
GtkWidget *old_focus_child;
GtkWidget *parent;
/* 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)
{
}
/* 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"