]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkwidget.c
Silence new gcc warnings
[~andy/gtk] / gtk / gtkwidget.c
index 18765972a14e541c7b0dcc6b08c1373bb6013811..11338a22ebf69f051e452bf0c0e7ce3c48be96e0 100644 (file)
  */
 
 #include "config.h"
+
 #include <stdarg.h>
 #include <string.h>
 #include <locale.h>
+
+#include <gobject/gvaluecollector.h>
+#include <gobject/gobjectnotifyqueue.c>
+#include <cairo-gobject.h>
+
 #include "gtkcontainer.h"
 #include "gtkaccelmap.h"
 #include "gtkclipboard.h"
 #include "gtkiconfactory.h"
 #include "gtkintl.h"
-#include "gtkmain.h"
+#include "gtkmainprivate.h"
 #include "gtkmarshalers.h"
 #include "gtkrc.h"
-#include "gtkselection.h"
+#include "gtkselectionprivate.h"
 #include "gtksettingsprivate.h"
 #include "gtksizegroup-private.h"
 #include "gtkwidget.h"
 #include "gtkwindowprivate.h"
 #include "gtkbindings.h"
 #include "gtkprivate.h"
-#include "gdk/gdk.h"
-#include <gobject/gvaluecollector.h>
-#include <gobject/gobjectnotifyqueue.c>
-#include <cairo-gobject.h>
-#include "gdk/gdkkeysyms.h"
 #include "gtkaccessible.h"
 #include "gtktooltip.h"
 #include "gtkinvisible.h"
 #include "gtkbuildable.h"
 #include "gtkbuilderprivate.h"
 #include "gtksizerequest.h"
-#include "gtkstylecontext.h"
+#include "gtkstylecontextprivate.h"
 #include "gtksymboliccolor.h"
 #include "gtkcssprovider.h"
 #include "gtkanimationdescription.h"
 #include "gtkmodifierstyle.h"
 #include "gtkversion.h"
 #include "gtkdebug.h"
+#include "gtktypebuiltins.h"
 
 
 /**
  * For example, when queried in the normal
  * %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH mode:
  * First, the default minimum and natural width for each widget
- * in the interface will be computed using gtk_width_get_preferred_width().
+ * in the interface will be computed using gtk_widget_get_preferred_width().
  * Because the preferred widths for each container depend on the preferred
  * widths of their children, this information propagates up the hierarchy,
  * and finally a minimum and natural width is determined for the entire
@@ -312,7 +314,7 @@ struct _GtkWidgetPrivate
   guint has_grab              : 1;
   guint shadowed              : 1;
   guint rc_style              : 1;
-  guint user_style            : 1;
+  guint style_update_pending  : 1;
   guint app_paintable         : 1;
   guint double_buffered       : 1;
   guint redraw_on_alloc       : 1;
@@ -661,6 +663,10 @@ static void gtk_widget_set_usize_internal (GtkWidget          *widget,
 static void gtk_widget_add_events_internal (GtkWidget *widget,
                                             GdkDevice *device,
                                             gint       events);
+static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
+                                                    GdkDevice *device,
+                                                    gboolean   recurse,
+                                                    gboolean   enabled);
 
 /* --- variables --- */
 static gpointer         gtk_widget_parent_class = NULL;
@@ -689,6 +695,7 @@ static GQuark               quark_has_tooltip = 0;
 static GQuark          quark_tooltip_window = 0;
 static GQuark          quark_visual = 0;
 static GQuark           quark_modifier_style = 0;
+static GQuark           quark_enabled_devices = 0;
 GParamSpecPool         *_gtk_widget_child_property_pool = NULL;
 GObjectNotifyContext   *_gtk_widget_child_property_notify_context = NULL;
 
@@ -802,6 +809,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
   quark_tooltip_window = g_quark_from_static_string ("gtk-tooltip-window");
   quark_visual = g_quark_from_static_string ("gtk-widget-visual");
   quark_modifier_style = g_quark_from_static_string ("gtk-widget-modifier-style");
+  quark_enabled_devices = g_quark_from_static_string ("gtk-widget-enabled-devices");
 
   style_property_spec_pool = g_param_spec_pool_new (FALSE);
   _gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
@@ -3719,14 +3727,6 @@ gtk_widget_unparent (GtkWidget *widget)
   if (gtk_container_get_focus_child (GTK_CONTAINER (priv->parent)) == widget)
     gtk_container_set_focus_child (GTK_CONTAINER (priv->parent), NULL);
 
-  /* If we are unanchoring the child, we save around the toplevel
-   * to emit hierarchy changed
-   */
-  if (priv->parent->priv->anchored)
-    g_object_ref (toplevel);
-  else
-    toplevel = NULL;
-
   gtk_widget_queue_draw_child (widget);
 
   /* Reset the width and height here, to force reallocation if we
@@ -3745,6 +3745,14 @@ gtk_widget_unparent (GtkWidget *widget)
        gtk_widget_unrealize (widget);
     }
 
+  /* If we are unanchoring the child, we save around the toplevel
+   * to emit hierarchy changed
+   */
+  if (priv->parent->priv->anchored)
+    g_object_ref (toplevel);
+  else
+    toplevel = NULL;
+
   /* Removing a widget from a container restores the child visible
    * flag to the default state, so it doesn't affect the child
    * in the next parent.
@@ -3753,7 +3761,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
@@ -3774,6 +3781,13 @@ gtk_widget_unparent (GtkWidget *widget)
       g_object_unref (toplevel);
     }
 
+  /* Now that the parent pointer is nullified and the hierarchy-changed
+   * already passed, go ahead and unset the parent window, if we are unparenting
+   * an embeded GtkWindow the window will become toplevel again and hierarchy-changed
+   * will fire again for the new subhierarchy.
+   */
+  gtk_widget_set_parent_window (widget, NULL);
+
   g_object_notify (G_OBJECT (widget), "parent");
   g_object_thaw_notify (G_OBJECT (widget));
   if (!priv->parent)
