From b67c5af55bf611c013b2c43e6878281abd773530 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 20 Dec 2010 12:58:04 -0500 Subject: [PATCH] Add invariant that a child is unmapped if parent is unmapped Requires fixes to GtkContainer and GtkWindow to unmap their children, rather than just withdrawing or hiding the container window. Requires fix to GtkHandleBox to chain up to GtkContainer unmap. Historically we avoided these unmaps for efficiency reasons, but these days it's a bigger problem that there's no way for child widgets to know that one of their ancestors has become unmapped. --- docs/widget_system.txt | 2 +- gtk/gtkcontainer.c | 13 +++++++++---- gtk/gtkhandlebox.c | 2 ++ gtk/gtkwidget.c | 12 ++++++++++++ gtk/gtkwindow.c | 5 +++++ 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/docs/widget_system.txt b/docs/widget_system.txt index 1c2867cad..9463f10db 100644 --- a/docs/widget_system.txt +++ b/docs/widget_system.txt @@ -255,7 +255,7 @@ In the following widget->parent && GTK_WIDGET_MAPPED (widget->parent) && GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_CHILD_VISIBLE - => GTK_WIDGET_MAPPED (widget) + <=> GTK_WIDGET_MAPPED (widget) Note:, the definition diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index a5120377c..0ae08277f 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -3110,12 +3110,17 @@ gtk_container_unmap (GtkWidget *widget) { gtk_widget_set_mapped (widget, FALSE); + /* hide our window first so user doesn't see all the child windows + * vanishing one by one. (only matters these days if one of the + * children has an actual native window instead of client-side + * window, e.g. a GtkSocket would) + */ if (gtk_widget_get_has_window (widget)) gdk_window_hide (gtk_widget_get_window (widget)); - else - gtk_container_forall (GTK_CONTAINER (widget), - (GtkCallback)gtk_widget_unmap, - NULL); + + gtk_container_forall (GTK_CONTAINER (widget), + (GtkCallback)gtk_widget_unmap, + NULL); } /** diff --git a/gtk/gtkhandlebox.c b/gtk/gtkhandlebox.c index 1e02e84f8..2b1f9063a 100644 --- a/gtk/gtkhandlebox.c +++ b/gtk/gtkhandlebox.c @@ -397,6 +397,8 @@ gtk_handle_box_unmap (GtkWidget *widget) gdk_window_hide (priv->float_window); priv->float_window_mapped = FALSE; } + + GTK_WIDGET_CLASS (gtk_handle_box_parent_class)->unmap (widget); } static void diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index d3ff2b866..92e427891 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -8722,6 +8722,18 @@ gtk_widget_verify_invariants (GtkWidget *widget) 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) diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 6a782ce5c..1a77b1f1f 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -4828,6 +4828,7 @@ gtk_window_unmap (GtkWidget *widget) { GtkWindow *window = GTK_WINDOW (widget); GtkWindowPrivate *priv = window->priv; + GtkWidget *child; GtkWindowGeometryInfo *info; GdkWindow *gdk_window; GdkWindowState state; @@ -4862,6 +4863,10 @@ gtk_window_unmap (GtkWidget *widget) priv->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0; priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0; priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0; + + child = gtk_bin_get_child (&(window->bin)); + if (child) + gtk_widget_unmap (child); } static void -- 2.43.2