#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_interface_init (GtkExtendedLayoutIface *iface);
/* 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_interface_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_REALIZED (socket))
- gtk_widget_realize (GTK_WIDGET (socket));
-
- _gtk_socket_add_window (socket, wid, TRUE);
-}
-
/**
* gtk_socket_add_id:
* @socket_: a #GtkSocket
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);
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);
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;
{
GtkSocket *socket = GTK_SOCKET (widget);
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
+ gtk_widget_set_realized (widget, FALSE);
if (socket->plug_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,
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;
}
{
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;
{
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;
}
{
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);
_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
GtkBin *bin;
GtkWindow *window;
GtkContainer *container;
+ GtkWidget *child;
GtkWidget *toplevel;
GtkWidget *old_focus_child;
GtkWidget *parent;
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;
/* 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_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"