]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkwidget.c
Change FSF Address
[~andy/gtk] / gtk / gtkwidget.c
index 6b96be4141cd181a83d94cef35180bd85047252f..ff483125fedb2bb93823a6106689e73063334e27 100644 (file)
@@ -12,9 +12,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
@@ -35,7 +33,7 @@
 #include <cairo-gobject.h>
 
 #include "gtkcontainer.h"
-#include "gtkaccelmap.h"
+#include "gtkaccelmapprivate.h"
 #include "gtkclipboard.h"
 #include "gtkiconfactory.h"
 #include "gtkintl.h"
@@ -372,6 +370,11 @@ struct _GtkWidgetPrivate
    */
   gchar *name;
 
+  /* The list of attached windows to this widget.
+   * We keep a list in order to call reset_style to all of them,
+   * recursively. */
+  GList *attached_windows; 
+
   /* The style for the widget. The style contains the
    * colors the widget should be drawn in for each state
    * along with graphics contexts used to draw with and
@@ -532,7 +535,6 @@ struct _GtkStateData
 {
   guint         flags : GTK_STATE_FLAGS_BITS;
   guint         operation : 2;
-  guint                use_forall : 1;
 };
 
 /* --- prototypes --- */
@@ -3784,8 +3786,10 @@ gtk_widget_unparent (GtkWidget *widget)
       gtk_widget_queue_compute_expand (old_parent);
     }
 
-  /* Unset window-unfocused since we are no longer inside a toplevel window */
-  gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_WINDOW_UNFOCUSED);
+  /* Unset BACKDROP since we are no longer inside a toplevel window */
+  gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_BACKDROP);
+  if (priv->context)
+    gtk_style_context_set_parent (priv->context, NULL);
 
   g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent);
   if (toplevel)
@@ -5725,6 +5729,19 @@ _gtk_widget_draw_internal (GtkWidget *widget,
       g_signal_emit (widget, widget_signals[DRAW],
                      0, cr,
                      &result);
+
+      if (cairo_status (cr) &&
+          _gtk_cairo_get_event (cr))
+        {
+          /* We check the event so we only warn about internal GTK calls.
+           * Errors might come from PDF streams having write failures and
+           * we don't want to spam stderr in that case.
+           * We do want to catch errors from
+           */
+          g_warning ("drawing failure for widget `%s': %s",
+                     G_OBJECT_TYPE_NAME (widget),
+                     cairo_status_to_string (cairo_status (cr)));
+        }
     }
 
   context = gtk_widget_get_style_context (widget);
