[gtk+] GtkHeaderBar: Survive toggling custom / non-custom titles



commit d42c2c3f19aebb976cf26303dbfb591bae2feae1
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Mar 19 20:52:54 2013 -0400

    GtkHeaderBar: Survive toggling custom / non-custom titles
    
    The code was always adding a label widget as a child, but
    then skipping over it in forall if a custom_title was present.
    This confuses internal logic of GTK+ which assumes that it
    can iterate over the entire widget hierarchy with forall,
    to maintain state. Fix this by destroying the label when
    a custom_title is set, and recreating it as needed.

 gtk/gtkheaderbar.c |   73 +++++++++++++++++++++++++++++++++------------------
 1 files changed, 47 insertions(+), 26 deletions(-)
---
diff --git a/gtk/gtkheaderbar.c b/gtk/gtkheaderbar.c
index 88bc1ab..1cbb69e 100644
--- a/gtk/gtkheaderbar.c
+++ b/gtk/gtkheaderbar.c
@@ -116,18 +116,13 @@ get_css_padding_and_border (GtkWidget *widget,
 }
 
 static void
-gtk_header_bar_init (GtkHeaderBar *bar)
+construct_label (GtkHeaderBar *bar)
 {
-  GtkStyleContext *context;
-  GtkHeaderBarPrivate *priv;
-
-  priv = G_TYPE_INSTANCE_GET_PRIVATE (bar, GTK_TYPE_HEADER_BAR, GtkHeaderBarPrivate);
-  bar->priv = priv;
+  GtkHeaderBarPrivate *priv = bar->priv;
 
-  gtk_widget_set_has_window (GTK_WIDGET (bar), FALSE);
-  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (bar), FALSE);
+  g_assert (priv->label == NULL);
 
-  priv->label = gtk_label_new ("");
+  priv->label = gtk_label_new (priv->title);
   boldify_label (priv->label);
   gtk_widget_set_parent (priv->label, GTK_WIDGET (bar));
   gtk_widget_set_valign (priv->label, GTK_ALIGN_CENTER);
@@ -135,6 +130,19 @@ gtk_header_bar_init (GtkHeaderBar *bar)
   gtk_label_set_single_line_mode (GTK_LABEL (priv->label), TRUE);
   gtk_label_set_ellipsize (GTK_LABEL (priv->label), PANGO_ELLIPSIZE_END);
   gtk_widget_show (priv->label);
+}
+
+static void
+gtk_header_bar_init (GtkHeaderBar *bar)
+{
+  GtkStyleContext *context;
+  GtkHeaderBarPrivate *priv;
+
+  priv = G_TYPE_INSTANCE_GET_PRIVATE (bar, GTK_TYPE_HEADER_BAR, GtkHeaderBarPrivate);
+  bar->priv = priv;
+
+  gtk_widget_set_has_window (GTK_WIDGET (bar), FALSE);
+  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (bar), FALSE);
 
   priv->title = NULL;
   priv->custom_title = NULL;
@@ -143,6 +151,8 @@ gtk_header_bar_init (GtkHeaderBar *bar)
   priv->hpadding = DEFAULT_HPADDING;
   priv->vpadding = DEFAULT_VPADDING;
 
+  construct_label (bar);
+
   context = gtk_widget_get_style_context (GTK_WIDGET (bar));
   gtk_style_context_add_class (context, "header-bar");
   gtk_style_context_add_class (context, GTK_STYLE_CLASS_HORIZONTAL);
@@ -220,10 +230,13 @@ gtk_header_bar_get_size (GtkWidget      *widget,
         nvis_children += 1;
     }
 
-  if (add_child_size (priv->label, orientation, &minimum, &natural))
-    nvis_children += 1;
+  if (priv->label != NULL)
+    {
+      if (add_child_size (priv->label, orientation, &minimum, &natural))
+        nvis_children += 1;
+    }
 
-  if (priv->custom_title)
+  if (priv->custom_title != NULL)
     {
       if (add_child_size (priv->custom_title, orientation, &minimum, &natural))
         nvis_children += 1;
@@ -622,8 +635,11 @@ gtk_header_bar_set_title (GtkHeaderBar *bar,
   g_free (priv->title);
   priv->title = new_title;
 
-  gtk_label_set_label (GTK_LABEL (priv->label), priv->title);
-  gtk_widget_queue_resize (GTK_WIDGET (bar));
+  if (priv->label != NULL)
+    {
+      gtk_label_set_label (GTK_LABEL (priv->label), priv->title);
+      gtk_widget_queue_resize (GTK_WIDGET (bar));
+    }
 
   g_object_notify (G_OBJECT (bar), "title");
 }
@@ -684,20 +700,27 @@ gtk_header_bar_set_custom_title (GtkHeaderBar *bar,
       gtk_widget_unparent (custom);
     }
 
-  if (title_widget)
+  if (title_widget != NULL)
     {
       priv->custom_title = title_widget;
 
-      gtk_widget_hide (priv->label);
-
       gtk_widget_set_parent (priv->custom_title, GTK_WIDGET (bar));
       gtk_widget_set_valign (priv->custom_title, GTK_ALIGN_CENTER);
-
       gtk_widget_show (title_widget);
+
+      if (priv->label != NULL)
+        {
+          GtkWidget *label = priv->label;
+
+          priv->label = NULL;
+          gtk_widget_unparent (label);
+        }
+
     }
   else
     {
-      gtk_widget_show (priv->label);
+      if (priv->label == NULL)
+        construct_label (bar);
     }
 
   gtk_widget_queue_resize (GTK_WIDGET (bar));
@@ -897,13 +920,11 @@ gtk_header_bar_forall (GtkContainer *container,
         (* callback) (child->widget, callback_data);
     }
 
-  if (include_internals)
-    {
-      if (priv->custom_title)
-        (* callback) (priv->custom_title, callback_data);
-      else
-        (* callback) (priv->label, callback_data);
-    }
+  if (priv->custom_title != NULL)
+    (* callback) (priv->custom_title, callback_data);
+
+  if (include_internals && priv->label != NULL)
+    (* callback) (priv->label, callback_data);
 
   children = priv->children;
   while (children)


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