]> Pileus Git - ~andy/gtk/commitdiff
Add invariant that a child is unmapped if parent is unmapped
authorHavoc Pennington <hp@pobox.com>
Mon, 20 Dec 2010 17:58:04 +0000 (12:58 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 20 Dec 2010 17:58:04 +0000 (12:58 -0500)
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
gtk/gtkcontainer.c
gtk/gtkhandlebox.c
gtk/gtkwidget.c
gtk/gtkwindow.c

index 1c2867cad5e96cd2b56d724e19cf2f097ba0e9d6..9463f10db9925b0cbf2d7d6a2d0faa0ab2344797 100644 (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
 
index a5120377cf42d01804d993a4254736852bc2b05a..0ae08277f7c85e0810a3b7ef1513c7e4d3ac3f67 100644 (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);
 }
 
 /**
index 1e02e84f87a7f93e6df6da9b282bac31ca7d6dd7..2b1f9063ae5382a40efb1e0a6bd00a6fc6039462 100644 (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
index d3ff2b8666ad31f7a3d32ceed07297ca2a8cd0fd..92e427891206fbd73358b1096d47a5d2a285bade 100644 (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)
index 6a782ce5c6c2b24085d47ff176ae54f97dae5f01..1a77b1f1f86011acf187e0c96171a27c62d01d3e 100644 (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