[gtk+] Fixed issues with "hierarchy-changed" signal.



commit fdba9f281dbf7487129ab59d71090bc775d8f316
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Fri Dec 24 12:01:43 2010 +0900

    Fixed issues with "hierarchy-changed" signal.
    
    GtkFileChooserDefault watches the toplevel and montitors "set-focus"
    signal on it... however the connection needs to be remade when the
    GtkFileChooserDialog is in an embedded toplevel.
    
    Measure's taken: GtkWindow propagates hierarchy changes when
    _gtk_window_set_is_toplevel() is called, gtk_widget_unparent()
    unsets the widget's parent window earlier in the function so that
    the possible hierarchy change is still able to properly access the hierarchy.
    
    GtkFileChooserDefault checks if the "new" toplevel is indeed
    gtk_widget_is_toplevel() but not the old one, GtkRange has been
    updated to use gtk_widget_is_toplevel() inside it's hierarhcy_changed
    vfunc, other classes already do this properly.

 gtk/gtkfilechooserdefault.c |    2 +-
 gtk/gtkrange.c              |    2 +-
 gtk/gtkwidget.c             |    9 ++++++++-
 gtk/gtkwindow.c             |    9 +++++++++
 4 files changed, 19 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index c9eef75..b99348a 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -5599,7 +5599,7 @@ gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget,
     g_assert (impl->toplevel_set_focus_id == 0);
 
   toplevel = gtk_widget_get_toplevel (widget);
-  if (GTK_IS_WINDOW (toplevel))
+  if (gtk_widget_is_toplevel (toplevel))
     {
       impl->toplevel_set_focus_id = g_signal_connect (toplevel, "set-focus",
 						      G_CALLBACK (toplevel_set_focus_cb), impl);
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index 678a2dd..4c8d428 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -1660,7 +1660,7 @@ gtk_range_hierarchy_changed (GtkWidget *widget,
                                           G_CALLBACK (resize_grip_visible_changed),
                                           widget);
   window = gtk_widget_get_toplevel (widget);
-  if (GTK_IS_WINDOW (window))
+  if (gtk_widget_is_toplevel (window))
     g_signal_connect (window, "notify::resize-grip-visible",
                       G_CALLBACK (resize_grip_visible_changed), widget);
 }
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 9aa0865..20a268b 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -3714,9 +3714,17 @@ gtk_widget_unparent (GtkWidget *widget)
   g_object_freeze_notify (G_OBJECT (widget));
   nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
 
+  /* 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);
+
   toplevel = gtk_widget_get_toplevel (widget);
   if (gtk_widget_is_toplevel (toplevel))
     _gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
+  else
+    toplevel = NULL;
 
   if (gtk_container_get_focus_child (GTK_CONTAINER (priv->parent)) == widget)
     gtk_container_set_focus_child (GTK_CONTAINER (priv->parent), NULL);
@@ -3755,7 +3763,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
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 477cccd..60693ff 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -9221,6 +9221,7 @@ _gtk_window_set_is_toplevel (GtkWindow *window,
 			     gboolean   is_toplevel)
 {
   GtkWidget *widget;
+  GtkWidget *toplevel;
 
   widget = GTK_WIDGET (window);
 
@@ -9234,6 +9235,12 @@ _gtk_window_set_is_toplevel (GtkWindow *window,
 
   if (is_toplevel)
     {
+      toplevel = gtk_widget_get_toplevel (widget);
+      if (!gtk_widget_is_toplevel (toplevel))
+	toplevel = NULL;
+
+      _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
+
       _gtk_widget_set_is_toplevel (widget, TRUE);
       toplevel_list = g_slist_prepend (toplevel_list, window);
     }
@@ -9241,6 +9248,8 @@ _gtk_window_set_is_toplevel (GtkWindow *window,
     {
       _gtk_widget_set_is_toplevel (widget, FALSE);
       toplevel_list = g_slist_remove (toplevel_list, window);
+
+      _gtk_widget_propagate_hierarchy_changed (widget, widget);
     }
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]