@@ -7092,7 +7109,6 @@ _gtk_widget_update_state_flags (GtkWidget     *widget,
 
       data.flags = flags;
       data.operation = operation;
-      data.use_forall = FALSE;
 
       gtk_widget_propagate_state (widget, &data);
 
@@ -7663,7 +7679,6 @@ gtk_widget_set_sensitive (GtkWidget *widget,
                          gboolean   sensitive)
 {
   GtkWidgetPrivate *priv;
-  GtkStateData data;
 
   g_return_if_fail (GTK_IS_WIDGET (widget));
 
@@ -7674,24 +7689,24 @@ gtk_widget_set_sensitive (GtkWidget *widget,
   if (priv->sensitive == sensitive)
     return;
 
-  data.flags = GTK_STATE_FLAG_INSENSITIVE;
+  priv->sensitive = sensitive;
 
-  if (sensitive)
-    {
-      priv->sensitive = TRUE;
-      data.operation = STATE_CHANGE_UNSET;
-    }
-  else
+  if (priv->parent == NULL
+      || gtk_widget_is_sensitive (priv->parent))
     {
-      priv->sensitive = FALSE;
-      data.operation = STATE_CHANGE_SET;
-    }
+      GtkStateData data;
 
-  data.use_forall = TRUE;
+      data.flags = GTK_STATE_FLAG_INSENSITIVE;
 
-  gtk_widget_propagate_state (widget, &data);
+      if (sensitive)
+        data.operation = STATE_CHANGE_UNSET;
+      else
+        data.operation = STATE_CHANGE_SET;
 
-  gtk_widget_queue_resize (widget);
+      gtk_widget_propagate_state (widget, &data);
+
+      gtk_widget_queue_resize (widget);
+    }
 
   g_object_notify (G_OBJECT (widget), "sensitive");
 }
@@ -7803,9 +7818,11 @@ gtk_widget_set_parent (GtkWidget *widget,
   data.flags |= priv->state_flags;
 
   data.operation = STATE_CHANGE_REPLACE;
-  data.use_forall = gtk_widget_is_sensitive (parent) != gtk_widget_is_sensitive (widget);
   gtk_widget_propagate_state (widget, &data);
 
+  if (priv->context)
+    gtk_style_context_set_parent (priv->context,
+                                  gtk_widget_get_style_context (parent));
   gtk_widget_reset_style (widget);
 
   g_signal_emit (widget, widget_signals[PARENT_SET], 0, NULL);
@@ -8300,6 +8317,9 @@ gtk_widget_reset_style (GtkWidget *widget)
   g_return_if_fail (GTK_IS_WIDGET (widget));
 
   reset_style_recurse (widget, NULL);
+
+  g_list_foreach (widget->priv->attached_windows,
+                  (GFunc) reset_style_recurse, NULL);
 }
 
 #ifdef G_ENABLE_DEBUG
@@ -10101,6 +10121,17 @@ gtk_widget_real_destroy (GtkWidget *object)
   GtkWidget *widget = GTK_WIDGET (object);
   GtkWidgetPrivate *priv = widget->priv;
 
+  if (GTK_WIDGET_GET_CLASS (widget)->priv->accessible_type != GTK_TYPE_ACCESSIBLE)
+    {
+      GtkAccessible *accessible = g_object_steal_qdata (G_OBJECT (widget), quark_accessible_object);
+      
+      if (accessible)
+        {
+          gtk_accessible_set_widget (accessible, NULL);
+          g_object_unref (accessible);
+        }
+    }
+
   /* wipe accelerator closures (keep order) */
   g_object_set_qdata (G_OBJECT (widget), quark_accel_path, NULL);
   g_object_set_qdata (G_OBJECT (widget), quark_accel_closures, NULL);
@@ -10701,10 +10732,13 @@ gtk_widget_propagate_state (GtkWidget    *widget,
       if (!gtk_widget_is_sensitive (widget) && gtk_widget_has_grab (widget))
         gtk_grab_remove (widget);
 
+      gtk_style_context_set_state (gtk_widget_get_style_context (widget), new_flags);
+
       g_signal_emit (widget, widget_signals[STATE_CHANGED], 0, old_state);
       g_signal_emit (widget, widget_signals[STATE_FLAGS_CHANGED], 0, old_flags);
 
-      if (!priv->shadowed)
+      if (!priv->shadowed &&
+          (new_flags & GTK_STATE_FLAG_INSENSITIVE) != (old_flags & GTK_STATE_FLAG_INSENSITIVE))
         {
           GList *event_windows = NULL;
           GList *devices, *d;
@@ -10729,7 +10763,7 @@ gtk_widget_propagate_state (GtkWidget    *widget,
               if (!gtk_widget_is_sensitive (widget))
                 _gtk_widget_synthesize_crossing (widget, NULL, d->data,
                                                  GDK_CROSSING_STATE_CHANGED);
-              else if (old_flags & GTK_STATE_FLAG_INSENSITIVE)
+              else
                 _gtk_widget_synthesize_crossing (NULL, widget, d->data,
                                                  GDK_CROSSING_STATE_CHANGED);
 
@@ -10747,14 +10781,9 @@ gtk_widget_propagate_state (GtkWidget    *widget,
           /* Make sure to only propate the right states further */
           child_data.flags &= GTK_STATE_FLAGS_DO_PROPAGATE;
 
-          if (child_data.use_forall)
-            gtk_container_forall (GTK_CONTAINER (widget),
-                                  (GtkCallback) gtk_widget_propagate_state,
-                                  &child_data);
-          else
-            gtk_container_foreach (GTK_CONTAINER (widget),
-                                   (GtkCallback) gtk_widget_propagate_state,
-                                   &child_data);
+          gtk_container_forall (GTK_CONTAINER (widget),
+                                (GtkCallback) gtk_widget_propagate_state,
+                                &child_data);
         }
 
       /* Trigger state change transitions for the widget */
@@ -11396,7 +11425,9 @@ gtk_widget_real_get_accessible (GtkWidget *widget)
       }
     else
       {
-        accessible = g_object_new (priv->accessible_type, NULL);
+        accessible = g_object_new (priv->accessible_type,
+                                   "widget", widget,
+                                   NULL);
         if (priv->accessible_role != ATK_ROLE_INVALID)
           atk_object_set_role (accessible, priv->accessible_role);
 
@@ -12010,8 +12041,7 @@ gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
        }
       g_object_unref (relation_set);
 
-      g_slist_foreach (atk_relations, (GFunc)free_relation, NULL);
-      g_slist_free (atk_relations);
+      g_slist_free_full (atk_relations, (GDestroyNotify) free_relation);
       g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
                          NULL);
     }
@@ -12418,8 +12448,7 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
           else
             g_warning ("accessibility action on a widget that does not implement AtkAction");
 
-         g_slist_foreach (a11y_data->actions, (GFunc)free_action, NULL);
-         g_slist_free (a11y_data->actions);
+         g_slist_free_full (a11y_data->actions, (GDestroyNotify) free_action);
        }
 
       if (a11y_data->relations)
@@ -13689,6 +13718,20 @@ _gtk_widget_get_sizegroups (GtkWidget    *widget)
   return NULL;
 }
 
+void
+_gtk_widget_add_attached_window (GtkWidget    *widget,
+                                 GtkWindow    *window)
+{
+  widget->priv->attached_windows = g_list_prepend (widget->priv->attached_windows, window);
+}
+
+void
+_gtk_widget_remove_attached_window (GtkWidget    *widget,
+                                    GtkWindow    *window)
+{
+  widget->priv->attached_windows = g_list_remove (widget->priv->attached_windows, window);
+}
+
 /**
  * gtk_widget_path_append_for_widget:
  * @path: a widget path
@@ -13777,7 +13820,15 @@ gtk_widget_get_path (GtkWidget *widget)
            * where style properties might be retrieved on that
            * situation.
            */
-          widget->priv->path = gtk_widget_path_new ();
+          GtkWidget *attach_widget = NULL;
+
+          if (GTK_IS_WINDOW (widget))
+            attach_widget = gtk_window_get_attached_to (GTK_WINDOW (widget));
+
+          if (attach_widget != NULL)
+            widget->priv->path = gtk_widget_path_copy (gtk_widget_get_path (attach_widget));
+          else
+            widget->priv->path = gtk_widget_path_new ();
     
           gtk_widget_path_append_for_widget (widget->priv->path, widget);
         }
@@ -13849,6 +13900,9 @@ gtk_widget_get_style_context (GtkWidget *widget)
         gtk_style_context_set_screen (priv->context, screen);
 
       gtk_style_context_set_path (priv->context, path);
+      if (priv->parent)
+        gtk_style_context_set_parent (priv->context,
+                                      gtk_widget_get_style_context (priv->parent));
     }
 
   return widget->priv->context;