@@ -4183,6 +4197,9 @@ gtk_widget_unmap (GtkWidget *widget)
       g_signal_emit (widget, widget_signals[UNMAP], 0);
 
       gtk_widget_pop_verify_invariants (widget);
+
+      if (priv->context)
+        gtk_style_context_cancel_animations (priv->context, NULL);
     }
 }
 
@@ -4211,6 +4228,105 @@ _gtk_widget_enable_device_events (GtkWidget *widget)
     }
 }
 
+static GList *
+get_widget_windows (GtkWidget *widget)
+{
+  GList *window_list, *last, *l, *children, *ret;
+
+  if (gtk_widget_get_has_window (widget))
+    window_list = g_list_prepend (NULL, gtk_widget_get_window (widget));
+  else
+    window_list = gdk_window_peek_children (gtk_widget_get_window (widget));
+
+  last = g_list_last (window_list);
+  ret = NULL;
+
+  for (l = window_list; l; l = l->next)
+    {
+      GtkWidget *window_widget = NULL;
+
+      gdk_window_get_user_data (l->data, (gpointer *) &window_widget);
+
+      if (widget != window_widget)
+        continue;
+
+      ret = g_list_prepend (ret, l->data);
+      children = gdk_window_peek_children (GDK_WINDOW (l->data));
+
+      if (children)
+        {
+          last = g_list_concat (last, children);
+          last = g_list_last (last);
+        }
+    }
+
+  g_list_free (window_list);
+
+  return ret;
+}
+
+static void
+device_enable_foreach (GtkWidget *widget,
+                       gpointer   user_data)
+{
+  GdkDevice *device = user_data;
+  gtk_widget_set_device_enabled_internal (widget, device, TRUE, TRUE);
+}
+
+static void
+device_disable_foreach (GtkWidget *widget,
+                        gpointer   user_data)
+{
+  GdkDevice *device = user_data;
+  gtk_widget_set_device_enabled_internal (widget, device, TRUE, FALSE);
+}
+
+static void
+gtk_widget_set_device_enabled_internal (GtkWidget *widget,
+                                        GdkDevice *device,
+                                        gboolean   recurse,
+                                        gboolean   enabled)
+{
+  GList *window_list, *l;
+
+  window_list = get_widget_windows (widget);
+
+  for (l = window_list; l; l = l->next)
+    {
+      GdkEventMask events = 0;
+      GdkWindow *window;
+
+      window = l->data;
+
+      if (enabled)
+        events = gdk_window_get_events (window);
+
+      gdk_window_set_device_events (window, device, events);
+    }
+
+  if (recurse && GTK_IS_CONTAINER (widget))
+    {
+      if (enabled)
+        gtk_container_forall (GTK_CONTAINER (widget), device_enable_foreach, device);
+      else
+        gtk_container_forall (GTK_CONTAINER (widget), device_disable_foreach, device);
+    }
+
+  g_list_free (window_list);
+}
+
+static void
+gtk_widget_update_devices_mask (GtkWidget *widget,
+                                gboolean   recurse)
+{
+  GList *enabled_devices, *l;
+
+  enabled_devices = g_object_get_qdata (G_OBJECT (widget), quark_enabled_devices);
+
+  for (l = enabled_devices; l; l = l->next)
+    gtk_widget_set_device_enabled_internal (widget, GDK_DEVICE (l->data), recurse, TRUE);
+}
+
 /**
  * gtk_widget_realize:
  * @widget: a #GtkWidget
@@ -4266,6 +4382,9 @@ gtk_widget_realize (GtkWidget *widget)
 
       gtk_widget_ensure_style (widget);
 
+      if (priv->style_update_pending)
+        g_signal_emit (widget, widget_signals[STYLE_UPDATED], 0);
+
       g_signal_emit (widget, widget_signals[REALIZE], 0);
 
       gtk_widget_real_set_has_tooltip (widget,
@@ -4286,6 +4405,7 @@ gtk_widget_realize (GtkWidget *widget)
         gdk_window_set_support_multidevice (priv->window, TRUE);
 
       _gtk_widget_enable_device_events (widget);
+      gtk_widget_update_devices_mask (widget, TRUE);
 
       gtk_widget_pop_verify_invariants (widget);
     }
@@ -4348,6 +4468,8 @@ gtk_widget_unrealize (GtkWidget *widget)
  * Normally you would only use this function in widget
  * implementations. You might also use it to schedule a redraw of a
  * #GtkDrawingArea or some portion thereof.
+ *
+ * Since: 3.0
  **/
 void
 gtk_widget_queue_draw_region (GtkWidget      *widget,
@@ -4597,7 +4719,7 @@ gtk_widget_queue_shallow_draw (GtkWidget *widget)
 /**
  * gtk_widget_size_allocate:
  * @widget: a #GtkWidget
- * @allocation: (inout): position and size to be allocated to @widget
+ * @allocation: position and size to be allocated to @widget
  *
  * This function is only used by #GtkContainer subclasses, to assign a size
  * and position to their child widgets.
@@ -5487,6 +5609,8 @@ gtk_cairo_set_event (cairo_t        *cr,
  * use "else if" statements to check which window should be drawn.
  *
  * Returns: %TRUE if @window should be drawn
+ *
+ * Since: 3.0
  **/
 gboolean
 gtk_cairo_should_draw_window (cairo_t *cr,
@@ -5561,6 +5685,8 @@ _gtk_widget_draw_internal (GtkWidget *widget,
  * <note><para>Special purpose widgets may contain special code for
  * rendering to the screen and might appear differently on screen
  * and when rendered using gtk_widget_draw().</para></note>
+ *
+ * Since: 3.0
  **/
 void
 gtk_widget_draw (GtkWidget *widget,
@@ -5712,6 +5838,8 @@ _gtk_widget_get_translation_to_window (GtkWidget      *widget,
  * preparing an expose event to be emitted with the #GtkWidget::draw
  * signal. It is intended to help porting multiwindow widgets from
  * GTK+ 2 to the rendering architecture of GTK+ 3.
+ *
+ * Since: 3.0
  **/
 void
 gtk_cairo_transform_to_window (cairo_t   *cr,
@@ -6841,7 +6969,8 @@ _gtk_widget_update_state_flags (GtkWidget     *widget,
     gtk_widget_set_sensitive (widget,
                               operation != STATE_CHANGE_UNSET);
 
-  flags &= ~(GTK_STATE_FLAG_INSENSITIVE);
+  if (operation != STATE_CHANGE_REPLACE)
+    flags &= ~(GTK_STATE_FLAG_INSENSITIVE);
 
   if (flags != 0 ||
       operation == STATE_CHANGE_REPLACE)
@@ -6947,6 +7076,9 @@ gtk_widget_get_state_flags (GtkWidget *widget)
   if (!gtk_widget_is_sensitive (widget))
     flags |= GTK_STATE_FLAG_INSENSITIVE;
 
+  if (gtk_widget_has_focus (widget))
+    flags |= GTK_STATE_FLAG_FOCUSED;
+
   return flags;
 }
 
@@ -7672,6 +7804,8 @@ gtk_widget_get_parent (GtkWidget *widget)
  * (finally #GtkWidget) would attach the style itself.
  *
  * Since: 2.20
+ *
+ * Deprecated: 3.0. This step is unnecessary with #GtkStyleContext.
  **/
 void
 gtk_widget_style_attach (GtkWidget *widget)
@@ -7710,19 +7844,21 @@ gtk_widget_has_rc_style (GtkWidget *widget)
 /**
  * gtk_widget_set_style:
  * @widget: a #GtkWidget
- * @style: (allow-none): a #GtkStyle, or %NULL to remove the effect of a previous
- *         gtk_widget_set_style() and go back to the default style
+ * @style: (allow-none): a #GtkStyle, or %NULL to remove the effect
+ *     of a previous call to gtk_widget_set_style() and go back to
+ *     the default style
  *
- * Sets the #GtkStyle for a widget (@widget->style). You probably don't
- * want to use this function; it interacts badly with themes, because
- * themes work by replacing the #GtkStyle. Instead, use
- * gtk_widget_modify_style().
+ * Sets the #GtkStyle for a widget (@widget->style).
+ *
+ * You probably don't want to use this function; it interacts
+ * badly with themes, because themes work by replacing the #GtkStyle.
+ * Instead, use gtk_widget_modify_style().
  *
  * Deprecated:3.0: Use #GtkStyleContext instead
- **/
+ */
 void
 gtk_widget_set_style (GtkWidget *widget,
-                     GtkStyle  *style)
+                      GtkStyle  *style)
 {
   g_return_if_fail (GTK_IS_WIDGET (widget));
 }
@@ -7731,13 +7867,14 @@ gtk_widget_set_style (GtkWidget *widget,
  * gtk_widget_ensure_style:
  * @widget: a #GtkWidget
  *
- * Ensures that @widget has a style (@widget->style). Not a very useful
- * function; most of the time, if you want the style, the widget is
- * realized, and realized widgets are guaranteed to have a style
- * already.
+ * Ensures that @widget has a style (@widget->style).
+ *
+ * Not a very useful function; most of the time, if you
+ * want the style, the widget is realized, and realized
+ * widgets are guaranteed to have a style already.
  *
  * Deprecated:3.0: Use #GtkStyleContext instead
- **/
+ */
 void
 gtk_widget_ensure_style (GtkWidget *widget)
 {
@@ -7774,7 +7911,7 @@ gtk_widget_ensure_style (GtkWidget *widget)
  * Return value: (transfer none): the widget's #GtkStyle
  *
  * Deprecated:3.0: Use #GtkStyleContext instead
- **/
+ */
 GtkStyle*
 gtk_widget_get_style (GtkWidget *widget)
 {
@@ -7788,13 +7925,14 @@ gtk_widget_get_style (GtkWidget *widget)
  * @widget: a #GtkWidget
  * @style: the #GtkRcStyle holding the style modifications
  *
- * Modifies style values on the widget. Modifications made using this
- * technique take precedence over style values set via an RC file,
- * however, they will be overriden if a style is explicitely set on
- * the widget using gtk_widget_set_style(). The #GtkRcStyle structure
- * is designed so each field can either be set or unset, so it is
- * possible, using this function, to modify some style values and
- * leave the others unchanged.
+ * Modifies style values on the widget.
+ *
+ * Modifications made using this technique take precedence over
+ * style values set via an RC file, however, they will be overridden
+ * if a style is explicitely set on the widget using gtk_widget_set_style().
+ * The #GtkRcStyle structure is designed so each field can either be
+ * set or unset, so it is possible, using this function, to modify some
+ * style values and leave the others unchanged.
  *
  * Note that modifications made with this function are not cumulative
  * with previous calls to gtk_widget_modify_style() or with such
@@ -7807,18 +7945,18 @@ gtk_widget_get_style (GtkWidget *widget)
  * effect with the initial modifications.
  *
  * Deprecated:3.0: Use #GtkStyleContext with a custom #GtkStyleProvider instead
- **/
+ */
 void
 gtk_widget_modify_style (GtkWidget      *widget,
-                        GtkRcStyle     *style)
+                         GtkRcStyle     *style)
 {
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (GTK_IS_RC_STYLE (style));
 
   g_object_set_qdata_full (G_OBJECT (widget),
-                          quark_rc_style,
-                          gtk_rc_style_copy (style),
-                          (GDestroyNotify) g_object_unref);
+                           quark_rc_style,
+                           gtk_rc_style_copy (style),
+                           (GDestroyNotify) g_object_unref);
 }
 
 /**
@@ -7844,7 +7982,7 @@ gtk_widget_modify_style (GtkWidget      *widget,
  *     g_object_ref().
  *
  * Deprecated:3.0: Use #GtkStyleContext with a custom #GtkStyleProvider instead
- **/
+ */
 GtkRcStyle *
 gtk_widget_get_modifier_style (GtkWidget *widget)
 {
@@ -7858,9 +7996,9 @@ gtk_widget_get_modifier_style (GtkWidget *widget)
     {
       rc_style = gtk_rc_style_new ();
       g_object_set_qdata_full (G_OBJECT (widget),
-                              quark_rc_style,
-                              rc_style,
-                              (GDestroyNotify) g_object_unref);
+                               quark_rc_style,
+                               rc_style,
+                               (GDestroyNotify) g_object_unref);
     }
 
   return rc_style;
@@ -7868,31 +8006,31 @@ gtk_widget_get_modifier_style (GtkWidget *widget)
 
 static void
 gtk_widget_modify_color_component (GtkWidget      *widget,
-                                  GtkRcFlags      component,
-                                  GtkStateType    state,
-                                  const GdkColor *color)
+                                   GtkRcFlags      component,
+                                   GtkStateType    state,
+                                   const GdkColor *color)
 {
   GtkRcStyle *rc_style = gtk_widget_get_modifier_style (widget);
 
   if (color)
     {
       switch (component)
-       {
-       case GTK_RC_FG:
-         rc_style->fg[state] = *color;
-         break;
-       case GTK_RC_BG:
-         rc_style->bg[state] = *color;
-         break;
-       case GTK_RC_TEXT:
-         rc_style->text[state] = *color;
-         break;
-       case GTK_RC_BASE:
-         rc_style->base[state] = *color;
-         break;
-       default:
-         g_assert_not_reached();
-       }
+        {
+        case GTK_RC_FG:
+          rc_style->fg[state] = *color;
+          break;
+        case GTK_RC_BG:
+          rc_style->bg[state] = *color;
+          break;
+        case GTK_RC_TEXT:
+          rc_style->text[state] = *color;
+          break;
+        case GTK_RC_BASE:
+          rc_style->base[state] = *color;
+          break;
+        default:
+          g_assert_not_reached();
+        }
 
       rc_style->color_flags[state] |= component;
     }
@@ -7947,39 +8085,35 @@ _gtk_widget_get_modifier_properties (GtkWidget *widget)
  * @widget: a #GtkWidget
  * @state: the state for which to set the color
  * @color: the color to assign, or %NULL to undo the effect
- *         of previous calls to gtk_widget_override_color()
- *
- * Sets the color to use for a widget. All other style values are left
- * untouched.
- *
- * <note>
- * <para>
- * This API is mostly meant as a quick way for applications to change a
- * widget appearance. If you are developing a widgets library and intend
- * this change to be themeable, it is better done by setting meaningful
- * CSS classes and regions in your widget/container implementation through
- * gtk_style_context_add_class() and gtk_style_context_add_region().
- * </para>
- * <para>
- * This way, your widget library can install a #GtkCssProvider with the
- * %GTK_STYLE_PROVIDER_PRIORITY_FALLBACK priority in order to provide a
- * default styling for those widgets that need so, and this theming may
- * fully overridden by the user's theme.
- * </para>
- * </note>
- *
- * <note>
- * <para>
- * Note that for complex widgets this may bring in
- * undesired results (such as uniform background color everywhere),
- * in these cases it is better to fully style such widgets through a
+ *     of previous calls to gtk_widget_override_color()
+ *
+ * Sets the color to use for a widget.
+ *
+ * All other style values are left untouched.
+ *
+ * <note><para>
+ * This API is mostly meant as a quick way for applications to
+ * change a widget appearance. If you are developing a widgets
+ * library and intend this change to be themeable, it is better
+ * done by setting meaningful CSS classes and regions in your
+ * widget/container implementation through gtk_style_context_add_class()
+ * and gtk_style_context_add_region().
+ * </para><para>
+ * This way, your widget library can install a #GtkCssProvider
+ * with the %GTK_STYLE_PROVIDER_PRIORITY_FALLBACK priority in order
+ * to provide a default styling for those widgets that need so, and
+ * this theming may fully overridden by the user's theme.
+ * </para></note>
+ * <note><para>
+ * Note that for complex widgets this may bring in undesired
+ * results (such as uniform background color everywhere), in
+ * these cases it is better to fully style such widgets through a
  * #GtkCssProvider with the %GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
  * priority.
- * </para>
- * </note>
+ * </para></note>
  *
  * Since: 3.0
- **/
+ */
 void
 gtk_widget_override_color (GtkWidget     *widget,
                            GtkStateFlags  state,
@@ -7998,13 +8132,15 @@ gtk_widget_override_color (GtkWidget     *widget,
  * @widget: a #GtkWidget
  * @state: the state for which to set the background color
  * @color: the color to assign, or %NULL to undo the effect
- *         of previous calls to gtk_widget_override_background_color()
+ *     of previous calls to gtk_widget_override_background_color()
  *
- * Sets the background color to use for a widget. All other style values
- * are left untouched. See gtk_widget_override_color().
+ * Sets the background color to use for a widget.
+ *
+ * All other style values are left untouched.
+ * See gtk_widget_override_color().
  *
  * Since: 3.0
- **/
+ */
 void
 gtk_widget_override_background_color (GtkWidget     *widget,
                                       GtkStateFlags  state,
@@ -8022,14 +8158,13 @@ gtk_widget_override_background_color (GtkWidget     *widget,
  * gtk_widget_override_font:
  * @widget: a #GtkWidget
  * @font_desc: the font descriptiong to use, or %NULL to undo
- *             the effect of previous calls to
- *             gtk_widget_override_font().
+ *     the effect of previous calls to gtk_widget_override_font()
  *
  * Sets the font to use for a widget. All other style values are
  * left untouched. See gtk_widget_override_color().
  *
  * Since: 3.0
- **/
+ */
 void
 gtk_widget_override_font (GtkWidget                  *widget,
                           const PangoFontDescription *font_desc)
@@ -8046,16 +8181,18 @@ gtk_widget_override_font (GtkWidget                  *widget,
  * gtk_widget_override_symbolic_color:
  * @widget: a #GtkWidget
  * @name: the name of the symbolic color to modify
- * @color: (allow-none): the color to assign (does not need to be allocated),
- *         or %NULL to undo the effect of previous calls to
- *         gtk_widget_override_symbolic_color().
+ * @color: (allow-none): the color to assign (does not need
+ *     to be allocated), or %NULL to undo the effect of previous
+ *     calls to gtk_widget_override_symbolic_color()
+ *
+ * Sets a symbolic color for a widget.
  *
- * Sets a symbolic color for a widget, All other style values are left
- * untouched. See gtk_widget_override_color() for overriding the foreground
+ * All other style values are left untouched.
+ * See gtk_widget_override_color() for overriding the foreground
  * or background color.
  *
  * Since: 3.0
- **/
+ */
 void
 gtk_widget_override_symbolic_color (GtkWidget     *widget,
                                     const gchar   *name,
@@ -8113,19 +8250,20 @@ gtk_widget_override_cursor (GtkWidget     *widget,
  * @widget: a #GtkWidget
  * @state: the state for which to set the foreground color
  * @color: (allow-none): the color to assign (does not need to be allocated),
- *         or %NULL to undo the effect of previous calls to
- *         of gtk_widget_modify_fg().
+ *     or %NULL to undo the effect of previous calls to
+ *     of gtk_widget_modify_fg().
  *
  * Sets the foreground color for a widget in a particular state.
- * All other style values are left untouched. See also
- * gtk_widget_modify_style().
+ *
+ * All other style values are left untouched.
+ * See also gtk_widget_modify_style().
  *
  * Deprecated:3.0: Use gtk_widget_override_color() instead
- **/
+ */
 void
 gtk_widget_modify_fg (GtkWidget      *widget,
-                     GtkStateType    state,
-                     const GdkColor *color)
+                      GtkStateType    state,
+                      const GdkColor *color)
 {
   GtkStateFlags flags;
   GdkRGBA rgba;
@@ -8159,38 +8297,43 @@ gtk_widget_modify_fg (GtkWidget      *widget,
       rgba.blue = color->blue / 65535.;
       rgba.alpha = 1;
 
-      gtk_widget_override_color (widget, state, &rgba);
+      gtk_widget_override_color (widget, flags, &rgba);
     }
   else
-    gtk_widget_override_color (widget, state, NULL);
+    gtk_widget_override_color (widget, flags, NULL);
 }
 
 /**
  * gtk_widget_modify_bg:
  * @widget: a #GtkWidget
  * @state: the state for which to set the background color
- * @color: (allow-none): the color to assign (does not need to be allocated),
- *         or %NULL to undo the effect of previous calls to
- *         of gtk_widget_modify_bg().
+ * @color: (allow-none): the color to assign (does not need
+ *     to be allocated), or %NULL to undo the effect of previous
+ *     calls to of gtk_widget_modify_bg().
  *
  * Sets the background color for a widget in a particular state.
- * All other style values are left untouched. See also
- * gtk_widget_modify_style().
  *
- * Note that "no window" widgets (which have the %GTK_NO_WINDOW flag set)
- * draw on their parent container's window and thus may not draw any
- * background themselves. This is the case for e.g. #GtkLabel. To modify
- * the background of such widgets, you have to set the background color
- * on their parent; if you want to set the background of a rectangular
- * area around a label, try placing the label in a #GtkEventBox widget
- * and setting the background color on that.
+ * All other style values are left untouched.
+ * See also gtk_widget_modify_style().
+ *
+ * <note><para>
+ * Note that "no window" widgets (which have the %GTK_NO_WINDOW
+ * flag set) draw on their parent container's window and thus may
+ * not draw any background themselves. This is the case for e.g.
+ * #GtkLabel.
+ * </para><para>
+ * To modify the background of such widgets, you have to set the
+ * background color on their parent; if you want to set the background
+ * of a rectangular area around a label, try placing the label in
+ * a #GtkEventBox widget and setting the background color on that.
+ * </para></note>
  *
  * Deprecated:3.0: Use gtk_widget_override_background_color() instead
- **/
+ */
 void
 gtk_widget_modify_bg (GtkWidget      *widget,
-                     GtkStateType    state,
-                     const GdkColor *color)
+                      GtkStateType    state,
+                      const GdkColor *color)
 {
   GtkStateFlags flags;
   GdkRGBA rgba;
@@ -8224,32 +8367,34 @@ gtk_widget_modify_bg (GtkWidget      *widget,
       rgba.blue = color->blue / 65535.;
       rgba.alpha = 1;
 
-      gtk_widget_override_background_color (widget, state, &rgba);
+      gtk_widget_override_background_color (widget, flags, &rgba);
     }
   else
-    gtk_widget_override_background_color (widget, state, NULL);
+    gtk_widget_override_background_color (widget, flags, NULL);
 }
 
 /**
  * gtk_widget_modify_text:
  * @widget: a #GtkWidget
  * @state: the state for which to set the text color
- * @color: (allow-none): the color to assign (does not need to be allocated),
- *         or %NULL to undo the effect of previous calls to
- *         of gtk_widget_modify_text().
+ * @color: (allow-none): the color to assign (does not need to
+ *     be allocated), or %NULL to undo the effect of previous
+ *     calls to of gtk_widget_modify_text().
  *
- * Sets the text color for a widget in a particular state.  All other
- * style values are left untouched. The text color is the foreground
- * color used along with the base color (see gtk_widget_modify_base())
- * for widgets such as #GtkEntry and #GtkTextView. See also
- * gtk_widget_modify_style().
+ * Sets the text color for a widget in a particular state.
+ *
+ * All other style values are left untouched.
+ * The text color is the foreground color used along with the
+ * base color (see gtk_widget_modify_base()) for widgets such
+ * as #GtkEntry and #GtkTextView.
+ * See also gtk_widget_modify_style().
  *
  * Deprecated:3.0: Use gtk_widget_override_color() instead
- **/
+ */
 void
 gtk_widget_modify_text (GtkWidget      *widget,
-                       GtkStateType    state,
-                       const GdkColor *color)
+                        GtkStateType    state,
+                        const GdkColor *color)
 {
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
@@ -8261,9 +8406,9 @@ gtk_widget_modify_text (GtkWidget      *widget,
  * gtk_widget_modify_base:
  * @widget: a #GtkWidget
  * @state: the state for which to set the base color
- * @color: (allow-none): the color to assign (does not need to be allocated),
- *         or %NULL to undo the effect of previous calls to
- *         of gtk_widget_modify_base().
+ * @color: (allow-none): the color to assign (does not need to
+ *     be allocated), or %NULL to undo the effect of previous
+ *     calls to of gtk_widget_modify_base().
  *
  * Sets the base color for a widget in a particular state.
  * All other style values are left untouched. The base color
@@ -8271,20 +8416,24 @@ gtk_widget_modify_text (GtkWidget      *widget,
  * (see gtk_widget_modify_text()) for widgets such as #GtkEntry
  * and #GtkTextView. See also gtk_widget_modify_style().
  *
- * Note that "no window" widgets (which have the %GTK_NO_WINDOW flag set)
- * draw on their parent container's window and thus may not draw any
- * background themselves. This is the case for e.g. #GtkLabel. To modify
- * the background of such widgets, you have to set the base color on their
- * parent; if you want to set the background of a rectangular area around
- * a label, try placing the label in a #GtkEventBox widget and setting
- * the base color on that.
+ * <note><para>
+ * Note that "no window" widgets (which have the %GTK_NO_WINDOW
+ * flag set) draw on their parent container's window and thus may
+ * not draw any background themselves. This is the case for e.g.
+ * #GtkLabel.
+ * </para><para>
+ * To modify the background of such widgets, you have to set the
+ * base color on their parent; if you want to set the background
+ * of a rectangular area around a label, try placing the label in
+ * a #GtkEventBox widget and setting the base color on that.
+ * </para></note>
  *
  * Deprecated:3.0: Use gtk_widget_override_background_color() instead
- **/
+ */
 void
 gtk_widget_modify_base (GtkWidget      *widget,
-                       GtkStateType    state,
-                       const GdkColor *color)
+                        GtkStateType    state,
+                        const GdkColor *color)
 {
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
@@ -8296,25 +8445,27 @@ gtk_widget_modify_base (GtkWidget      *widget,
  * gtk_widget_modify_cursor:
  * @widget: a #GtkWidget
  * @primary: the color to use for primary cursor (does not need to be
- *           allocated), or %NULL to undo the effect of previous calls to
- *           of gtk_widget_modify_cursor().
+ *     allocated), or %NULL to undo the effect of previous calls to
+ *     of gtk_widget_modify_cursor().
  * @secondary: the color to use for secondary cursor (does not need to be
- *             allocated), or %NULL to undo the effect of previous calls to
- *             of gtk_widget_modify_cursor().
+ *     allocated), or %NULL to undo the effect of previous calls to
+ *     of gtk_widget_modify_cursor().
  *
  * Sets the cursor color to use in a widget, overriding the
  * #GtkWidget:cursor-color and #GtkWidget:secondary-cursor-color
- * style properties. All other style values are left untouched.
+ * style properties.
+ *
+ * All other style values are left untouched.
  * See also gtk_widget_modify_style().
  *
  * Since: 2.12
  *
  * Deprecated: 3.0. Use gtk_widget_override_cursor() instead.
- **/
+ */
 void
 gtk_widget_modify_cursor (GtkWidget      *widget,
-                         const GdkColor *primary,
-                         const GdkColor *secondary)
+                          const GdkColor *primary,
+                          const GdkColor *secondary)
 {
   GdkRGBA primary_rgba, secondary_rgba;
 
@@ -8336,17 +8487,19 @@ gtk_widget_modify_cursor (GtkWidget      *widget,
 /**
  * gtk_widget_modify_font:
  * @widget: a #GtkWidget
- * @font_desc: (allow-none): the font description to use, or %NULL to undo
- *   the effect of previous calls to gtk_widget_modify_font().
+ * @font_desc: (allow-none): the font description to use, or %NULL
+ *     to undo the effect of previous calls to gtk_widget_modify_font()
  *
- * Sets the font to use for a widget.  All other style values are left
- * untouched. See also gtk_widget_modify_style().
+ * Sets the font to use for a widget.
+ *
+ * All other style values are left untouched.
+ * See also gtk_widget_modify_style().
  *
  * Deprecated:3.0: Use gtk_widget_override_font() instead
- **/
+ */
 void
 gtk_widget_modify_font (GtkWidget            *widget,
-                       PangoFontDescription *font_desc)
+                        PangoFontDescription *font_desc)
 {
   g_return_if_fail (GTK_IS_WIDGET (widget));
 
@@ -8633,6 +8786,7 @@ gtk_widget_get_default_style (void)
 }
 
 #ifdef G_ENABLE_DEBUG
+
 /* Verify invariants, see docs/widget_system.txt for notes on much of
  * this.  Invariants may be temporarily broken while we're in the
  * process of updating state, of course, so you can only
@@ -9003,23 +9157,20 @@ gtk_widget_render_icon_pixbuf (GtkWidget   *widget,
                                const gchar *stock_id,
                                GtkIconSize  size)
 {
-  GtkWidgetPrivate *priv;
+  GtkStyleContext *context;
   GtkIconSet *icon_set;
 
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
   g_return_val_if_fail (stock_id != NULL, NULL);
   g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID || size == -1, NULL);
 
-  priv = widget->priv;
-
-  gtk_widget_ensure_style (widget);
-
-  icon_set = gtk_style_context_lookup_icon_set (priv->context, stock_id);
+  context = gtk_widget_get_style_context (widget);
+  icon_set = gtk_style_context_lookup_icon_set (context, stock_id);
 
   if (icon_set == NULL)
     return NULL;
 
-  return gtk_icon_set_render_icon_pixbuf (icon_set, priv->context, size);
+  return gtk_icon_set_render_icon_pixbuf (icon_set, context, size);
 }
 
 /**
@@ -9063,6 +9214,16 @@ gtk_widget_render_icon (GtkWidget      *widget,
  * @parent_window: the new parent window.
  *
  * Sets a non default parent window for @widget.
+ *
+ * For GtkWindow classes, setting a @parent_window effects whether 
+ * the window is a toplevel window or can be embedded into other
+ * widgets.
+ *
+ * <note><para>
+ * For GtkWindow classes, this needs to be called before the
+ * window is realized.
+ * </para></note>
+ * 
  **/
 void
 gtk_widget_set_parent_window   (GtkWidget           *widget,
@@ -9083,6 +9244,13 @@ gtk_widget_set_parent_window   (GtkWidget           *widget,
        g_object_unref (old_parent_window);
       if (parent_window)
        g_object_ref (parent_window);
+
+      /* Unset toplevel flag when adding a parent window to a widget,
+       * this is the primary entry point to allow toplevels to be
+       * embeddable.
+       */
+      if (GTK_IS_WINDOW (widget) && !GTK_IS_PLUG (widget))
+       _gtk_window_set_is_toplevel (GTK_WINDOW (widget), parent_window == NULL);
     }
 }
 
@@ -9720,6 +9888,53 @@ gtk_widget_set_device_events (GtkWidget    *widget,
   g_hash_table_insert (device_events, device, GUINT_TO_POINTER (events));
 }
 
+/**
+ * gtk_widget_enable_device:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ *
+ * Enables a #GdkDevice to interact with @widget and
+ * all its children, it does so by descending through
+ * the #GdkWindow hierarchy and enabling the same mask
+ * that is has for core events (i.e. the one that
+ * gdk_window_get_events() returns).
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_set_device_enabled (GtkWidget *widget,
+                               GdkDevice *device,
+                               gboolean   enabled)
+{
+  GList *enabled_devices;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (GDK_IS_DEVICE (device));
+
+  enabled_devices = g_object_get_qdata (G_OBJECT (widget), quark_enabled_devices);
+  enabled_devices = g_list_append (enabled_devices, device);
+
+  g_object_set_qdata_full (G_OBJECT (widget), quark_enabled_devices,
+                           enabled_devices, (GDestroyNotify) g_list_free);;
+
+  if (gtk_widget_get_realized (widget))
+    gtk_widget_set_device_enabled_internal (widget, device, TRUE, enabled);
+}
+
+gboolean
+gtk_widget_get_device_enabled (GtkWidget *widget,
+                               GdkDevice *device)
+{
+  GList *enabled_devices;
+
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+  g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
+
+  enabled_devices = g_object_get_qdata (G_OBJECT (widget), quark_enabled_devices);
+
+  return g_list_find (enabled_devices, device) != NULL;
+}
+
 static void
 gtk_widget_add_events_internal_list (GtkWidget *widget,
                                      GdkDevice *device,
@@ -9789,7 +10004,10 @@ gtk_widget_add_events (GtkWidget *widget,
                       GINT_TO_POINTER (old_events | events));
 
   if (gtk_widget_get_realized (widget))
-    gtk_widget_add_events_internal (widget, NULL, events);
+    {
+      gtk_widget_add_events_internal (widget, NULL, events);
+      gtk_widget_update_devices_mask (widget, FALSE);
+    }
 
   g_object_notify (G_OBJECT (widget), "events");
 }
@@ -10969,8 +11187,8 @@ _gtk_widget_synthesize_crossing (GtkWidget       *from,
 }
 
 static void
-gtk_widget_propagate_state (GtkWidget           *widget,
-                           GtkStateData        *data)
+gtk_widget_propagate_state (GtkWidget    *widget,
+                            GtkStateData *data)
 {
   GtkWidgetPrivate *priv = widget->priv;
   GtkStateFlags new_flags, old_flags = priv->state_flags;
@@ -11003,7 +11221,7 @@ gtk_widget_propagate_state (GtkWidget           *widget,
       window = gtk_widget_get_toplevel (widget);
 
       if (window && gtk_widget_is_toplevel (window))
-       gtk_window_set_focus (GTK_WINDOW (window), NULL);
+        gtk_window_set_focus (GTK_WINDOW (window), NULL);
     }
 
   new_flags = gtk_widget_get_state_flags (widget);
@@ -11013,7 +11231,7 @@ gtk_widget_propagate_state (GtkWidget           *widget,
       g_object_ref (widget);
 
       if (!gtk_widget_is_sensitive (widget) && gtk_widget_has_grab (widget))
-       gtk_grab_remove (widget);
+        gtk_grab_remove (widget);
 
       g_signal_emit (widget, widget_signals[STATE_CHANGED], 0, old_state);
       g_signal_emit (widget, widget_signals[STATE_FLAGS_CHANGED], 0, old_flags);
@@ -11059,7 +11277,7 @@ gtk_widget_propagate_state (GtkWidget           *widget,
           data->parent_sensitive = gtk_widget_is_sensitive (widget);
 
           /* Do not propagate insensitive state further */
-          data->flags &= ~(GTK_STATE_FLAG_INSENSITIVE);
+          data->flags &= ~(GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_FOCUSED);
 
           if (data->use_forall)
             gtk_container_forall (GTK_CONTAINER (widget),
@@ -11076,10 +11294,8 @@ gtk_widget_propagate_state (GtkWidget           *widget,
           gtk_widget_get_mapped (widget))
         {
           gint diff, flag = 1;
-          GdkWindow *window;
 
           diff = old_flags ^ new_flags;
-          window = gtk_widget_get_window (widget);
 
           while (diff != 0)
             {
@@ -11264,7 +11480,7 @@ gtk_widget_input_shape_combine_region (GtkWidget *widget,
  */
 
 /**
- * gtk_widget_class_install_style_property_parser:
+ * gtk_widget_class_install_style_property_parser: (skip)
  * @klass: a #GtkWidgetClass
  * @pspec: the #GParamSpec for the style property
  * @parser: the parser for the style property
@@ -11320,8 +11536,8 @@ gtk_widget_class_install_style_property (GtkWidgetClass *klass,
  * gtk_widget_class_find_style_property:
  * @klass: a #GtkWidgetClass
  * @property_name: the name of the style property to find
- * @returns: (allow-none): the #GParamSpec of the style property or %NULL if @class has no
- *   style property with that name.
+ * @returns: (transfer none): the #GParamSpec of the style property or
+ *   %NULL if @class has no style property with that name.
  *
  * Finds a style property of a widget class by name.
  *
@@ -11343,8 +11559,9 @@ gtk_widget_class_find_style_property (GtkWidgetClass *klass,
  * gtk_widget_class_list_style_properties:
  * @klass: a #GtkWidgetClass
  * @n_properties: location to return the number of style properties found
- * @returns: an newly allocated array of #GParamSpec*. The array must
- *       be freed with g_free().
+ * @returns: (array length=n_properties) (transfer container): an
+ *       newly allocated array of #GParamSpec*. The array must be
+ *       freed with g_free().
  *
  * Returns all style properties of a widget class.
  *
@@ -13710,6 +13927,11 @@ _gtk_widget_set_has_focus (GtkWidget *widget,
                            gboolean   has_focus)
 {
   widget->priv->has_focus = has_focus;
+
+  if (has_focus)
+    gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_FOCUSED, FALSE);
+  else
+    gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_FOCUSED);
 }
 
 /**
@@ -13927,8 +14149,22 @@ gtk_widget_get_path (GtkWidget *widget)
         gtk_widget_path_iter_set_name (widget->priv->path, pos, widget->priv->name);
 
       if (widget->priv->context)
-        gtk_style_context_set_path (widget->priv->context,
-                                    widget->priv->path);
+        {
+          GList *classes, *l;
+
+          /* Also add any persistent classes in
+           * the style context the widget path
+           */
+          classes = gtk_style_context_list_classes (widget->priv->context);
+
+          for (l = classes; l; l = l->next)
+            gtk_widget_path_iter_add_class (widget->priv->path, pos, l->data);
+
+          gtk_style_context_set_path (widget->priv->context,
+                                      widget->priv->path);
+
+          g_list_free (classes);
+        }
     }
 
   return widget->priv->path;
@@ -13941,7 +14177,16 @@ style_context_changed (GtkStyleContext *context,
   GtkWidget *widget = user_data;
 
   gtk_widget_update_pango_context (widget);
-  g_signal_emit (widget, widget_signals[STYLE_UPDATED], 0);
+
+  if (gtk_widget_get_realized (widget))
+    g_signal_emit (widget, widget_signals[STYLE_UPDATED], 0);
+  else
+    {
+      /* Compress all style updates so it
+       * is only emitted once pre-realize.
+       */
+      widget->priv->style_update_pending = TRUE;
+    }
 
   if (widget->priv->anchored)
     gtk_widget_queue_resize (widget);