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.
This commit is contained in:
Havoc Pennington 2010-12-20 12:58:04 -05:00 committed by Matthias Clasen
parent 23ce44c9fe
commit b67c5af55b
5 changed files with 29 additions and 5 deletions

View File

@ -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

View File

@ -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);
}
/**

View File

@ -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

View File

@ -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)

View File

@ -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