1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* By Owen Taylor <otaylor@gtk.org> 98/4/4 */
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include "gdk/gdkkeysyms.h"
33 #include "gtkmarshalers.h"
34 #include "gtkwindow.h"
36 #include "gtkprivate.h"
37 #include "gtksocket.h"
38 #include "gtksocketprivate.h"
44 /* Forward declararations */
46 static void gtk_socket_class_init (GtkSocketClass *klass);
47 static void gtk_socket_init (GtkSocket *socket);
48 static void gtk_socket_finalize (GObject *object);
49 static void gtk_socket_notify (GObject *object,
51 static void gtk_socket_realize (GtkWidget *widget);
52 static void gtk_socket_unrealize (GtkWidget *widget);
53 static void gtk_socket_size_request (GtkWidget *widget,
54 GtkRequisition *requisition);
55 static void gtk_socket_size_allocate (GtkWidget *widget,
56 GtkAllocation *allocation);
57 static void gtk_socket_hierarchy_changed (GtkWidget *widget,
58 GtkWidget *old_toplevel);
59 static void gtk_socket_grab_notify (GtkWidget *widget,
60 gboolean was_grabbed);
61 static gboolean gtk_socket_key_event (GtkWidget *widget,
63 static gboolean gtk_socket_focus (GtkWidget *widget,
64 GtkDirectionType direction);
65 static void gtk_socket_remove (GtkContainer *container,
67 static void gtk_socket_forall (GtkContainer *container,
68 gboolean include_internals,
70 gpointer callback_data);
78 GdkModifierType accel_mods;
87 static guint socket_signals[LAST_SIGNAL] = { 0 };
89 static GtkWidgetClass *parent_class = NULL;
92 * _gtk_socket_get_private:
94 * @socket: a #GtkSocket
96 * Returns the private data associated with a GtkSocket, creating it
100 _gtk_socket_get_private (GtkSocket *socket)
102 return G_TYPE_INSTANCE_GET_PRIVATE (socket, GTK_TYPE_SOCKET, GtkSocketPrivate);
106 gtk_socket_get_type (void)
108 static GType socket_type = 0;
112 static const GTypeInfo socket_info =
114 sizeof (GtkSocketClass),
115 NULL, /* base_init */
116 NULL, /* base_finalize */
117 (GClassInitFunc) gtk_socket_class_init,
118 NULL, /* class_finalize */
119 NULL, /* class_data */
121 16, /* n_preallocs */
122 (GInstanceInitFunc) gtk_socket_init,
125 socket_type = g_type_register_static (GTK_TYPE_CONTAINER, I_("GtkSocket"),
133 gtk_socket_finalize (GObject *object)
135 GtkSocket *socket = GTK_SOCKET (object);
137 g_object_unref (socket->accel_group);
138 socket->accel_group = NULL;
140 G_OBJECT_CLASS (parent_class)->finalize (object);
144 gtk_socket_class_init (GtkSocketClass *class)
146 GtkWidgetClass *widget_class;
147 GtkContainerClass *container_class;
148 GObjectClass *gobject_class;
150 gobject_class = (GObjectClass *) class;
151 widget_class = (GtkWidgetClass*) class;
152 container_class = (GtkContainerClass*) class;
154 parent_class = g_type_class_peek_parent (class);
156 gobject_class->finalize = gtk_socket_finalize;
157 gobject_class->notify = gtk_socket_notify;
159 widget_class->realize = gtk_socket_realize;
160 widget_class->unrealize = gtk_socket_unrealize;
161 widget_class->size_request = gtk_socket_size_request;
162 widget_class->size_allocate = gtk_socket_size_allocate;
163 widget_class->hierarchy_changed = gtk_socket_hierarchy_changed;
164 widget_class->grab_notify = gtk_socket_grab_notify;
165 widget_class->key_press_event = gtk_socket_key_event;
166 widget_class->key_release_event = gtk_socket_key_event;
167 widget_class->focus = gtk_socket_focus;
169 /* We don't want to show_all/hide_all the in-process
172 widget_class->show_all = gtk_widget_show;
173 widget_class->hide_all = gtk_widget_hide;
175 container_class->remove = gtk_socket_remove;
176 container_class->forall = gtk_socket_forall;
178 socket_signals[PLUG_ADDED] =
179 g_signal_new (I_("plug_added"),
180 G_OBJECT_CLASS_TYPE (class),
182 G_STRUCT_OFFSET (GtkSocketClass, plug_added),
184 _gtk_marshal_VOID__VOID,
186 socket_signals[PLUG_REMOVED] =
187 g_signal_new (I_("plug_removed"),
188 G_OBJECT_CLASS_TYPE (class),
190 G_STRUCT_OFFSET (GtkSocketClass, plug_removed),
191 _gtk_boolean_handled_accumulator, NULL,
192 _gtk_marshal_BOOLEAN__VOID,
195 g_type_class_add_private (gobject_class, sizeof (GtkSocketPrivate));
199 gtk_socket_init (GtkSocket *socket)
201 socket->request_width = 0;
202 socket->request_height = 0;
203 socket->current_width = 0;
204 socket->current_height = 0;
206 socket->plug_window = NULL;
207 socket->plug_widget = NULL;
208 socket->focus_in = FALSE;
209 socket->have_size = FALSE;
210 socket->need_map = FALSE;
211 socket->active = FALSE;
213 socket->accel_group = gtk_accel_group_new ();
214 g_object_set_data (G_OBJECT (socket->accel_group), I_("gtk-socket"), socket);
220 * Create a new empty #GtkSocket.
222 * Return value: the new #GtkSocket.
225 gtk_socket_new (void)
229 socket = g_object_new (GTK_TYPE_SOCKET, NULL);
231 return GTK_WIDGET (socket);
236 * @socket_: a #GtkSocket
237 * @wid: the window ID of an existing toplevel window.
239 * Reparents a pre-existing toplevel window into a #GtkSocket. This is
240 * meant to embed clients that do not know about embedding into a
241 * #GtkSocket, however doing so is inherently unreliable, and using
242 * this function is not recommended.
244 * The #GtkSocket must have already be added into a toplevel window
245 * before you can make this call.
248 gtk_socket_steal (GtkSocket *socket,
251 g_return_if_fail (GTK_IS_SOCKET (socket));
252 g_return_if_fail (GTK_WIDGET_ANCHORED (socket));
254 if (!GTK_WIDGET_REALIZED (socket))
255 gtk_widget_realize (GTK_WIDGET (socket));
257 _gtk_socket_add_window (socket, wid, TRUE);
262 * @socket_: a #GtkSocket
263 * @window_id: the window ID of a client participating in the XEMBED protocol.
265 * Adds an XEMBED client, such as a #GtkPlug, to the #GtkSocket. The
266 * client may be in the same process or in a different process.
268 * To embed a #GtkPlug in a #GtkSocket, you can either create the
269 * #GtkPlug with <literal>gtk_plug_new (0)</literal>, call
270 * gtk_plug_get_id() to get the window ID of the plug, and then pass that to the
271 * gtk_socket_add_id(), or you can call gtk_socket_get_id() to get the
272 * window ID for the socket, and call gtk_plug_new() passing in that
275 * The #GtkSocket must have already be added into a toplevel window
276 * before you can make this call.
279 gtk_socket_add_id (GtkSocket *socket,
280 GdkNativeWindow window_id)
282 g_return_if_fail (GTK_IS_SOCKET (socket));
283 g_return_if_fail (GTK_WIDGET_ANCHORED (socket));
285 if (!GTK_WIDGET_REALIZED (socket))
286 gtk_widget_realize (GTK_WIDGET (socket));
288 _gtk_socket_add_window (socket, window_id, TRUE);
293 * @socket_: a #GtkSocket.
295 * Gets the window ID of a #GtkSocket widget, which can then
296 * be used to create a client embedded inside the socket, for
297 * instance with gtk_plug_new().
299 * The #GtkSocket must have already be added into a toplevel window
300 * before you can make this call.
302 * Return value: the window ID for the socket
305 gtk_socket_get_id (GtkSocket *socket)
307 g_return_val_if_fail (GTK_IS_SOCKET (socket), 0);
308 g_return_val_if_fail (GTK_WIDGET_ANCHORED (socket), 0);
310 if (!GTK_WIDGET_REALIZED (socket))
311 gtk_widget_realize (GTK_WIDGET (socket));
313 return _gtk_socket_windowing_get_id (socket);
317 gtk_socket_realize (GtkWidget *widget)
320 GdkWindowAttr attributes;
321 gint attributes_mask;
323 g_return_if_fail (GTK_IS_SOCKET (widget));
325 socket = GTK_SOCKET (widget);
326 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
328 attributes.window_type = GDK_WINDOW_CHILD;
329 attributes.x = widget->allocation.x;
330 attributes.y = widget->allocation.y;
331 attributes.width = widget->allocation.width;
332 attributes.height = widget->allocation.height;
333 attributes.wclass = GDK_INPUT_OUTPUT;
334 attributes.visual = gtk_widget_get_visual (widget);
335 attributes.colormap = gtk_widget_get_colormap (widget);
336 attributes.event_mask = GDK_FOCUS_CHANGE_MASK;
338 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
340 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
341 &attributes, attributes_mask);
342 gdk_window_set_user_data (widget->window, socket);
344 widget->style = gtk_style_attach (widget->style, widget->window);
345 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
347 _gtk_socket_windowing_realize_window (socket);
349 gdk_window_add_filter (widget->window,
350 _gtk_socket_windowing_filter_func,
353 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
355 /* We sync here so that we make sure that if the XID for
356 * our window is passed to another application, SubstructureRedirectMask
357 * will be set by the time the other app creates its window.
359 gdk_display_sync (gtk_widget_get_display (widget));
363 * _gtk_socket_end_embedding:
365 * @socket: a #GtkSocket
367 * Called to end the embedding of a plug in the socket.
370 _gtk_socket_end_embedding (GtkSocket *socket)
372 GtkSocketPrivate *private = _gtk_socket_get_private (socket);
373 GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
376 if (toplevel && GTK_IS_WINDOW (toplevel))
377 _gtk_socket_windowing_end_embedding_toplevel (socket);
379 g_object_unref (socket->plug_window);
380 socket->plug_window = NULL;
381 socket->current_width = 0;
382 socket->current_height = 0;
383 private->resize_count = 0;
385 /* Remove from end to avoid indexes shifting. This is evil */
386 for (i = socket->accel_group->n_accels - 1; i >= 0; i--)
388 GtkAccelGroupEntry *accel_entry = &socket->accel_group->priv_accels[i];
389 gtk_accel_group_disconnect (socket->accel_group, accel_entry->closure);
394 gtk_socket_unrealize (GtkWidget *widget)
396 GtkSocket *socket = GTK_SOCKET (widget);
398 GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
400 if (socket->plug_widget)
402 _gtk_plug_remove_from_socket (GTK_PLUG (socket->plug_widget), socket);
404 else if (socket->plug_window)
406 _gtk_socket_end_embedding (socket);
409 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
410 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
414 gtk_socket_size_request (GtkWidget *widget,
415 GtkRequisition *requisition)
417 GtkSocket *socket = GTK_SOCKET (widget);
419 if (socket->plug_widget)
421 gtk_widget_size_request (socket->plug_widget, requisition);
425 if (socket->is_mapped && !socket->have_size && socket->plug_window)
426 _gtk_socket_windowing_size_request (socket);
428 if (socket->is_mapped && socket->have_size)
430 requisition->width = MAX (socket->request_width, 1);
431 requisition->height = MAX (socket->request_height, 1);
435 requisition->width = 1;
436 requisition->height = 1;
442 gtk_socket_size_allocate (GtkWidget *widget,
443 GtkAllocation *allocation)
447 g_return_if_fail (GTK_IS_SOCKET (widget));
448 g_return_if_fail (allocation != NULL);
450 socket = GTK_SOCKET (widget);
452 widget->allocation = *allocation;
453 if (GTK_WIDGET_REALIZED (widget))
455 gdk_window_move_resize (widget->window,
456 allocation->x, allocation->y,
457 allocation->width, allocation->height);
459 if (socket->plug_widget)
461 GtkAllocation child_allocation;
463 child_allocation.x = 0;
464 child_allocation.y = 0;
465 child_allocation.width = allocation->width;
466 child_allocation.height = allocation->height;
468 gtk_widget_size_allocate (socket->plug_widget, &child_allocation);
470 else if (socket->plug_window)
472 GtkSocketPrivate *private = _gtk_socket_get_private (socket);
474 gdk_error_trap_push ();
476 if (allocation->width != socket->current_width ||
477 allocation->height != socket->current_height)
479 gdk_window_move_resize (socket->plug_window,
481 allocation->width, allocation->height);
482 if (private->resize_count)
483 private->resize_count--;
485 GTK_NOTE (PLUGSOCKET,
486 g_message ("GtkSocket - allocated: %d %d",
487 allocation->width, allocation->height));
488 socket->current_width = allocation->width;
489 socket->current_height = allocation->height;
492 if (socket->need_map)
494 gdk_window_show (socket->plug_window);
495 socket->need_map = FALSE;
498 while (private->resize_count)
500 _gtk_socket_windowing_send_configure_event (socket);
501 private->resize_count--;
502 GTK_NOTE (PLUGSOCKET,
503 g_message ("GtkSocket - sending synthetic configure: %d %d",
504 allocation->width, allocation->height));
507 gdk_display_sync (gtk_widget_get_display (widget));
508 gdk_error_trap_pop ();
514 activate_key (GtkAccelGroup *accel_group,
515 GObject *acceleratable,
517 GdkModifierType accel_mods,
518 GrabbedKey *grabbed_key)
520 GdkEvent *gdk_event = gtk_get_current_event ();
522 GtkSocket *socket = g_object_get_data (G_OBJECT (accel_group), "gtk-socket");
523 gboolean retval = FALSE;
525 if (gdk_event && gdk_event->type == GDK_KEY_PRESS && socket->plug_window)
527 _gtk_socket_windowing_send_key_event (socket, gdk_event, TRUE);
532 gdk_event_free (gdk_event);
538 find_accel_key (GtkAccelKey *key,
542 GrabbedKey *grabbed_key = data;
544 return (key->accel_key == grabbed_key->accel_key &&
545 key->accel_mods == grabbed_key->accel_mods);
549 * _gtk_socket_add_grabbed_key:
551 * @socket: a #GtkSocket
553 * @modifiers: modifiers for the key
555 * Called from the GtkSocket platform-specific backend when the
556 * corresponding plug has told the socket to grab a key.
559 _gtk_socket_add_grabbed_key (GtkSocket *socket,
561 GdkModifierType modifiers)
564 GrabbedKey *grabbed_key;
566 grabbed_key = g_new (GrabbedKey, 1);
568 grabbed_key->accel_key = keyval;
569 grabbed_key->accel_mods = modifiers;
571 if (gtk_accel_group_find (socket->accel_group,
575 g_warning ("GtkSocket: request to add already present grabbed key %u,%#x\n",
577 g_free (grabbed_key);
581 closure = g_cclosure_new (G_CALLBACK (activate_key), grabbed_key, (GClosureNotify)g_free);
583 gtk_accel_group_connect (socket->accel_group, keyval, modifiers, GTK_ACCEL_LOCKED,
588 * _gtk_socket_remove_grabbed_key:
590 * @socket: a #GtkSocket
592 * @modifiers: modifiers for the key
594 * Called from the GtkSocket backend when the corresponding plug has
595 * told the socket to remove a key grab.
598 _gtk_socket_remove_grabbed_key (GtkSocket *socket,
600 GdkModifierType modifiers)
604 for (i = 0; i < socket->accel_group->n_accels; i++)
606 GtkAccelGroupEntry *accel_entry = &socket->accel_group->priv_accels[i];
607 if (accel_entry->key.accel_key == keyval &&
608 accel_entry->key.accel_mods == modifiers)
610 gtk_accel_group_disconnect (socket->accel_group,
611 accel_entry->closure);
616 g_warning ("GtkSocket: request to remove non-present grabbed key %u,%#x\n",
621 socket_update_focus_in (GtkSocket *socket)
623 gboolean focus_in = FALSE;
625 if (socket->plug_window)
627 GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
629 if (GTK_WIDGET_TOPLEVEL (toplevel) &&
630 GTK_WINDOW (toplevel)->has_toplevel_focus &&
631 gtk_widget_is_focus (GTK_WIDGET (socket)))
635 if (focus_in != socket->focus_in)
637 socket->focus_in = focus_in;
639 _gtk_socket_windowing_focus_change (socket, focus_in);
644 socket_update_active (GtkSocket *socket)
646 gboolean active = FALSE;
648 if (socket->plug_window)
650 GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
652 if (GTK_WIDGET_TOPLEVEL (toplevel) &&
653 GTK_WINDOW (toplevel)->is_active)
657 if (active != socket->active)
659 socket->active = active;
661 _gtk_socket_windowing_update_active (socket, active);
666 gtk_socket_hierarchy_changed (GtkWidget *widget,
667 GtkWidget *old_toplevel)
669 GtkSocket *socket = GTK_SOCKET (widget);
670 GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
672 if (toplevel && !GTK_IS_WINDOW (toplevel))
675 if (toplevel != socket->toplevel)
677 if (socket->toplevel)
679 gtk_window_remove_accel_group (GTK_WINDOW (socket->toplevel), socket->accel_group);
680 g_signal_handlers_disconnect_by_func (socket->toplevel,
681 socket_update_focus_in,
683 g_signal_handlers_disconnect_by_func (socket->toplevel,
684 socket_update_active,
688 socket->toplevel = toplevel;
692 gtk_window_add_accel_group (GTK_WINDOW (socket->toplevel), socket->accel_group);
693 g_signal_connect_swapped (socket->toplevel, "notify::has-toplevel-focus",
694 G_CALLBACK (socket_update_focus_in), socket);
695 g_signal_connect_swapped (socket->toplevel, "notify::is-active",
696 G_CALLBACK (socket_update_active), socket);
699 socket_update_focus_in (socket);
700 socket_update_active (socket);
705 gtk_socket_grab_notify (GtkWidget *widget,
706 gboolean was_grabbed)
708 GtkSocket *socket = GTK_SOCKET (widget);
710 if (!socket->same_app)
711 _gtk_socket_windowing_update_modality (socket, !was_grabbed);
715 gtk_socket_key_event (GtkWidget *widget,
718 GtkSocket *socket = GTK_SOCKET (widget);
720 if (GTK_WIDGET_HAS_FOCUS (socket) && socket->plug_window && !socket->plug_widget)
722 _gtk_socket_windowing_send_key_event (socket, (GdkEvent *) event, FALSE);
731 gtk_socket_notify (GObject *object,
734 if (!strcmp (pspec->name, "is-focus"))
736 socket_update_focus_in (GTK_SOCKET (object));
740 * _gtk_socket_claim_focus:
742 * @socket: a #GtkSocket
745 * Claims focus for the socket. XXX send_event?
748 _gtk_socket_claim_focus (GtkSocket *socket,
752 socket->focus_in = TRUE; /* Otherwise, our notify handler will send FOCUS_IN */
754 /* Oh, the trickery... */
756 GTK_WIDGET_SET_FLAGS (socket, GTK_CAN_FOCUS);
757 gtk_widget_grab_focus (GTK_WIDGET (socket));
758 GTK_WIDGET_UNSET_FLAGS (socket, GTK_CAN_FOCUS);
762 gtk_socket_focus (GtkWidget *widget,
763 GtkDirectionType direction)
767 g_return_val_if_fail (GTK_IS_SOCKET (widget), FALSE);
769 socket = GTK_SOCKET (widget);
771 if (socket->plug_widget)
772 return gtk_widget_child_focus (socket->plug_widget, direction);
774 if (!gtk_widget_is_focus (widget))
776 _gtk_socket_windowing_focus (socket, direction);
777 _gtk_socket_claim_focus (socket, FALSE);
786 gtk_socket_remove (GtkContainer *container,
789 GtkSocket *socket = GTK_SOCKET (container);
791 g_return_if_fail (child == socket->plug_widget);
793 _gtk_plug_remove_from_socket (GTK_PLUG (socket->plug_widget), socket);
797 gtk_socket_forall (GtkContainer *container,
798 gboolean include_internals,
799 GtkCallback callback,
800 gpointer callback_data)
802 GtkSocket *socket = GTK_SOCKET (container);
804 if (socket->plug_widget)
805 (* callback) (socket->plug_widget, callback_data);
809 * _gtk_socket_add_window:
811 * @socket: a #GtkSocket
812 * @xid: the native identifier for a window
813 * @need_reparent: whether the socket's plug's window needs to be
814 * reparented to the socket
816 * Adds a window to a GtkSocket.
819 _gtk_socket_add_window (GtkSocket *socket,
821 gboolean need_reparent)
823 GtkWidget *widget = GTK_WIDGET (socket);
824 GdkDisplay *display = gtk_widget_get_display (widget);
825 gpointer user_data = NULL;
827 socket->plug_window = gdk_window_lookup_for_display (display, xid);
829 if (socket->plug_window)
831 g_object_ref (socket->plug_window);
832 gdk_window_get_user_data (socket->plug_window, &user_data);
835 if (user_data) /* A widget's window in this process */
837 GtkWidget *child_widget = user_data;
839 if (!GTK_IS_PLUG (child_widget))
841 g_warning (G_STRLOC ": Can't add non-GtkPlug to GtkSocket");
842 socket->plug_window = NULL;
843 gdk_error_trap_pop ();
848 _gtk_plug_add_to_socket (GTK_PLUG (child_widget), socket);
850 else /* A foreign window */
853 GdkDragProtocol protocol;
855 gdk_error_trap_push ();
857 if (!socket->plug_window)
859 socket->plug_window = gdk_window_foreign_new_for_display (display, xid);
860 if (!socket->plug_window) /* was deleted before we could get it */
862 gdk_error_trap_pop ();
867 _gtk_socket_windowing_select_plug_window_input (socket);
869 if (gdk_error_trap_pop ())
871 g_object_unref (socket->plug_window);
872 socket->plug_window = NULL;
876 /* OK, we now will reliably get destroy notification on socket->plug_window */
878 gdk_error_trap_push ();
882 gdk_window_hide (socket->plug_window); /* Shouldn't actually be necessary for XEMBED, but just in case */
883 gdk_window_reparent (socket->plug_window, widget->window, 0, 0);
886 socket->have_size = FALSE;
888 _gtk_socket_windowing_embed_get_info (socket);
890 socket->need_map = socket->is_mapped;
892 if (gdk_drag_get_protocol_for_display (display, xid, &protocol))
893 gtk_drag_dest_set_proxy (GTK_WIDGET (socket), socket->plug_window,
896 gdk_display_sync (display);
897 gdk_error_trap_pop ();
899 gdk_window_add_filter (socket->plug_window,
900 _gtk_socket_windowing_filter_func,
903 /* Add a pointer to the socket on our toplevel window */
905 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
906 if (toplevel && GTK_IS_WINDOW (toplevel))
907 gtk_window_add_embedded_xid (GTK_WINDOW (toplevel), xid);
909 _gtk_socket_windowing_embed_notify (socket);
911 socket_update_active (socket);
912 socket_update_focus_in (socket);
914 gtk_widget_queue_resize (GTK_WIDGET (socket));
917 if (socket->plug_window)
918 g_signal_emit (socket, socket_signals[PLUG_ADDED], 0);
922 * _gtk_socket_handle_map_request:
924 * @socket: a #GtkSocket
926 * Called from the GtkSocket backend when the plug has been mapped.
929 _gtk_socket_handle_map_request (GtkSocket *socket)
931 if (!socket->is_mapped)
933 socket->is_mapped = TRUE;
934 socket->need_map = TRUE;
936 gtk_widget_queue_resize (GTK_WIDGET (socket));
941 * _gtk_socket_unmap_notify:
943 * @socket: a #GtkSocket
945 * Called from the GtkSocket backend when the plug has been unmapped ???
948 _gtk_socket_unmap_notify (GtkSocket *socket)
950 if (socket->is_mapped)
952 socket->is_mapped = FALSE;
953 gtk_widget_queue_resize (GTK_WIDGET (socket));
958 * _gtk_socket_advance_toplevel_focus:
960 * @socket: a #GtkSocket
961 * @direction: a direction
963 * Called from the GtkSocket backend when the corresponding plug
964 * has told the socket to move the focus.
967 _gtk_socket_advance_toplevel_focus (GtkSocket *socket,
968 GtkDirectionType direction)
972 GtkContainer *container;
974 GtkWidget *old_focus_child;
977 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
981 if (!GTK_WIDGET_TOPLEVEL (toplevel) || GTK_IS_PLUG (toplevel))
983 gtk_widget_child_focus (toplevel,direction);
987 container = GTK_CONTAINER (toplevel);
988 window = GTK_WINDOW (toplevel);
989 bin = GTK_BIN (toplevel);
991 /* This is a copy of gtk_window_focus(), modified so that we
992 * can detect wrap-around.
994 old_focus_child = container->focus_child;
998 if (gtk_widget_child_focus (old_focus_child, direction))
1001 /* We are allowed exactly one wrap-around per sequence of focus
1004 if (_gtk_socket_windowing_embed_get_focus_wrapped ())
1007 _gtk_socket_windowing_embed_set_focus_wrapped ();
1010 if (window->focus_widget)
1012 /* Wrapped off the end, clear the focus setting for the toplevel */
1013 parent = window->focus_widget->parent;
1016 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
1017 parent = GTK_WIDGET (parent)->parent;
1020 gtk_window_set_focus (GTK_WINDOW (container), NULL);
1023 /* Now try to focus the first widget in the window */
1026 if (gtk_widget_child_focus (bin->child, direction))
1031 #define __GTK_SOCKET_C__
1032 #include "gtkaliasdef.c"