[gtk] Replace stateful actions by property actions



commit d1f4068b9471184bd431f04b87c3201fd721d898
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Jun 22 20:18:05 2019 +0000

    Replace stateful actions by property actions
    
    The only cases of stateful actions we've seen
    so far have been boolean properties, and we
    don't really want to add much state handling
    API, so lets just go with property actions
    for now.
    
    Adapt the only user in GtkText.

 docs/reference/gtk/gtk4-sections.txt |   5 +-
 gtk/gsettings-mapping.c              | 592 +++++++++++++++++++++++++++++++++++
 gtk/gsettings-mapping.h              |  34 ++
 gtk/gtkactionmuxer.c                 | 174 +++++++++-
 gtk/gtkactionmuxerprivate.h          |   9 +-
 gtk/gtktext.c                        |  48 +--
 gtk/gtkwidget.c                      | 175 ++++++-----
 gtk/gtkwidget.h                      |  46 +--
 gtk/meson.build                      |   1 +
 9 files changed, 899 insertions(+), 185 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index cfb88c7efd..8f3d7a9f02 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4630,13 +4630,10 @@ gtk_widget_insert_action_group
 gtk_widget_activate_action
 gtk_widget_activate_default
 GtkWidgetActionActivateFunc
-GtkWidgetActionSetStateFunc
-GtkWidgetActionGetStateFunc
 gtk_widget_class_install_action
-gtk_widget_class_install_stateful_action
+gtk_widget_class_install_property_action
 gtk_widget_class_query_action
 gtk_widget_action_enabled_changed
-gtk_widget_action_state_changed
 
 <SUBSECTION Standard>
 GTK_WIDGET
