X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkwidget.c;h=4ee58865acef0e9c9397cda606d87b1e0322c50a;hb=aa787c9dd17c9dbee97c76209e62284cd836fdea;hp=ca61f04a20f7903a3c199c10884dcc77837e7730;hpb=d7dc12d30117374df300102052350085fe70d132;p=~andy%2Fgtk diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index ca61f04a2..4ee58865a 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -25,31 +25,31 @@ */ #include "config.h" + #include #include #include + +#include +#include +#include + #include "gtkcontainer.h" #include "gtkaccelmap.h" #include "gtkclipboard.h" #include "gtkiconfactory.h" #include "gtkintl.h" -#include "gtkmain.h" +#include "gtkmainprivate.h" #include "gtkmarshalers.h" #include "gtkrc.h" #include "gtkselection.h" -#include "gtksettings.h" +#include "gtksettingsprivate.h" #include "gtksizegroup-private.h" #include "gtkwidget.h" #include "gtkwidgetprivate.h" #include "gtkwindowprivate.h" #include "gtkbindings.h" #include "gtkprivate.h" -#include "gdk/gdk.h" -#include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */ -#include -#include -#include -#include "gdk/gdkkeysyms.h" #include "gtkaccessible.h" #include "gtktooltip.h" #include "gtkinvisible.h" @@ -63,6 +63,7 @@ #include "gtkmodifierstyle.h" #include "gtkversion.h" #include "gtkdebug.h" +#include "gtktypebuiltins.h" /** @@ -313,7 +314,7 @@ struct _GtkWidgetPrivate guint has_grab : 1; guint shadowed : 1; guint rc_style : 1; - guint user_style : 1; + guint style_update_pending : 1; guint app_paintable : 1; guint double_buffered : 1; guint redraw_on_alloc : 1; @@ -369,6 +370,11 @@ struct _GtkWidgetPrivate */ GtkWidget *parent; +#ifdef G_ENABLE_DEBUG + /* Number of gtk_widget_push_verify_invariants () */ + guint verifying_invariants_count; +#endif /* G_ENABLE_DEBUG */ + /* Widget's path for styling */ GtkWidgetPath *path; }; @@ -556,14 +562,20 @@ static void gtk_widget_real_move_focus (GtkWidget GtkDirectionType direction); static gboolean gtk_widget_real_keynav_failed (GtkWidget *widget, GtkDirectionType direction); +#ifdef G_ENABLE_DEBUG +static void gtk_widget_verify_invariants (GtkWidget *widget); +static void gtk_widget_push_verify_invariants (GtkWidget *widget); +static void gtk_widget_pop_verify_invariants (GtkWidget *widget); +#else +#define gtk_widget_verify_invariants(widget) +#define gtk_widget_push_verify_invariants(widget) +#define gtk_widget_pop_verify_invariants(widget) +#endif static PangoContext* gtk_widget_peek_pango_context (GtkWidget *widget); static void gtk_widget_update_pango_context (GtkWidget *widget); static void gtk_widget_propagate_state (GtkWidget *widget, GtkStateData *data); -static void gtk_widget_reset_rc_style (GtkWidget *widget); -static void gtk_widget_set_style_internal (GtkWidget *widget, - GtkStyle *style, - gboolean initial_emission); +; static gint gtk_widget_event_internal (GtkWidget *widget, GdkEvent *event); static gboolean gtk_widget_real_mnemonic_activate (GtkWidget *widget, @@ -2150,13 +2162,9 @@ gtk_widget_class_init (GtkWidgetClass *klass) * @widget: the object which received the signal * @event: (type Gdk.EventAny): the #GdkEventAny which triggered this signal * - * The ::unmap-event signal may be emitted when the @widget's window is + * The ::unmap-event signal will be emitted when the @widget's window is * unmapped. A window is unmapped when it becomes invisible on the screen. * - * For performance reasons GTK+ may not emit ::unmap-event, so one - * should always also implement ::unrealize in order to release - * resources and disconnect signal handlers. - * * To receive this signal, the #GdkWindow associated to the widget needs * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask * automatically for all new windows. @@ -2449,7 +2457,8 @@ gtk_widget_class_init (GtkWidgetClass *klass) g_signal_new (I_("drag-failed"), G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - 0, _gtk_boolean_handled_accumulator, NULL, + G_STRUCT_OFFSET (GtkWidgetClass, drag_failed), + _gtk_boolean_handled_accumulator, NULL, _gtk_marshal_BOOLEAN__OBJECT_ENUM, G_TYPE_BOOLEAN, 2, GDK_TYPE_DRAG_CONTEXT, @@ -3698,8 +3707,9 @@ gtk_widget_unparent (GtkWidget *widget) if (priv->parent == NULL) return; - /* keep this function in sync with gtk_menu_detach() - */ + /* keep this function in sync with gtk_menu_detach() */ + + gtk_widget_push_verify_invariants (widget); g_object_freeze_notify (G_OBJECT (widget)); nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context); @@ -3737,6 +3747,12 @@ gtk_widget_unparent (GtkWidget *widget) gtk_widget_unrealize (widget); } + /* Need to unset the parent window early, this can result in + * an additional "hierarchy-changed" propagation if we are removing + * a parented GtkWindow from the hierarchy. + */ + gtk_widget_set_parent_window (widget, NULL); + /* Removing a widget from a container restores the child visible * flag to the default state, so it doesn't affect the child * in the next parent. @@ -3745,7 +3761,6 @@ gtk_widget_unparent (GtkWidget *widget) old_parent = priv->parent; priv->parent = NULL; - gtk_widget_set_parent_window (widget, NULL); /* parent may no longer expand if the removed * child was expand=TRUE and could therefore @@ -3760,7 +3775,7 @@ gtk_widget_unparent (GtkWidget *widget) } g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent); - if (toplevel) + if (toplevel && gtk_widget_is_toplevel (toplevel)) { _gtk_widget_propagate_hierarchy_changed (widget, toplevel); g_object_unref (toplevel); @@ -3771,6 +3786,8 @@ gtk_widget_unparent (GtkWidget *widget) if (!priv->parent) g_object_notify_queue_clear (G_OBJECT (widget), nqueue); g_object_notify_queue_thaw (G_OBJECT (widget), nqueue); + + gtk_widget_pop_verify_invariants (widget); g_object_unref (widget); } @@ -3852,8 +3869,10 @@ gtk_widget_show (GtkWidget *widget) if (!gtk_widget_get_visible (widget)) { g_object_ref (widget); + gtk_widget_push_verify_invariants (widget); + if (!gtk_widget_is_toplevel (widget)) - gtk_widget_queue_resize (widget); + gtk_widget_queue_resize (widget); /* see comment in set_parent() for why this should and can be * conditional @@ -3868,6 +3887,8 @@ gtk_widget_show (GtkWidget *widget) g_signal_emit (widget, widget_signals[SHOW], 0); g_object_notify (G_OBJECT (widget), "visible"); + + gtk_widget_pop_verify_invariants (widget); g_object_unref (widget); } } @@ -3949,8 +3970,10 @@ gtk_widget_hide (GtkWidget *widget) GtkWidget *toplevel = gtk_widget_get_toplevel (widget); g_object_ref (widget); + gtk_widget_push_verify_invariants (widget); + if (toplevel != widget && gtk_widget_is_toplevel (toplevel)) - _gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget); + _gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget); /* a parent may now be expand=FALSE since we're hidden. */ if (widget->priv->need_compute_expand || @@ -3964,6 +3987,8 @@ gtk_widget_hide (GtkWidget *widget) if (!gtk_widget_is_toplevel (widget)) gtk_widget_queue_resize (widget); g_object_notify (G_OBJECT (widget), "visible"); + + gtk_widget_pop_verify_invariants (widget); g_object_unref (widget); } } @@ -4123,13 +4148,17 @@ gtk_widget_map (GtkWidget *widget) if (!gtk_widget_get_mapped (widget)) { + gtk_widget_push_verify_invariants (widget); + if (!gtk_widget_get_realized (widget)) - gtk_widget_realize (widget); + gtk_widget_realize (widget); g_signal_emit (widget, widget_signals[MAP], 0); if (!gtk_widget_get_has_window (widget)) - gdk_window_invalidate_rect (priv->window, &priv->allocation, FALSE); + gdk_window_invalidate_rect (priv->window, &priv->allocation, FALSE); + + gtk_widget_pop_verify_invariants (widget); _gtk_widget_start_state_transitions (widget); } @@ -4153,10 +4182,14 @@ gtk_widget_unmap (GtkWidget *widget) if (gtk_widget_get_mapped (widget)) { + gtk_widget_push_verify_invariants (widget); + if (!gtk_widget_get_has_window (widget)) gdk_window_invalidate_rect (priv->window, &priv->allocation, FALSE); _gtk_tooltip_hide (widget); g_signal_emit (widget, widget_signals[UNMAP], 0); + + gtk_widget_pop_verify_invariants (widget); } } @@ -4222,6 +4255,8 @@ gtk_widget_realize (GtkWidget *widget) if (!gtk_widget_get_realized (widget)) { + gtk_widget_push_verify_invariants (widget); + /* if (GTK_IS_CONTAINER (widget) && gtk_widget_get_has_window (widget)) g_message ("gtk_widget_realize(%s)", G_OBJECT_TYPE_NAME (widget)); @@ -4238,6 +4273,9 @@ gtk_widget_realize (GtkWidget *widget) gtk_widget_ensure_style (widget); + if (priv->style_update_pending) + g_signal_emit (widget, widget_signals[STYLE_UPDATED], 0); + g_signal_emit (widget, widget_signals[REALIZE], 0); gtk_widget_real_set_has_tooltip (widget, @@ -4258,6 +4296,8 @@ gtk_widget_realize (GtkWidget *widget) gdk_window_set_support_multidevice (priv->window, TRUE); _gtk_widget_enable_device_events (widget); + + gtk_widget_pop_verify_invariants (widget); } } @@ -4274,6 +4314,8 @@ gtk_widget_unrealize (GtkWidget *widget) { g_return_if_fail (GTK_IS_WIDGET (widget)); + gtk_widget_push_verify_invariants (widget); + if (widget->priv->has_shape_mask) gtk_widget_shape_combine_region (widget, NULL); @@ -4283,12 +4325,18 @@ gtk_widget_unrealize (GtkWidget *widget) if (gtk_widget_get_realized (widget)) { g_object_ref (widget); - _gtk_tooltip_hide (widget); + + if (widget->priv->mapped) + gtk_widget_unmap (widget); + g_signal_emit (widget, widget_signals[UNREALIZE], 0); + g_assert (!widget->priv->mapped); gtk_widget_set_realized (widget, FALSE); - gtk_widget_set_mapped (widget, FALSE); + g_object_unref (widget); } + + gtk_widget_pop_verify_invariants (widget); } /***************************************** @@ -4588,6 +4636,8 @@ gtk_widget_size_allocate (GtkWidget *widget, g_return_if_fail (GTK_IS_WIDGET (widget)); + gtk_widget_push_verify_invariants (widget); + #ifdef G_ENABLE_DEBUG if (gtk_get_debug_flags () & GTK_DEBUG_GEOMETRY) { @@ -4687,7 +4737,7 @@ gtk_widget_size_allocate (GtkWidget *widget, old_allocation.y != real_allocation.y); if (!alloc_needed && !size_changed && !position_changed) - return; + goto out; g_signal_emit (widget, widget_signals[SIZE_ALLOCATE], 0, &real_allocation); @@ -4739,6 +4789,9 @@ gtk_widget_size_allocate (GtkWidget *widget, gtk_widget_invalidate_widget_windows (priv->parent, invalidate); cairo_region_destroy (invalidate); } + +out: + gtk_widget_pop_verify_invariants (widget); } /** @@ -6290,9 +6343,29 @@ gtk_widget_real_query_tooltip (GtkWidget *widget, static void gtk_widget_real_style_updated (GtkWidget *widget) { + if (gtk_widget_get_realized (widget)) + { + /* Trigger ::style-set for old + * widgets not listening to this + */ + g_signal_emit (widget, + widget_signals[STYLE_SET], + 0, + widget->priv->style); + } + if (widget->priv->context) - gtk_style_context_invalidate (widget->priv->context); - gtk_widget_queue_resize (widget); + { + gtk_style_context_invalidate (widget->priv->context); + + if (gtk_widget_get_realized (widget) && + gtk_widget_get_has_window (widget)) + gtk_style_context_set_background (widget->priv->context, + widget->priv->window); + } + + if (widget->priv->anchored) + gtk_widget_queue_resize (widget); } static gboolean @@ -6734,9 +6807,6 @@ gtk_widget_set_name (GtkWidget *widget, if (priv->context) gtk_style_context_set_path (priv->context, priv->path); - if (priv->rc_style) - gtk_widget_reset_rc_style (widget); - g_object_notify (G_OBJECT (widget), "name"); } @@ -7085,9 +7155,11 @@ gtk_widget_get_has_window (GtkWidget *widget) * gtk_widget_is_toplevel: * @widget: a #GtkWidget * - * Determines whether @widget is a toplevel widget. Currently only - * #GtkWindow and #GtkInvisible are toplevel widgets. Toplevel - * widgets have no parent widget. + * Determines whether @widget is a toplevel widget. + * + * Currently only #GtkWindow and #GtkInvisible (and out-of-process + * #GtkPlugs) are toplevel widgets. Toplevel widgets have no parent + * widget. * * Return value: %TRUE if @widget is a toplevel, %FALSE otherwise * @@ -7502,6 +7574,9 @@ gtk_widget_set_parent (GtkWidget *widget, */ g_object_ref_sink (widget); + + gtk_widget_push_verify_invariants (widget); + priv->parent = parent; parent_flags = gtk_widget_get_state_flags (parent); @@ -7565,6 +7640,8 @@ gtk_widget_set_parent (GtkWidget *widget, gtk_style_context_set_screen (widget->priv->context, gtk_widget_get_screen (widget)); } + + gtk_widget_pop_verify_invariants (widget); } /** @@ -7658,23 +7735,6 @@ gtk_widget_set_style (GtkWidget *widget, GtkStyle *style) { g_return_if_fail (GTK_IS_WIDGET (widget)); - - if (style) - { - gboolean initial_emission; - - initial_emission = !widget->priv->rc_style && !widget->priv->user_style; - - widget->priv->rc_style = FALSE; - widget->priv->user_style = TRUE; - - gtk_widget_set_style_internal (widget, style, initial_emission); - } - else - { - if (widget->priv->user_style) - gtk_widget_reset_rc_style (widget); - } } /** @@ -7694,46 +7754,25 @@ gtk_widget_ensure_style (GtkWidget *widget) g_return_if_fail (GTK_IS_WIDGET (widget)); if (!widget->priv->style || - !gtk_style_has_context (widget->priv->style)) + widget->priv->style == gtk_widget_get_default_style ()) { GtkStyle *style; + if (widget->priv->style) + g_object_unref (widget->priv->style); + style = g_object_new (GTK_TYPE_STYLE, "context", gtk_widget_get_style_context (widget), NULL); - gtk_widget_set_style_internal (widget, style, TRUE); - g_object_unref (style); - } - -#if 0 - if (!widget->priv->rc_style && !widget->priv->user_style) - gtk_widget_reset_rc_style (widget); -#endif -} - -/* Look up the RC style for this widget, unsetting any user style that - * may be in effect currently - **/ -static void -gtk_widget_reset_rc_style (GtkWidget *widget) -{ - GtkWidgetPrivate *priv = widget->priv; - GtkStyle *new_style = NULL; - gboolean initial_emission; + widget->priv->style = g_object_ref (style); - initial_emission = !priv->rc_style && !priv->user_style; - - priv->user_style = FALSE; - priv->rc_style = TRUE; - - if (gtk_widget_has_screen (widget)) - new_style = gtk_rc_get_style (widget); - if (!new_style) - new_style = gtk_widget_get_default_style (); + g_signal_emit (widget, + widget_signals[STYLE_SET], + 0, NULL); - if (initial_emission || new_style != priv->style) - gtk_widget_set_style_internal (widget, new_style, initial_emission); + g_object_unref (style); + } } /** @@ -7790,13 +7829,6 @@ gtk_widget_modify_style (GtkWidget *widget, quark_rc_style, gtk_rc_style_copy (style), (GDestroyNotify) g_object_unref); - - /* note that "style" may be invalid here if it was the old - * modifier style and the only reference was our own. - */ - - if (widget->priv->rc_style) - gtk_widget_reset_rc_style (widget); } /** @@ -7888,11 +7920,6 @@ modifier_style_changed (GtkModifierStyle *style, context = gtk_widget_get_style_context (widget); gtk_style_context_invalidate (context); - - g_signal_emit (widget, - widget_signals[STYLE_SET], - 0, - widget->priv->style); } static GtkModifierStyle * @@ -8347,59 +8374,6 @@ static void gtk_widget_real_style_set (GtkWidget *widget, GtkStyle *previous_style) { - GtkWidgetPrivate *priv = widget->priv; - - if (gtk_widget_get_realized (widget) && - gtk_widget_get_has_window (widget)) - gtk_style_set_background (priv->style, priv->window, - gtk_widget_get_state (widget)); -} - -static void -gtk_widget_set_style_internal (GtkWidget *widget, - GtkStyle *style, - gboolean initial_emission) -{ - GtkWidgetPrivate *priv = widget->priv; - - g_object_ref (widget); - g_object_freeze_notify (G_OBJECT (widget)); - - if (priv->style != style) - { - GtkStyle *previous_style; - - if (gtk_widget_get_realized (widget)) - gtk_style_detach (priv->style); - - previous_style = priv->style; - priv->style = style; - g_object_ref (priv->style); - - if (gtk_widget_get_realized (widget)) - priv->style = gtk_style_attach (priv->style, priv->window); - - gtk_widget_update_pango_context (widget); - g_signal_emit (widget, - widget_signals[STYLE_SET], - 0, - initial_emission ? NULL : previous_style); - g_object_unref (previous_style); - - if (priv->anchored && !initial_emission) - gtk_widget_queue_resize (widget); - } - else if (initial_emission) - { - gtk_widget_update_pango_context (widget); - g_signal_emit (widget, - widget_signals[STYLE_SET], - 0, - NULL); - } - g_object_notify (G_OBJECT (widget), "style"); - g_object_thaw_notify (G_OBJECT (widget)); - g_object_unref (widget); } typedef struct { @@ -8594,11 +8568,6 @@ _gtk_widget_propagate_screen_changed (GtkWidget *widget, static void reset_style_recurse (GtkWidget *widget, gpointer data) { -#if 0 - if (widget->priv->rc_style) - gtk_widget_reset_rc_style (widget); -#endif - if (widget->priv->context) { _gtk_widget_update_path (widget); @@ -8673,6 +8642,192 @@ gtk_widget_get_default_style (void) return gtk_default_style; } +#ifdef G_ENABLE_DEBUG + +/* Verify invariants, see docs/widget_system.txt for notes on much of + * this. Invariants may be temporarily broken while we're in the + * process of updating state, of course, so you can only + * verify_invariants() after a given operation is complete. + * Use push/pop_verify_invariants to help with that. + */ +static void +gtk_widget_verify_invariants (GtkWidget *widget) +{ + GtkWidget *parent; + + if (widget->priv->verifying_invariants_count > 0) + return; + + parent = widget->priv->parent; + + if (widget->priv->mapped) + { + /* Mapped implies ... */ + + if (!widget->priv->realized) + g_warning ("%s %p is mapped but not realized", + G_OBJECT_TYPE_NAME (widget), widget); + + if (!widget->priv->visible) + g_warning ("%s %p is mapped but not visible", + G_OBJECT_TYPE_NAME (widget), widget); + + if (!widget->priv->toplevel) + { + if (!widget->priv->child_visible) + g_warning ("%s %p is mapped but not child_visible", + G_OBJECT_TYPE_NAME (widget), widget); + } + } + else + { + /* Not mapped implies... */ + +#if 0 + /* This check makes sense for normal toplevels, but for + * something like a toplevel that is embedded within a clutter + * state, mapping may depend on external factors. + */ + if (widget->priv->toplevel) + { + if (widget->priv->visible) + g_warning ("%s %p toplevel is visible but not mapped", + G_OBJECT_TYPE_NAME (widget), widget); + } +#endif + } + + /* Parent related checks aren't possible if parent has + * verifying_invariants_count > 0 because parent needs to recurse + * children first before the invariants will hold. + */ + if (parent == NULL || parent->priv->verifying_invariants_count == 0) + { + if (parent && + parent->priv->realized) + { + /* Parent realized implies... */ + +#if 0 + /* This is in widget_system.txt but appears to fail + * because there's no gtk_container_realize() that + * realizes all children... instead we just lazily + * wait for map to fix things up. + */ + if (!widget->priv->realized) + g_warning ("%s %p is realized but child %s %p is not realized", + G_OBJECT_TYPE_NAME (parent), parent, + G_OBJECT_TYPE_NAME (widget), widget); +#endif + } + else if (!widget->priv->toplevel) + { + /* No parent or parent not realized on non-toplevel implies... */ + + if (widget->priv->realized && !widget->priv->in_reparent) + g_warning ("%s %p is not realized but child %s %p is realized", + parent ? G_OBJECT_TYPE_NAME (parent) : "no parent", parent, + G_OBJECT_TYPE_NAME (widget), widget); + } + + if (parent && + parent->priv->mapped && + widget->priv->visible && + widget->priv->child_visible) + { + /* Parent mapped and we are visible implies... */ + + if (!widget->priv->mapped) + g_warning ("%s %p is mapped but visible child %s %p is not mapped", + G_OBJECT_TYPE_NAME (parent), parent, + G_OBJECT_TYPE_NAME (widget), widget); + } + else if (!widget->priv->toplevel) + { + /* No parent or parent not mapped on non-toplevel implies... */ + + if (widget->priv->mapped && !widget->priv->in_reparent) + g_warning ("%s %p is mapped but visible=%d child_visible=%d parent %s %p mapped=%d", + G_OBJECT_TYPE_NAME (widget), widget, + widget->priv->visible, + widget->priv->child_visible, + parent ? G_OBJECT_TYPE_NAME (parent) : "no parent", parent, + parent ? parent->priv->mapped : FALSE); + } + } + + if (!widget->priv->realized) + { + /* Not realized implies... */ + +#if 0 + /* widget_system.txt says these hold, but they don't. */ + if (widget->priv->resize_pending) + g_warning ("%s %p resize pending but not realized", + G_OBJECT_TYPE_NAME (widget), widget); + + if (widget->priv->alloc_needed) + g_warning ("%s %p alloc needed but not realized", + G_OBJECT_TYPE_NAME (widget), widget); + + if (widget->priv->width_request_needed) + g_warning ("%s %p width request needed but not realized", + G_OBJECT_TYPE_NAME (widget), widget); + + if (widget->priv->height_request_needed) + g_warning ("%s %p height request needed but not realized", + G_OBJECT_TYPE_NAME (widget), widget); +#endif + } +} + +/* The point of this push/pop is that invariants may not hold while + * we're busy making changes. So we only check at the outermost call + * on the call stack, after we finish updating everything. + */ +static void +gtk_widget_push_verify_invariants (GtkWidget *widget) +{ + widget->priv->verifying_invariants_count += 1; +} + +static void +gtk_widget_verify_child_invariants (GtkWidget *widget, + gpointer client_data) +{ + /* We don't recurse further; this is a one-level check. */ + gtk_widget_verify_invariants (widget); +} + +static void +gtk_widget_pop_verify_invariants (GtkWidget *widget) +{ + g_assert (widget->priv->verifying_invariants_count > 0); + + widget->priv->verifying_invariants_count -= 1; + + if (widget->priv->verifying_invariants_count == 0) + { + gtk_widget_verify_invariants (widget); + + if (GTK_IS_CONTAINER (widget)) + { + /* Check one level of children, because our + * push_verify_invariants() will have prevented some of the + * checks. This does not recurse because if recursion is + * needed, it will happen naturally as each child has a + * push/pop on that child. For example if we're recursively + * mapping children, we'll push/pop on each child as we map + * it. + */ + gtk_container_forall (GTK_CONTAINER (widget), + gtk_widget_verify_child_invariants, + NULL); + } + } +} +#endif /* G_ENABLE_DEBUG */ + static PangoContext * gtk_widget_peek_pango_context (GtkWidget *widget) { @@ -8919,6 +9074,16 @@ gtk_widget_render_icon (GtkWidget *widget, * @parent_window: the new parent window. * * Sets a non default parent window for @widget. + * + * For GtkWindow classes, setting a @parent_window effects whether + * the window is a toplevel window or can be embedded into other + * widgets. + * + * + * For GtkWindow classes, this needs to be called before the + * window is realized. + * + * **/ void gtk_widget_set_parent_window (GtkWidget *widget, @@ -8939,6 +9104,13 @@ gtk_widget_set_parent_window (GtkWidget *widget, g_object_unref (old_parent_window); if (parent_window) g_object_ref (parent_window); + + /* Unset toplevel flag when adding a parent window to a widget, + * this is the primary entry point to allow toplevels to be + * embeddable. + */ + if (GTK_IS_WINDOW (widget) && !GTK_IS_PLUG (widget)) + _gtk_window_set_is_toplevel (GTK_WINDOW (widget), parent_window == NULL); } } @@ -9002,6 +9174,7 @@ gtk_widget_set_child_visible (GtkWidget *widget, priv = widget->priv; g_object_ref (widget); + gtk_widget_verify_invariants (widget); if (is_visible) priv->child_visible = TRUE; @@ -9026,6 +9199,7 @@ gtk_widget_set_child_visible (GtkWidget *widget, gtk_widget_unmap (widget); } + gtk_widget_verify_invariants (widget); g_object_unref (widget); } @@ -10370,10 +10544,7 @@ gtk_widget_real_unrealize (GtkWidget *widget) { GtkWidgetPrivate *priv = widget->priv; - if (gtk_widget_get_mapped (widget)) - gtk_widget_real_unmap (widget); - - gtk_widget_set_mapped (widget, FALSE); + g_assert (!widget->priv->mapped); /* printf ("unrealizing %s\n", g_type_name (G_TYPE_FROM_INSTANCE (widget))); */ @@ -13797,7 +13968,20 @@ style_context_changed (GtkStyleContext *context, { GtkWidget *widget = user_data; - g_signal_emit (widget, widget_signals[STYLE_UPDATED], 0); + gtk_widget_update_pango_context (widget); + + if (gtk_widget_get_realized (widget)) + g_signal_emit (widget, widget_signals[STYLE_UPDATED], 0); + else + { + /* Compress all style updates so it + * is only emitted once pre-realize. + */ + widget->priv->style_update_pending = TRUE; + } + + if (widget->priv->anchored) + gtk_widget_queue_resize (widget); } /**