diff --git a/gtk/gsettings-mapping.c b/gtk/gsettings-mapping.c
new file mode 100644
index 0000000000..8c64b02a50
--- /dev/null
+++ b/gtk/gsettings-mapping.c
@@ -0,0 +1,592 @@
+/*
+ * Copyright © 2010 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Vincent Untz <vuntz gnome org>
+ */
+
+#include "config.h"
+
+#include "gsettings-mapping.h"
+
+static GVariant *
+g_settings_set_mapping_int (const GValue       *value,
+                            const GVariantType *expected_type)
+{
+  GVariant *variant = NULL;
+  gint64 l;
+
+  if (G_VALUE_HOLDS_INT (value))
+    l = g_value_get_int (value);
+  else if (G_VALUE_HOLDS_INT64 (value))
+    l = g_value_get_int64 (value);
+  else
+    return NULL;
+
+  if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
+    {
+      if (G_MININT16 <= l && l <= G_MAXINT16)
+        variant = g_variant_new_int16 ((gint16) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
+    {
+      if (0 <= l && l <= G_MAXUINT16)
+        variant = g_variant_new_uint16 ((guint16) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
+    {
+      if (G_MININT32 <= l && l <= G_MAXINT32)
+        variant = g_variant_new_int32 ((gint) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
+    {
+      if (0 <= l && l <= G_MAXUINT32)
+        variant = g_variant_new_uint32 ((guint) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
+    {
+      if (G_MININT64 <= l && l <= G_MAXINT64)
+        variant = g_variant_new_int64 ((gint64) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
+    {
+      if (0 <= l && l <= G_MAXUINT64)
+        variant = g_variant_new_uint64 ((guint64) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
+    {
+      if (0 <= l && l <= G_MAXUINT32)
+        variant = g_variant_new_handle ((guint) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
+    variant = g_variant_new_double ((gdouble) l);
+
+  return variant;
+}
+
+static GVariant *
+g_settings_set_mapping_float (const GValue       *value,
+                              const GVariantType *expected_type)
+{
+  GVariant *variant = NULL;
+  gdouble d;
+  gint64 l;
+
+  if (G_VALUE_HOLDS_DOUBLE (value))
+    d = g_value_get_double (value);
+  else
+    return NULL;
+
+  l = (gint64) d;
+  if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
+    {
+      if (G_MININT16 <= l && l <= G_MAXINT16)
+        variant = g_variant_new_int16 ((gint16) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
+    {
+      if (0 <= l && l <= G_MAXUINT16)
+        variant = g_variant_new_uint16 ((guint16) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
+    {
+      if (G_MININT32 <= l && l <= G_MAXINT32)
+        variant = g_variant_new_int32 ((gint) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
+    {
+      if (0 <= l && l <= G_MAXUINT32)
+        variant = g_variant_new_uint32 ((guint) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
+    {
+      if (G_MININT64 <= l && l <= G_MAXINT64)
+        variant = g_variant_new_int64 ((gint64) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
+    {
+      if (0 <= l && l <= G_MAXUINT64)
+        variant = g_variant_new_uint64 ((guint64) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
+    {
+      if (0 <= l && l <= G_MAXUINT32)
+        variant = g_variant_new_handle ((guint) l);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
+    variant = g_variant_new_double ((gdouble) d);
+
+  return variant;
+}
+static GVariant *
+g_settings_set_mapping_unsigned_int (const GValue       *value,
+                                     const GVariantType *expected_type)
+{
+  GVariant *variant = NULL;
+  guint64 u;
+
+  if (G_VALUE_HOLDS_UINT (value))
+    u = g_value_get_uint (value);
+  else if (G_VALUE_HOLDS_UINT64 (value))
+    u = g_value_get_uint64 (value);
+  else
+    return NULL;
+
+  if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
+    {
+      if (u <= G_MAXINT16)
+        variant = g_variant_new_int16 ((gint16) u);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
+    {
+      if (u <= G_MAXUINT16)
+        variant = g_variant_new_uint16 ((guint16) u);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
+    {
+      if (u <= G_MAXINT32)
+        variant = g_variant_new_int32 ((gint) u);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
+    {
+      if (u <= G_MAXUINT32)
+        variant = g_variant_new_uint32 ((guint) u);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
+    {
+      if (u <= G_MAXINT64)
+        variant = g_variant_new_int64 ((gint64) u);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
+    {
+      if (u <= G_MAXUINT64)
+        variant = g_variant_new_uint64 ((guint64) u);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
+    {
+      if (u <= G_MAXUINT32)
+        variant = g_variant_new_handle ((guint) u);
+    }
+  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
+    variant = g_variant_new_double ((gdouble) u);
+
+  return variant;
+}
+
+static gboolean
+g_settings_get_mapping_int (GValue   *value,
+                            GVariant *variant)
+{
+  const GVariantType *type;
+  gint64 l;
+
+  type = g_variant_get_type (variant);
+
+  if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
+    l = g_variant_get_int16 (variant);
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
+    l = g_variant_get_int32 (variant);
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
+    l = g_variant_get_int64 (variant);
+  else
+    return FALSE;
+
+  if (G_VALUE_HOLDS_INT (value))
+    {
+      g_value_set_int (value, l);
+      return (G_MININT32 <= l && l <= G_MAXINT32);
+    }
+  else if (G_VALUE_HOLDS_UINT (value))
+    {
+      g_value_set_uint (value, l);
+      return (0 <= l && l <= G_MAXUINT32);
+    }
+  else if (G_VALUE_HOLDS_INT64 (value))
+    {
+      g_value_set_int64 (value, l);
+      return (G_MININT64 <= l && l <= G_MAXINT64);
+    }
+  else if (G_VALUE_HOLDS_UINT64 (value))
+    {
+      g_value_set_uint64 (value, l);
+      return (0 <= l && l <= G_MAXUINT64);
+    }
+  else if (G_VALUE_HOLDS_DOUBLE (value))
+    {
+      g_value_set_double (value, l);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+g_settings_get_mapping_float (GValue   *value,
+                              GVariant *variant)
+{
+  const GVariantType *type;
+  gdouble d;
+  gint64 l;
+
+  type = g_variant_get_type (variant);
+
+  if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
+    d = g_variant_get_double (variant);
+  else
+    return FALSE;
+
+  l = (gint64)d;
+  if (G_VALUE_HOLDS_INT (value))
+    {
+      g_value_set_int (value, l);
+      return (G_MININT32 <= l && l <= G_MAXINT32);
+    }
+  else if (G_VALUE_HOLDS_UINT (value))
+    {
+      g_value_set_uint (value, l);
+      return (0 <= l && l <= G_MAXUINT32);
+    }
+  else if (G_VALUE_HOLDS_INT64 (value))
+    {
+      g_value_set_int64 (value, l);
+      return (G_MININT64 <= l && l <= G_MAXINT64);
+    }
+  else if (G_VALUE_HOLDS_UINT64 (value))
+    {
+      g_value_set_uint64 (value, l);
+      return (0 <= l && l <= G_MAXUINT64);
+    }
+  else if (G_VALUE_HOLDS_DOUBLE (value))
+    {
+      g_value_set_double (value, d);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+static gboolean
+g_settings_get_mapping_unsigned_int (GValue   *value,
+                                     GVariant *variant)
+{
+  const GVariantType *type;
+  guint64 u;
+
+  type = g_variant_get_type (variant);
+
+  if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
+    u = g_variant_get_uint16 (variant);
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
+    u = g_variant_get_uint32 (variant);
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
+    u = g_variant_get_uint64 (variant);
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
+    u = g_variant_get_handle (variant);
+  else
+    return FALSE;
+
+  if (G_VALUE_HOLDS_INT (value))
+    {
+      g_value_set_int (value, u);
+      return (u <= G_MAXINT32);
+    }
+  else if (G_VALUE_HOLDS_UINT (value))
+    {
+      g_value_set_uint (value, u);
+      return (u <= G_MAXUINT32);
+    }
+  else if (G_VALUE_HOLDS_INT64 (value))
+    {
+      g_value_set_int64 (value, u);
+      return (u <= G_MAXINT64);
+    }
+  else if (G_VALUE_HOLDS_UINT64 (value))
+    {
+      g_value_set_uint64 (value, u);
+      return (u <= G_MAXUINT64);
+    }
+  else if (G_VALUE_HOLDS_DOUBLE (value))
+    {
+      g_value_set_double (value, u);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+GVariant *
+g_settings_set_mapping (const GValue       *value,
+                        const GVariantType *expected_type,
+                        gpointer            user_data)
+{
+  gchar *type_string;
+
+  if (G_VALUE_HOLDS_BOOLEAN (value))
+    {
+      if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
+        return g_variant_new_boolean (g_value_get_boolean (value));
+    }
+
+  else if (G_VALUE_HOLDS_CHAR (value)  ||
+           G_VALUE_HOLDS_UCHAR (value))
+    {
+      if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
+        {
+          if (G_VALUE_HOLDS_CHAR (value))
+            return g_variant_new_byte (g_value_get_schar (value));
+          else
+            return g_variant_new_byte (g_value_get_uchar (value));
+        }
+    }
+
+  else if (G_VALUE_HOLDS_INT (value)   ||
+           G_VALUE_HOLDS_INT64 (value))
+    return g_settings_set_mapping_int (value, expected_type);
+
+  else if (G_VALUE_HOLDS_DOUBLE (value))
+    return g_settings_set_mapping_float (value, expected_type);
+
+  else if (G_VALUE_HOLDS_UINT (value)  ||
+           G_VALUE_HOLDS_UINT64 (value))
+    return g_settings_set_mapping_unsigned_int (value, expected_type);
+
+  else if (G_VALUE_HOLDS_STRING (value))
+    {
+      if (g_value_get_string (value) == NULL)
+        return NULL;
+      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
+        return g_variant_new_string (g_value_get_string (value));
+      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING))
+        return g_variant_new_bytestring (g_value_get_string (value));
+      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
+        return g_variant_new_object_path (g_value_get_string (value));
+      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
+        return g_variant_new_signature (g_value_get_string (value));
+    }
+
+  else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
+    {
+      if (g_value_get_boxed (value) == NULL)
+        return NULL;
+      return g_variant_new_strv ((const gchar **) g_value_get_boxed (value),
+                                 -1);
+    }
+
+  else if (G_VALUE_HOLDS_ENUM (value))
+    {
+      GEnumValue *enumval;
+      GEnumClass *eclass;
+
+      /* GParamSpecEnum holds a ref on the class so we just peek... */
+      eclass = g_type_class_peek (G_VALUE_TYPE (value));
+      enumval = g_enum_get_value (eclass, g_value_get_enum (value));
+
+      if (enumval)
+        return g_variant_new_string (enumval->value_nick);
+      else
+        return NULL;
+    }
+
+  else if (G_VALUE_HOLDS_FLAGS (value))
+    {
+      GVariantBuilder builder;
+      GFlagsValue *flagsval;
+      GFlagsClass *fclass;
+      guint flags;
+
+      fclass = g_type_class_peek (G_VALUE_TYPE (value));
+      flags = g_value_get_flags (value);
+
+      g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+      while (flags)
+        {
+          flagsval = g_flags_get_first_value (fclass, flags);
+
+          if (flagsval == NULL)
+            {
+              g_variant_builder_clear (&builder);
+              return NULL;
+            }
+
+          g_variant_builder_add (&builder, "s", flagsval->value_nick);
+          flags &= ~flagsval->value;
+        }
+
+      return g_variant_builder_end (&builder);
+    }
+
+  type_string = g_variant_type_dup_string (expected_type);
+  g_critical ("No GSettings bind handler for type \"%s\".", type_string);
+  g_free (type_string);
+
+  return NULL;
+}
+
+gboolean
+g_settings_get_mapping (GValue   *value,
+                        GVariant *variant,
+                        gpointer  user_data)
+{
+  if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
+    {
+      if (!G_VALUE_HOLDS_BOOLEAN (value))
+        return FALSE;
+      g_value_set_boolean (value, g_variant_get_boolean (variant));
+      return TRUE;
+    }
+
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE))
+    {
+      if (G_VALUE_HOLDS_UCHAR (value))
+        g_value_set_uchar (value, g_variant_get_byte (variant));
+      else if (G_VALUE_HOLDS_CHAR (value))
+        g_value_set_schar (value, (gint8)g_variant_get_byte (variant));
+      else
+        return FALSE;
+      return TRUE;
+    }
+
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16)  ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32)  ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64))
+    return g_settings_get_mapping_int (value, variant);
+
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
+    return g_settings_get_mapping_float (value, variant);
+
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64) ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
+    return g_settings_get_mapping_unsigned_int (value, variant);
+
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)      ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH) ||
+           g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE))
+    {
+      if (G_VALUE_HOLDS_STRING (value))
+        {
+          g_value_set_string (value, g_variant_get_string (variant, NULL));
+          return TRUE;
+        }
+
+      else if (G_VALUE_HOLDS_ENUM (value))
+        {
+          GEnumClass *eclass;
+          GEnumValue *evalue;
+          const gchar *nick;
+
+          /* GParamSpecEnum holds a ref on the class so we just peek... */
+          eclass = g_type_class_peek (G_VALUE_TYPE (value));
+          nick = g_variant_get_string (variant, NULL);
+          evalue = g_enum_get_value_by_nick (eclass, nick);
+
+          if (evalue)
+            {
+             g_value_set_enum (value, evalue->value);
+             return TRUE;
+            }
+
+          g_warning ("Unable to look up enum nick ‘%s’ via GType", nick);
+          return FALSE;
+        }
+    }
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("as")))
+    {
+      if (G_VALUE_HOLDS (value, G_TYPE_STRV))
+        {
+          g_value_take_boxed (value, g_variant_dup_strv (variant, NULL));
+          return TRUE;
+        }
+
+      else if (G_VALUE_HOLDS_FLAGS (value))
+        {
+          GFlagsClass *fclass;
+          GFlagsValue *fvalue;
+          const gchar *nick;
+          GVariantIter iter;
+          guint flags = 0;
+
+          fclass = g_type_class_peek (G_VALUE_TYPE (value));
+
+          g_variant_iter_init (&iter, variant);
+          while (g_variant_iter_next (&iter, "&s", &nick))
+            {
+              fvalue = g_flags_get_value_by_nick (fclass, nick);
+
+              if (fvalue)
+                flags |= fvalue->value;
+
+              else
+                {
+                  g_warning ("Unable to lookup flags nick '%s' via GType",
+                             nick);
+                  return FALSE;
+                }
+            }
+
+          g_value_set_flags (value, flags);
+          return TRUE;
+        }
+    }
+  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTESTRING))
+    {
+      g_value_set_string (value, g_variant_get_bytestring (variant));
+      return TRUE;
+    }
+
+  g_critical ("No GSettings bind handler for type \"%s\".",
+              g_variant_get_type_string (variant));
+
+  return FALSE;
+}
+
+gboolean
+g_settings_mapping_is_compatible (GType               gvalue_type,
+                                  const GVariantType *variant_type)
+{
+  gboolean ok = FALSE;
+
+  if (gvalue_type == G_TYPE_BOOLEAN)
+    ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN);
+  else if (gvalue_type == G_TYPE_CHAR  ||
+           gvalue_type == G_TYPE_UCHAR)
+    ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BYTE);
+  else if (gvalue_type == G_TYPE_INT    ||
+           gvalue_type == G_TYPE_UINT   ||
+           gvalue_type == G_TYPE_INT64  ||
+           gvalue_type == G_TYPE_UINT64 ||
+           gvalue_type == G_TYPE_DOUBLE)
+    ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT16)  ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT16) ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32)  ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT32) ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64)  ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT64) ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_HANDLE) ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_DOUBLE));
+  else if (gvalue_type == G_TYPE_STRING)
+    ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING)      ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE ("ay")) ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_OBJECT_PATH) ||
+          g_variant_type_equal (variant_type, G_VARIANT_TYPE_SIGNATURE));
+  else if (gvalue_type == G_TYPE_STRV)
+    ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));
+  else if (G_TYPE_IS_ENUM (gvalue_type))
+    ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING);
+  else if (G_TYPE_IS_FLAGS (gvalue_type))
+    ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));
+
+  return ok;
+}
diff --git a/gtk/gsettings-mapping.h b/gtk/gsettings-mapping.h
new file mode 100644
index 0000000000..8a26684bb6
--- /dev/null
+++ b/gtk/gsettings-mapping.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2010 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Vincent Untz <vuntz gnome org>
+ */
+
+#ifndef __G_SETTINGS_MAPPING_H__
+#define __G_SETTINGS_MAPPING_H__
+
+#include <glib-object.h>
+
+GVariant *              g_settings_set_mapping                          (const GValue       *value,
+                                                                         const GVariantType *expected_type,
+                                                                         gpointer            user_data);
+gboolean                g_settings_get_mapping                          (GValue             *value,
+                                                                         GVariant           *variant,
+                                                                         gpointer            user_data);
+gboolean                g_settings_mapping_is_compatible                (GType               gvalue_type,
+                                                                         const GVariantType *variant_type);
+
+#endif /* __G_SETTINGS_MAPPING_H__ */
diff --git a/gtk/gtkactionmuxer.c b/gtk/gtkactionmuxer.c
index 515f93f6db..f74a65367a 100644
--- a/gtk/gtkactionmuxer.c
+++ b/gtk/gtkactionmuxer.c
@@ -26,6 +26,7 @@
 #include "gtkintl.h"
 #include "gtkmarshalers.h"
 #include "gtkwidget.h"
+#include "gsettings-mapping.h"
 
 #include <string.h>
 
@@ -420,6 +421,145 @@ gtk_action_muxer_parent_primary_accel_changed (GtkActionMuxer *parent,
   gtk_action_muxer_primary_accel_changed (muxer, action_name, action_and_target);
 }
 
+static GVariant *
+prop_action_get_state (GtkWidget       *widget,
+                       GtkWidgetAction *action)
+{
+  GValue value = G_VALUE_INIT;
+  GVariant *result;
+
+  g_value_init (&value, action->pspec->value_type);
+  g_object_get_property (G_OBJECT (widget), action->pspec->name, &value);
+
+  result = g_settings_set_mapping (&value, action->state_type, NULL);
+  g_value_unset (&value);
+
+  return g_variant_ref_sink (result);
+}
+
+static GVariant *
+prop_action_get_state_hint (GtkWidget       *widget,
+                            GtkWidgetAction *action)
+{
+  if (action->pspec->value_type == G_TYPE_INT)
+    {
+      GParamSpecInt *pspec = (GParamSpecInt *)action->pspec;
+      return g_variant_new ("(ii)", pspec->minimum, pspec->maximum);
+    }
+  else if (action->pspec->value_type == G_TYPE_UINT)
+    {
+      GParamSpecUInt *pspec = (GParamSpecUInt *)action->pspec;
+      return g_variant_new ("(uu)", pspec->minimum, pspec->maximum);
+    }
+  else if (action->pspec->value_type == G_TYPE_FLOAT)
+    {
+      GParamSpecFloat *pspec = (GParamSpecFloat *)action->pspec;
+      return g_variant_new ("(dd)", (double)pspec->minimum, (double)pspec->maximum);
+    }
+  else if (action->pspec->value_type == G_TYPE_DOUBLE)
+    {
+      GParamSpecDouble *pspec = (GParamSpecDouble *)action->pspec;
+      return g_variant_new ("(dd)", pspec->minimum, pspec->maximum);
+    }
+
+  return NULL;
+}
+
+static void
+prop_action_set_state (GtkWidget       *widget,
+                       GtkWidgetAction *action,
+                       GVariant        *state)
+{
+  GValue value = G_VALUE_INIT;
+
+  g_value_init (&value, action->pspec->value_type);
+  g_settings_get_mapping (&value, state, NULL);
+
+  g_object_set_property (G_OBJECT (widget), action->pspec->name, &value);
+  g_value_unset (&value);
+}
+
+static void
+prop_action_activate (GtkWidget       *widget,
+                      GtkWidgetAction *action,
+                      GVariant        *parameter)
+{
+  if (action->pspec->value_type == G_TYPE_BOOLEAN)
+    {
+      gboolean value;
+
+      g_return_if_fail (parameter == NULL);
+
+      g_object_get (G_OBJECT (widget), action->pspec->name, &value, NULL);
+      value = !value;
+      g_object_set (G_OBJECT (widget), action->pspec->name, value, NULL);
+    }
+  else
+    {
+      g_return_if_fail (parameter != NULL && g_variant_is_of_type (parameter, action->state_type));
+
+      prop_action_set_state (widget, action, parameter);
+    }
+}
+
+static void
+prop_action_notify (GObject    *object,
+                    GParamSpec *pspec,
+                    gpointer    user_data)
+{
+  GtkActionMuxer *muxer = user_data;
+  int i;
+  GtkWidgetAction *action = NULL;
+  GVariant *state;
+
+  g_assert ((GObject *)muxer->widget == object);
+
+  for (i = 0; i < muxer->widget_actions->len; i++)
+    {
+      action = g_ptr_array_index (muxer->widget_actions, i);
+      if (action->pspec == pspec)
+        break;
+      action = NULL;
+    }
+
+  g_assert (action != NULL);
+
+  state = prop_action_get_state (muxer->widget, action);
+  gtk_action_muxer_action_state_changed (muxer, action->name, state);
+  g_variant_unref (state);
+}
+
+static void
+prop_actions_connect (GtkActionMuxer *muxer)
+{
+  int i;
+
+  if (!muxer->widget || !muxer->widget_actions)
+    return;
+
+  for (i = 0; i < muxer->widget_actions->len; i++)
+    {
+      GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
+      char *detailed;
+
+      if (!action->pspec)
+        continue;
+
+      detailed = g_strconcat ("notify::", action->pspec->name, NULL);
+      g_signal_connect (muxer->widget, detailed,
+                        G_CALLBACK (prop_action_notify), muxer);
+      g_free (detailed);
+    }
+}
+
+static void
+prop_actions_disconnect (GtkActionMuxer *muxer)
+{
+  if (muxer->widget)
+    g_signal_handlers_disconnect_by_func (muxer->widget,
+                                          prop_action_notify, muxer);
+}
+
 static gboolean
 gtk_action_muxer_query_action (GActionGroup        *action_group,
                                const gchar         *action_name,
@@ -454,16 +594,12 @@ gtk_action_muxer_query_action (GActionGroup        *action_group,
               if (state)
                 *state = NULL;
 
-              if (action->get_state)
+              if (action->pspec)
                 {
-                  GVariant *s;
-
-                  s = g_variant_ref_sink (action->get_state (muxer->widget, action->name));
-
                   if (state)
-                    *state = g_variant_ref (s);
-
-                  g_variant_unref (s);
+                    *state = prop_action_get_state (muxer->widget, action);
+                  if (state_hint)
+                    *state_hint = prop_action_get_state_hint (muxer->widget, action);
                 }
 
               return TRUE;
@@ -503,7 +639,10 @@ gtk_action_muxer_activate_action (GActionGroup *action_group,
           GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
           if (strcmp (action->name, action_name) == 0)
             {
-              action->activate (muxer->widget, action->name, parameter);
+              if (action->activate)
+                action->activate (muxer->widget, action->name, parameter);
+              else if (action->pspec)
+                prop_action_activate (muxer->widget, action, parameter);
 
               return;
             }
@@ -536,8 +675,8 @@ gtk_action_muxer_change_action_state (GActionGroup *action_group,
           GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
           if (strcmp (action->name, action_name) == 0)
             {
-              if (action->set_state)
-                action->set_state (muxer->widget, action->name, state);
+              if (action->pspec)
+                prop_action_set_state (muxer->widget, action, state);
 
               return;
             }
@@ -668,6 +807,8 @@ gtk_action_muxer_dispose (GObject *object)
 {
   GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
 
+  prop_actions_disconnect (muxer);
+
   if (muxer->parent)
   {
     g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_added_to_parent, muxer);
@@ -685,6 +826,16 @@ gtk_action_muxer_dispose (GObject *object)
     ->dispose (object);
 }
 
+static void
+gtk_action_muxer_constructed (GObject *object)
+{
+  GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
+
+  prop_actions_connect (muxer);
+
+  G_OBJECT_CLASS (gtk_action_muxer_parent_class)->constructed (object);
+}
+
 static void
 gtk_action_muxer_get_property (GObject    *object,
                                guint       property_id,
@@ -775,6 +926,7 @@ gtk_action_muxer_class_init (GObjectClass *class)
 {
   class->get_property = gtk_action_muxer_get_property;
   class->set_property = gtk_action_muxer_set_property;
+  class->constructed = gtk_action_muxer_constructed;
   class->finalize = gtk_action_muxer_finalize;
   class->dispose = gtk_action_muxer_dispose;
 
diff --git a/gtk/gtkactionmuxerprivate.h b/gtk/gtkactionmuxerprivate.h
index b1b8cef9cc..44dbb8a404 100644
--- a/gtk/gtkactionmuxerprivate.h
+++ b/gtk/gtkactionmuxerprivate.h
@@ -33,14 +33,13 @@ G_BEGIN_DECLS
 
 typedef struct {
   char *name;
-
   GType owner;
-  GVariantType *parameter_type;
-  GVariantType *state_type;
 
+  const GVariantType *parameter_type;
   GtkWidgetActionActivateFunc activate;
-  GtkWidgetActionSetStateFunc set_state;
-  GtkWidgetActionGetStateFunc get_state;
+
+  const GVariantType *state_type;
+  GParamSpec *pspec;
 } GtkWidgetAction;
 
 typedef struct _GtkActionMuxer                              GtkActionMuxer;
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index 943f0d0cbf..7e91178259 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -563,15 +563,6 @@ static void gtk_text_activate_selection_select_all   (GtkWidget  *widget,
 static void gtk_text_activate_misc_insert_emoji      (GtkWidget  *widget,
                                                       const char *action_name,
                                                       GVariant   *parameter);
-static void gtk_text_activate_misc_toggle_visibility (GtkWidget  *widget,
-                                                      const char *action_name,
-                                                      GVariant   *parameter);
-
-static void      gtk_text_set_misc_toggle_visibility (GtkWidget  *widget,
-                                                      const char *action_name,
-                                                      GVariant   *state);
-static GVariant *gtk_text_get_misc_toggle_visibility (GtkWidget  *widget,
-                                                      const char *action_name);
 
 /* GtkTextContent implementation
  */
@@ -1375,11 +1366,9 @@ gtk_text_class_init (GtkTextClass *class)
                                    gtk_text_activate_selection_select_all);
   gtk_widget_class_install_action (widget_class, "misc.insert-emoji", NULL,
                                    gtk_text_activate_misc_insert_emoji);
-  gtk_widget_class_install_stateful_action (widget_class, "misc.toggle-visibility", NULL,
-                                            gtk_text_activate_misc_toggle_visibility,
-                                            "b",
-                                            gtk_text_set_misc_toggle_visibility,
-                                            gtk_text_get_misc_toggle_visibility);
+  gtk_widget_class_install_property_action (widget_class,
+                                            "misc.toggle-visibility",
+                                            "visibility");
 }
 
 static void
@@ -5313,8 +5302,6 @@ gtk_text_set_visibility (GtkText  *self,
       gtk_text_recompute (self);
 
       gtk_text_update_clipboard_actions (self);
-      gtk_widget_action_state_changed (GTK_WIDGET (self), "misc.toggle-visibility",
-                                       g_variant_new_boolean (visible));
     }
 }
 
@@ -5718,35 +5705,6 @@ gtk_text_activate_misc_insert_emoji (GtkWidget  *widget,
   hide_selection_bubble (self);
 }
 
-static void
-gtk_text_activate_misc_toggle_visibility (GtkWidget  *widget,
-                                          const char *action_name,
-                                          GVariant   *parameter)
-{
-  GtkText *self = GTK_TEXT (widget);
-  gtk_text_set_visibility (self, !gtk_text_get_visibility (self));
-}
-
-static GVariant *
-gtk_text_get_misc_toggle_visibility (GtkWidget  *widget,
-                                     const char *action_name)
-{
-  GtkText *self = GTK_TEXT (widget);
-  DisplayMode mode = gtk_text_get_display_mode (self);
-
-  return g_variant_new_boolean (mode == DISPLAY_NORMAL);
-}
-
-static void
-gtk_text_set_misc_toggle_visibility (GtkWidget  *widget,
-                                     const char *action_name,
-                                     GVariant   *state)
-{
-  GtkText *self = GTK_TEXT (widget);
-  gboolean visible = g_variant_get_boolean (state);
-  gtk_text_set_visibility (self, visible);
-}
-
 static void
 gtk_text_update_clipboard_actions (GtkText *self)
 {
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 16d86cfbb7..926d61fa00 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -13430,6 +13430,37 @@ gtk_widget_should_layout (GtkWidget *widget)
   return TRUE;
 }
 
+static void
+gtk_widget_class_add_action (GtkWidgetClass  *widget_class,
+                             GtkWidgetAction *action)
+{
+  GtkWidgetClassPrivate *priv = widget_class->priv;
+
+  if (priv->actions == NULL)
+    priv->actions = g_ptr_array_new ();
+  else if (GTK_IS_WIDGET_CLASS (&widget_class->parent_class))
+    {
+      GtkWidgetClass *parent_class = GTK_WIDGET_CLASS (&widget_class->parent_class);
+      GtkWidgetClassPrivate *parent_priv = parent_class->priv;
+      GPtrArray *parent_actions = parent_priv->actions;
+
+      if (priv->actions == parent_actions)
+        {
+          int i;
+
+          priv->actions = g_ptr_array_new ();
+          for (i = 0; i < parent_actions->len; i++)
+            g_ptr_array_add (priv->actions, g_ptr_array_index (parent_actions, i));
+        }
+    }
+
+  GTK_NOTE(ACTIONS, g_message ("%sClass: Adding %s action\n",
+                               g_type_name (G_TYPE_FROM_CLASS (widget_class)),
+                               action->name));
+
+  g_ptr_array_add (priv->actions, action);
+}
+
 /*
  * gtk_widget_class_install_action:
  * @widget_class: a #GtkWidgetClass
@@ -13450,76 +13481,89 @@ gtk_widget_class_install_action (GtkWidgetClass              *widget_class,
                                  const char                  *parameter_type,
                                  GtkWidgetActionActivateFunc  activate)
 {
-  gtk_widget_class_install_stateful_action (widget_class, action_name,
-                                            parameter_type, activate,
-                                            NULL, NULL, NULL);
+  GtkWidgetAction *action;
+
+  action = g_new0 (GtkWidgetAction, 1);
+  action->owner = G_TYPE_FROM_CLASS (widget_class);
+  action->name = g_strdup (action_name);
+  if (parameter_type)
+    action->parameter_type = g_variant_type_new (parameter_type);
+  else
+    action->parameter_type = NULL;
+  action->activate = activate;
+
+  gtk_widget_class_add_action (widget_class, action);
+}
+
+static const GVariantType *
+determine_type (GParamSpec *pspec)
+{
+  if (G_TYPE_IS_ENUM (pspec->value_type))
+    return G_VARIANT_TYPE_STRING;
+
+  switch (pspec->value_type)
+    {
+    case G_TYPE_BOOLEAN:
+      return G_VARIANT_TYPE_BOOLEAN;
+
+    case G_TYPE_INT:
+      return G_VARIANT_TYPE_INT32;
+
+    case G_TYPE_UINT:
+      return G_VARIANT_TYPE_UINT32;
+
+    case G_TYPE_DOUBLE:
+    case G_TYPE_FLOAT:
+      return G_VARIANT_TYPE_DOUBLE;
+
+    case G_TYPE_STRING:
+      return G_VARIANT_TYPE_STRING;
+
+    default:
+      g_critical ("Unable to use gtk_widget_class_install_property_action with property '%s::%s' of type 
'%s'",
+                  g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->value_type));
+      return NULL;
+    }
 }
 
-/*
- * gtk_widget_class_install_stateful_action:
- * @widget_class: a #GtkWidgetClass
- * @action_name: a prefixed action name, such as "clipboard.paste"
- * @parameter_type: (allow-none): the parameter type, or %NULL
- * @activate: callback to use when the action is activated
- * @state_type: (allow-none): the state type, or %NULL
- * @set_state: (allow-none): callback to use when the action state
-       is set, or %NULL for stateless actions
- * @get_state: (allow-none): callback to use when the action state
-       is queried, or %NULL for stateless actions
- *
- * This should be called at class initialization time to specify
- * actions to be added for all instances of this class.
- *
- * Actions installed in this way can be simple or stateful.
- * See the #GAction documentation for more information.
- */
 void
-gtk_widget_class_install_stateful_action (GtkWidgetClass              *widget_class,
-                                          const char                  *action_name,
-                                          const char                  *parameter_type,
-                                          GtkWidgetActionActivateFunc  activate,
-                                          const char                  *state_type,
-                                          GtkWidgetActionSetStateFunc  set_state,
-                                          GtkWidgetActionGetStateFunc  get_state)
+gtk_widget_class_install_property_action (GtkWidgetClass *widget_class,
+                                          const char     *action_name,
+                                          const char     *property_name)
 {
-  GtkWidgetClassPrivate *priv = widget_class->priv;
+  GParamSpec *pspec;
   GtkWidgetAction *action;
 
   g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
 
-  if (priv->actions == NULL)
-    priv->actions = g_ptr_array_new ();
-  else if (GTK_IS_WIDGET_CLASS (&widget_class->parent_class))
-    {
-      GtkWidgetClass *parent_class = GTK_WIDGET_CLASS (&widget_class->parent_class);
-      GtkWidgetClassPrivate *parent_priv = parent_class->priv;
-      GPtrArray *parent_actions = parent_priv->actions;
+  pspec = g_object_class_find_property (G_OBJECT_CLASS (widget_class), property_name);
 
-      if (priv->actions == parent_actions)
-        {
-          int i;
+  if (pspec == NULL)
+    {
+      g_critical ("Attempted to use non-existent property '%s::%s' for 
dgtk_widget_class_install_property_action",
+                  g_type_name (G_TYPE_FROM_CLASS (widget_class)), property_name);
+      return;
+    }
 
-          priv->actions = g_ptr_array_new ();
-          for (i = 0; i < parent_actions->len; i++)
-            g_ptr_array_add (priv->actions, g_ptr_array_index (parent_actions, i));
-        }
+  if (~pspec->flags & G_PARAM_READABLE || ~pspec->flags & G_PARAM_WRITABLE || pspec->flags & 
G_PARAM_CONSTRUCT_ONLY)
+    {
+      g_critical ("Property '%s::%s' used with gtk_widget_class_install_property_action must be readable, 
writable, and not construct-only",
+                  g_type_name (G_TYPE_FROM_CLASS (widget_class)), property_name);
+      return;
     }
 
   action = g_new0 (GtkWidgetAction, 1);
   action->owner = G_TYPE_FROM_CLASS (widget_class);
   action->name = g_strdup (action_name);
-  action->parameter_type = parameter_type ? g_variant_type_new (parameter_type) : NULL;
-  action->activate = activate;
-  action->state_type = state_type ? g_variant_type_new (state_type) : NULL;
-  action->set_state = set_state;
-  action->get_state = get_state;
-
-  GTK_NOTE(ACTIONS,
-           g_message ("%sClass: Adding %s action\n",
-                      g_type_name (G_TYPE_FROM_CLASS (widget_class)),
-                      action_name));
+  action->pspec = pspec;
+  action->state_type = determine_type (action->pspec);
+  if (action->pspec->value_type == G_TYPE_BOOLEAN)
+    action->parameter_type = NULL;
+  else
+    action->parameter_type = action->state_type;
+  action->activate = NULL;
 
-  g_ptr_array_add (priv->actions, action);
+  gtk_widget_class_add_action (widget_class, action);
 }
 
 /**
@@ -13545,29 +13589,6 @@ gtk_widget_action_enabled_changed (GtkWidget  *widget,
   gtk_action_muxer_action_enabled_changed (muxer, action_name, enabled);
 }
 
-/**
- * gtk_widget_action_state_changed:
- * @widget: a #GtkWidget
- * @action_name: action name, such as "clipboard.paste"
- * @state: the new state
- *
- * Notify when an action installed with
- * gtk_widget_class_install_stateful_action() changes
- * its state.
- */
-void
-gtk_widget_action_state_changed (GtkWidget  *widget,
-                                 const char *action_name,
-                                 GVariant   *state)
-{
-  GtkActionMuxer *muxer;
-
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-
-  muxer = _gtk_widget_get_action_muxer (widget, TRUE);
-  gtk_action_muxer_action_state_changed (muxer, action_name, state);
-}
-
 /**
  * gtk_widget_class_query_action:
  * @widget_class: a #GtkWidgetClass
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index c1a0482278..a9b1434f27 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -1038,38 +1038,6 @@ typedef void (* GtkWidgetActionActivateFunc) (GtkWidget  *widget,
                                               const char *action_name,
                                               GVariant   *parameter);
 
-/**
- * GtkWidgetActionGetStateFunc:
- * @widget: the widget to which the action belongs
- * @action_name: the action name
- *
- * The type of the callback functions used to query the state
- * of stateful actions installed with gtk_widget_class_install_action().
- *
- * See the #GAction documentation for more details about the
- * meaning of these properties.
- */
-typedef GVariant * (* GtkWidgetActionGetStateFunc) (GtkWidget  *widget,
-                                                    const char *action_name);
-
-/**
- * GtkWidgetActionSetStateFunc:
- * @widget: the widget to which the action belongs
- * @action_name: the action name
- * @state: the new state
- *
- * The type of the callback functions used to change the
- * state of actions installed with gtk_widget_class_install_action().
- *
- * The @state must match the @state_type of the action.
- *
- * This callback is used when the action state is
- * changed via the #GActionGroup API.
- */
-typedef void (*GtkWidgetActionSetStateFunc) (GtkWidget  *widget,
-                                             const char *action_name,
-                                             GVariant   *state);
-
 GDK_AVAILABLE_IN_ALL
 void                    gtk_widget_class_install_action (GtkWidgetClass              *widget_class,
                                                          const char                  *action_name,
@@ -1077,13 +1045,9 @@ void                    gtk_widget_class_install_action (GtkWidgetClass
                                                          GtkWidgetActionActivateFunc  activate);
 
 GDK_AVAILABLE_IN_ALL
-void                    gtk_widget_class_install_stateful_action (GtkWidgetClass              *widget_class,
-                                                                  const char                  *action_name,
-                                                                  const char                  
*parameter_type,
-                                                                  GtkWidgetActionActivateFunc  activate,
-                                                                  const char                  *state_type,
-                                                                  GtkWidgetActionSetStateFunc  set_state,
-                                                                  GtkWidgetActionGetStateFunc  get_state);
+void                    gtk_widget_class_install_property_action (GtkWidgetClass *widget_class,
+                                                                  const char     *action_name,
+                                                                  const char     *property_name);
 
 GDK_AVAILABLE_IN_ALL
 gboolean               gtk_widget_class_query_action  (GtkWidgetClass      *widget_class,
@@ -1097,10 +1061,6 @@ GDK_AVAILABLE_IN_ALL
 void                    gtk_widget_action_enabled_changed (GtkWidget  *widget,
                                                            const char *action_name,
                                                            gboolean    enabled);
-GDK_AVAILABLE_IN_ALL
-void                    gtk_widget_action_state_changed   (GtkWidget  *widget,
-                                                           const char *action_name,
-                                                           GVariant   *state);
 
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref)
diff --git a/gtk/meson.build b/gtk/meson.build
index c5bd9b154f..0b271b6f50 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -17,6 +17,7 @@ gtk_private_sources = files([
   'fallback-c89.c',
   'fnmatch.c',
   'tools/gdkpixbufutils.c',
+  'gsettings-mapping.c',
   'gtkactionhelper.c',
   'gtkactionmuxer.c',
   'gtkactionobservable.c',



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