[gnome-shell/wip/nielsdg/g-object-notify] st: Use g_object_notify_by_pspec()



commit 966fd931aba56176c61a44856f09a4d97c9933c2
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Mon Jul 29 17:59:41 2019 +0200

    st: Use g_object_notify_by_pspec()
    
    `g_object_notify()` actually takes a global lock to look up the property
    by its name, which means there is a performance hit (albeit tiny) every
    time this function is called. For this reason, always try to use
    `g_object_notify_by_pspec()` instead.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/652

 src/st/st-adjustment.c       | 128 ++++++++++++++-----------------
 src/st/st-bin.c              |  87 +++++++++++----------
 src/st/st-button.c           |  86 +++++++++++----------
 src/st/st-entry.c            | 134 +++++++++++++++++----------------
 src/st/st-icon.c             |  72 ++++++++++--------
 src/st/st-label.c            |  38 +++++-----
 src/st/st-scroll-bar.c       |  36 ++++-----
 src/st/st-scroll-view-fade.c |  57 +++++++-------
 src/st/st-scroll-view.c      | 143 ++++++++++++++++++-----------------
 src/st/st-widget.c           | 175 +++++++++++++++++++++----------------------
 10 files changed, 480 insertions(+), 476 deletions(-)
---
diff --git a/src/st/st-adjustment.c b/src/st/st-adjustment.c
index 5fb68f732..b705e6e6c 100644
--- a/src/st/st-adjustment.c
+++ b/src/st/st-adjustment.c
@@ -70,8 +70,12 @@ enum
   PROP_STEP_INC,
   PROP_PAGE_INC,
   PROP_PAGE_SIZE,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 enum
 {
   CHANGED,
@@ -206,72 +210,50 @@ st_adjustment_class_init (StAdjustmentClass *klass)
   object_class->get_property = st_adjustment_get_property;
   object_class->set_property = st_adjustment_set_property;
 
-  g_object_class_install_property (object_class,
-                                   PROP_LOWER,
-                                   g_param_spec_double ("lower",
-                                                        "Lower",
-                                                        "Lower bound",
-                                                        -G_MAXDOUBLE,
-                                                        G_MAXDOUBLE,
-                                                        0.0,
-                                                        ST_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT |
-                                                        G_PARAM_EXPLICIT_NOTIFY));
-  g_object_class_install_property (object_class,
-                                   PROP_UPPER,
-                                   g_param_spec_double ("upper",
-                                                        "Upper",
-                                                        "Upper bound",
-                                                        -G_MAXDOUBLE,
-                                                        G_MAXDOUBLE,
-                                                        0.0,
-                                                        ST_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT |
-                                                        G_PARAM_EXPLICIT_NOTIFY));
-  g_object_class_install_property (object_class,
-                                   PROP_VALUE,
-                                   g_param_spec_double ("value",
-                                                        "Value",
-                                                        "Current value",
-                                                        -G_MAXDOUBLE,
-                                                        G_MAXDOUBLE,
-                                                        0.0,
-                                                        ST_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT |
-                                                        G_PARAM_EXPLICIT_NOTIFY));
-  g_object_class_install_property (object_class,
-                                   PROP_STEP_INC,
-                                   g_param_spec_double ("step-increment",
-                                                        "Step Increment",
-                                                        "Step increment",
-                                                        0.0,
-                                                        G_MAXDOUBLE,
-                                                        0.0,
-                                                        ST_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT |
-                                                        G_PARAM_EXPLICIT_NOTIFY));
-  g_object_class_install_property (object_class,
-                                   PROP_PAGE_INC,
-                                   g_param_spec_double ("page-increment",
-                                                        "Page Increment",
-                                                        "Page increment",
-                                                        0.0,
-                                                        G_MAXDOUBLE,
-                                                        0.0,
-                                                        ST_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT |
-                                                        G_PARAM_EXPLICIT_NOTIFY));
-  g_object_class_install_property (object_class,
-                                   PROP_PAGE_SIZE,
-                                   g_param_spec_double ("page-size",
-                                                        "Page Size",
-                                                        "Page size",
-                                                        0.0,
-                                                        G_MAXDOUBLE,
-                                                        0.0,
-                                                        ST_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT |
-                                                        G_PARAM_EXPLICIT_NOTIFY));
+  props[PROP_LOWER] =
+    g_param_spec_double ("lower", "Lower", "Lower bound",
+                         -G_MAXDOUBLE,  G_MAXDOUBLE, 0.0,
+                         ST_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_EXPLICIT_NOTIFY);
+
+  props[PROP_UPPER] =
+    g_param_spec_double ("upper", "Upper", "Upper bound",
+                         -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+                         ST_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_EXPLICIT_NOTIFY);
+
+  props[PROP_VALUE] =
+    g_param_spec_double ("value", "Value", "Current value",
+                         -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
+                         ST_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_EXPLICIT_NOTIFY);
+
+  props[PROP_STEP_INC] =
+    g_param_spec_double ("step-increment", "Step Increment", "Step increment",
+                         0.0, G_MAXDOUBLE, 0.0,
+                         ST_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_EXPLICIT_NOTIFY);
+
+  props[PROP_PAGE_INC] =
+    g_param_spec_double ("page-increment", "Page Increment", "Page increment",
+                         0.0, G_MAXDOUBLE, 0.0,
+                         ST_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_EXPLICIT_NOTIFY);
+
+  props[PROP_PAGE_SIZE] =
+    g_param_spec_double ("page-size", "Page Size", "Page size",
+                         0.0, G_MAXDOUBLE, 0.0,
+                         ST_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_EXPLICIT_NOTIFY);
+
+  g_object_class_install_properties (object_class, N_PROPS, props);
+
   /**
    * StAdjustment::changed:
    * @self: the #StAdjustment
@@ -342,7 +324,7 @@ st_adjustment_set_value (StAdjustment *adjustment,
     {
       priv->value = value;
 
-      g_object_notify (G_OBJECT (adjustment), "value");
+      g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_VALUE]);
     }
 }
 
@@ -376,7 +358,7 @@ st_adjustment_clamp_page (StAdjustment *adjustment,
     }
 
   if (changed)
-    g_object_notify (G_OBJECT (adjustment), "value");
+    g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_VALUE]);
 }
 
 static gboolean
@@ -391,7 +373,7 @@ st_adjustment_set_lower (StAdjustment *adjustment,
 
       g_signal_emit (adjustment, signals[CHANGED], 0);
 
-      g_object_notify (G_OBJECT (adjustment), "lower");
+      g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_LOWER]);
 
       /* Defer clamp until after construction. */
       if (!priv->is_constructing)
@@ -415,7 +397,7 @@ st_adjustment_set_upper (StAdjustment *adjustment,
 
       g_signal_emit (adjustment, signals[CHANGED], 0);
 
-      g_object_notify (G_OBJECT (adjustment), "upper");
+      g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_UPPER]);
 
       /* Defer clamp until after construction. */
       if (!priv->is_constructing)
@@ -439,7 +421,7 @@ st_adjustment_set_step_increment (StAdjustment *adjustment,
 
       g_signal_emit (adjustment, signals[CHANGED], 0);
 
-      g_object_notify (G_OBJECT (adjustment), "step-increment");
+      g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_STEP_INC]);
 
       return TRUE;
     }
@@ -459,7 +441,7 @@ st_adjustment_set_page_increment (StAdjustment *adjustment,
 
       g_signal_emit (adjustment, signals[CHANGED], 0);
 
-      g_object_notify (G_OBJECT (adjustment), "page-increment");
+      g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_PAGE_INC]);
 
       return TRUE;
     }
@@ -479,7 +461,7 @@ st_adjustment_set_page_size (StAdjustment *adjustment,
 
       g_signal_emit (adjustment, signals[CHANGED], 0);
 
-      g_object_notify (G_OBJECT (adjustment), "page_size");
+      g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_PAGE_SIZE]);
 
       /* Well explicitely clamp after construction. */
       if (!priv->is_constructing)
diff --git a/src/st/st-bin.c b/src/st/st-bin.c
index f013909e8..6d6d056d2 100644
--- a/src/st/st-bin.c
+++ b/src/st/st-bin.c
@@ -58,9 +58,13 @@ enum
   PROP_X_ALIGN,
   PROP_Y_ALIGN,
   PROP_X_FILL,
-  PROP_Y_FILL
+  PROP_Y_FILL,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 static void clutter_container_iface_init (ClutterContainerIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (StBin, st_bin, ST_TYPE_WIDGET,
@@ -311,7 +315,6 @@ st_bin_class_init (StBinClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
   StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
-  GParamSpec *pspec;
 
   gobject_class->set_property = st_bin_set_property;
   gobject_class->get_property = st_bin_get_property;
@@ -329,64 +332,66 @@ st_bin_class_init (StBinClass *klass)
    *
    * The child #ClutterActor of the #StBin container.
    */
-  pspec = g_param_spec_object ("child",
-                               "Child",
-                               "The child of the Bin",
-                               CLUTTER_TYPE_ACTOR,
-                               ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_CHILD, pspec);
+  props[PROP_CHILD] =
+    g_param_spec_object ("child",
+                         "Child",
+                         "The child of the Bin",
+                         CLUTTER_TYPE_ACTOR,
+                         ST_PARAM_READWRITE);
 
   /**
    * StBin:x-align:
    *
    * The horizontal alignment of the #StBin child.
    */
-  pspec = g_param_spec_enum ("x-align",
-                             "X Align",
-                             "The horizontal alignment",
-                             ST_TYPE_ALIGN,
-                             ST_ALIGN_MIDDLE,
-                             ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_X_ALIGN, pspec);
+  props[PROP_X_ALIGN] =
+    g_param_spec_enum ("x-align",
+                       "X Align",
+                       "The horizontal alignment",
+                       ST_TYPE_ALIGN,
+                       ST_ALIGN_MIDDLE,
+                       ST_PARAM_READWRITE);
 
   /**
    * StBin:y-align:
    *
    * The vertical alignment of the #StBin child.
    */
-  pspec = g_param_spec_enum ("y-align",
-                             "Y Align",
-                             "The vertical alignment",
-                             ST_TYPE_ALIGN,
-                             ST_ALIGN_MIDDLE,
-                             ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_Y_ALIGN, pspec);
+  props[PROP_Y_ALIGN] =
+    g_param_spec_enum ("y-align",
+                       "Y Align",
+                       "The vertical alignment",
+                       ST_TYPE_ALIGN,
+                       ST_ALIGN_MIDDLE,
+                       ST_PARAM_READWRITE);
 
   /**
    * StBin:x-fill:
    *
    * Whether the child should fill the horizontal allocation
    */
-  pspec = g_param_spec_boolean ("x-fill",
-                                "X Fill",
-                                "Whether the child should fill the "
-                                "horizontal allocation",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_X_FILL, pspec);
+  props[PROP_X_FILL] =
+    g_param_spec_boolean ("x-fill",
+                          "X Fill",
+                          "Whether the child should fill the "
+                          "horizontal allocation",
+                          FALSE,
+                          ST_PARAM_READWRITE);
 
   /**
    * StBin:y-fill:
    *
    * Whether the child should fill the vertical allocation
    */
-  pspec = g_param_spec_boolean ("y-fill",
-                                "Y Fill",
-                                "Whether the child should fill the "
-                                "vertical allocation",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_Y_FILL, pspec);
+  props[PROP_Y_FILL] =
+    g_param_spec_boolean ("y-fill",
+                          "Y Fill",
+                          "Whether the child should fill the "
+                          "vertical allocation",
+                          FALSE,
+                          ST_PARAM_READWRITE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, props);
 }
 
 static void
@@ -447,7 +452,7 @@ st_bin_set_child (StBin        *bin,
 
   clutter_actor_queue_relayout (CLUTTER_ACTOR (bin));
 
-  g_object_notify (G_OBJECT (bin), "child");
+  g_object_notify_by_pspec (G_OBJECT (bin), props[PROP_CHILD]);
 }
 
 /**
@@ -492,14 +497,14 @@ st_bin_set_alignment (StBin  *bin,
   if (priv->x_align != x_align)
     {
       priv->x_align = x_align;
-      g_object_notify (G_OBJECT (bin), "x-align");
+      g_object_notify_by_pspec (G_OBJECT (bin), props[PROP_X_ALIGN]);
       changed = TRUE;
     }
 
   if (priv->y_align != y_align)
     {
       priv->y_align = y_align;
-      g_object_notify (G_OBJECT (bin), "y-align");
+      g_object_notify_by_pspec (G_OBJECT (bin), props[PROP_Y_ALIGN]);
       changed = TRUE;
     }
 
@@ -564,7 +569,7 @@ st_bin_set_fill (StBin   *bin,
       priv->x_fill = x_fill;
       changed = TRUE;
 
-      g_object_notify (G_OBJECT (bin), "x-fill");
+      g_object_notify_by_pspec (G_OBJECT (bin), props[PROP_X_FILL]);
     }
 
   if (priv->y_fill != y_fill)
@@ -572,7 +577,7 @@ st_bin_set_fill (StBin   *bin,
       priv->y_fill = y_fill;
       changed = TRUE;
 
-      g_object_notify (G_OBJECT (bin), "y-fill");
+      g_object_notify_by_pspec (G_OBJECT (bin), props[PROP_Y_FILL]);
     }
 
   if (changed)
diff --git a/src/st/st-button.c b/src/st/st-button.c
index 3af1811f7..16984f2b3 100644
--- a/src/st/st-button.c
+++ b/src/st/st-button.c
@@ -54,9 +54,13 @@ enum
   PROP_BUTTON_MASK,
   PROP_TOGGLE_MODE,
   PROP_CHECKED,
-  PROP_PRESSED
+  PROP_PRESSED,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 enum
 {
   CLICKED,
@@ -458,7 +462,6 @@ st_button_class_init (StButtonClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
   StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
-  GParamSpec *pspec;
 
   gobject_class->set_property = st_button_set_property;
   gobject_class->get_property = st_button_get_property;
@@ -476,41 +479,42 @@ st_button_class_init (StButtonClass *klass)
   widget_class->style_changed = st_button_style_changed;
   widget_class->get_accessible_type = st_button_accessible_get_type;
 
-  pspec = g_param_spec_string ("label",
-                               "Label",
-                               "Label of the button",
-                               NULL,
-                               ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
-
-  pspec = g_param_spec_flags ("button-mask",
-                              "Button mask",
-                              "Which buttons trigger the 'clicked' signal",
-                              ST_TYPE_BUTTON_MASK, ST_BUTTON_ONE,
-                              ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_BUTTON_MASK, pspec);
-
-  pspec = g_param_spec_boolean ("toggle-mode",
-                                "Toggle Mode",
-                                "Enable or disable toggling",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_TOGGLE_MODE, pspec);
-
-  pspec = g_param_spec_boolean ("checked",
-                                "Checked",
-                                "Indicates if a toggle button is \"on\""
-                                " or \"off\"",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_CHECKED, pspec);
-
-  pspec = g_param_spec_boolean ("pressed",
-                                "Pressed",
-                                "Indicates if the button is pressed in",
-                                FALSE,
-                                ST_PARAM_READABLE);
-  g_object_class_install_property (gobject_class, PROP_PRESSED, pspec);
+  props[PROP_LABEL] =
+    g_param_spec_string ("label",
+                         "Label",
+                         "Label of the button",
+                         NULL,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_BUTTON_MASK] =
+    g_param_spec_flags ("button-mask",
+                        "Button mask",
+                        "Which buttons trigger the 'clicked' signal",
+                        ST_TYPE_BUTTON_MASK, ST_BUTTON_ONE,
+                        ST_PARAM_READWRITE);
+
+  props[PROP_TOGGLE_MODE] =
+    g_param_spec_boolean ("toggle-mode",
+                          "Toggle Mode",
+                          "Enable or disable toggling",
+                          FALSE,
+                          ST_PARAM_READWRITE);
+
+  props[PROP_CHECKED] =
+    g_param_spec_boolean ("checked",
+                          "Checked",
+                          "Indicates if a toggle button is \"on\" or \"off\"",
+                          FALSE,
+                          ST_PARAM_READWRITE);
+
+  props[PROP_PRESSED] =
+    g_param_spec_boolean ("pressed",
+                          "Pressed",
+                          "Indicates if the button is pressed in",
+                          FALSE,
+                          ST_PARAM_READABLE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, props);
 
 
   /**
@@ -631,7 +635,7 @@ st_button_set_label (StButton    *button,
   /* Fake a style change so that we reset the style properties on the label */
   st_widget_style_changed (ST_WIDGET (button));
 
-  g_object_notify (G_OBJECT (button), "label");
+  g_object_notify_by_pspec (G_OBJECT (button), props[PROP_LABEL]);
 }
 
 /**
@@ -670,7 +674,7 @@ st_button_set_button_mask (StButton     *button,
   priv = st_button_get_instance_private (button);
   priv->button_mask = mask;
 
-  g_object_notify (G_OBJECT (button), "button-mask");
+  g_object_notify_by_pspec (G_OBJECT (button), props[PROP_BUTTON_MASK]);
 }
 
 /**
@@ -708,7 +712,7 @@ st_button_set_toggle_mode (StButton *button,
   priv = st_button_get_instance_private (button);
   priv->is_toggle = toggle;
 
-  g_object_notify (G_OBJECT (button), "toggle-mode");
+  g_object_notify_by_pspec (G_OBJECT (button), props[PROP_TOGGLE_MODE]);
 }
 
 /**
@@ -754,7 +758,7 @@ st_button_set_checked (StButton *button,
         st_widget_remove_style_pseudo_class (ST_WIDGET (button), "checked");
     }
 
-  g_object_notify (G_OBJECT (button), "checked");
+  g_object_notify_by_pspec (G_OBJECT (button), props[PROP_CHECKED]);
 }
 
 /**
diff --git a/src/st/st-entry.c b/src/st/st-entry.c
index 13688d0b6..eb8609887 100644
--- a/src/st/st-entry.c
+++ b/src/st/st-entry.c
@@ -80,8 +80,12 @@ enum
   PROP_TEXT,
   PROP_INPUT_PURPOSE,
   PROP_INPUT_HINTS,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 /* signals */
 enum
 {
@@ -910,7 +914,6 @@ st_entry_class_init (StEntryClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
   StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
-  GParamSpec *pspec;
 
   gobject_class->set_property = st_entry_set_property;
   gobject_class->get_property = st_entry_get_property;
@@ -933,68 +936,67 @@ st_entry_class_init (StEntryClass *klass)
   widget_class->navigate_focus = st_entry_navigate_focus;
   widget_class->get_accessible_type = st_entry_accessible_get_type;
 
-  pspec = g_param_spec_object ("clutter-text",
-                              "Clutter Text",
-                              "Internal ClutterText actor",
-                              CLUTTER_TYPE_TEXT,
-                              ST_PARAM_READABLE);
-  g_object_class_install_property (gobject_class, PROP_CLUTTER_TEXT, pspec);
-
-  pspec = g_param_spec_object ("primary-icon",
-                              "Primary Icon",
-                              "Primary Icon actor",
-                              CLUTTER_TYPE_ACTOR,
-                              ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_PRIMARY_ICON, pspec);
-
-  pspec = g_param_spec_object ("secondary-icon",
-                              "Secondary Icon",
-                              "Secondary Icon actor",
-                              CLUTTER_TYPE_ACTOR,
-                              ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_SECONDARY_ICON, pspec);
-
-  pspec = g_param_spec_string ("hint-text",
-                               "Hint Text",
-                               "Text to display when the entry is not focused "
-                               "and the text property is empty",
-                               NULL,
-                               ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_HINT_TEXT, pspec);
-
-  pspec = g_param_spec_object ("hint-actor",
-                               "Hint Actor",
-                               "An actor to display when the entry is not focused "
-                               "and the text property is empty",
-                               CLUTTER_TYPE_ACTOR,
-                               ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_HINT_ACTOR, pspec);
-
-  pspec = g_param_spec_string ("text",
-                               "Text",
-                               "Text of the entry",
-                               NULL,
-                               ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
-
-  pspec = g_param_spec_enum ("input-purpose",
-                             "Purpose",
-                             "Purpose of the text field",
-                             CLUTTER_TYPE_INPUT_CONTENT_PURPOSE,
-                             CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL,
-                             ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class,
-                                   PROP_INPUT_PURPOSE,
-                                   pspec);
-
-  pspec = g_param_spec_flags ("input-hints",
-                              "hints",
-                              "Hints for the text field behaviour",
-                              CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS,
-                              0, ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class,
-                                   PROP_INPUT_HINTS,
-                                   pspec);
+  props[PROP_CLUTTER_TEXT] =
+    g_param_spec_object ("clutter-text",
+                         "Clutter Text",
+                         "Internal ClutterText actor",
+                         CLUTTER_TYPE_TEXT,
+                         ST_PARAM_READABLE);
+
+  props[PROP_PRIMARY_ICON] =
+    g_param_spec_object ("primary-icon",
+                         "Primary Icon",
+                         "Primary Icon actor",
+                         CLUTTER_TYPE_ACTOR,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_SECONDARY_ICON] =
+    g_param_spec_object ("secondary-icon",
+                         "Secondary Icon",
+                         "Secondary Icon actor",
+                         CLUTTER_TYPE_ACTOR,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_HINT_TEXT] =
+    g_param_spec_string ("hint-text",
+                         "Hint Text",
+                         "Text to display when the entry is not focused "
+                         "and the text property is empty",
+                         NULL,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_HINT_ACTOR] =
+    g_param_spec_object ("hint-actor",
+                         "Hint Actor",
+                         "An actor to display when the entry is not focused "
+                         "and the text property is empty",
+                         CLUTTER_TYPE_ACTOR,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_TEXT] =
+    g_param_spec_string ("text",
+                         "Text",
+                         "Text of the entry",
+                         NULL,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_INPUT_PURPOSE] =
+    g_param_spec_enum ("input-purpose",
+                       "Purpose",
+                       "Purpose of the text field",
+                       CLUTTER_TYPE_INPUT_CONTENT_PURPOSE,
+                       CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL,
+                       ST_PARAM_READWRITE);
+
+  props[PROP_INPUT_HINTS] =
+    g_param_spec_flags ("input-hints",
+                        "hints",
+                        "Hints for the text field behaviour",
+                        CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS,
+                        0,
+                        ST_PARAM_READWRITE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, props);
 
   /* signals */
   /**
@@ -1132,7 +1134,7 @@ st_entry_set_text (StEntry     *entry,
 
   st_entry_update_hint_visibility (entry);
 
-  g_object_notify (G_OBJECT (entry), "text");
+  g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_TEXT]);
 }
 
 /**
@@ -1222,7 +1224,7 @@ st_entry_set_input_purpose (StEntry                    *entry,
     {
       clutter_text_set_input_purpose (editable, purpose);
 
-      g_object_notify (G_OBJECT (entry), "input-purpose");
+      g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_INPUT_PURPOSE]);
     }
 }
 
@@ -1267,7 +1269,7 @@ st_entry_set_input_hints (StEntry                      *entry,
     {
       clutter_text_set_input_hints (editable, hints);
 
-      g_object_notify (G_OBJECT (entry), "input-hints");
+      g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_INPUT_HINTS]);
     }
 }
 
diff --git a/src/st/st-icon.c b/src/st/st-icon.c
index 04d2d1d3c..2db0ba20c 100644
--- a/src/st/st-icon.c
+++ b/src/st/st-icon.c
@@ -39,9 +39,13 @@ enum
   PROP_GICON,
   PROP_ICON_NAME,
   PROP_ICON_SIZE,
-  PROP_FALLBACK_ICON_NAME
+  PROP_FALLBACK_ICON_NAME,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 struct _StIconPrivate
 {
   ClutterActor *icon_texture;
@@ -219,8 +223,6 @@ st_icon_resource_scale_changed (StWidget *widget)
 static void
 st_icon_class_init (StIconClass *klass)
 {
-  GParamSpec *pspec;
-
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
   StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
@@ -234,31 +236,35 @@ st_icon_class_init (StIconClass *klass)
   widget_class->style_changed = st_icon_style_changed;
   widget_class->resource_scale_changed = st_icon_resource_scale_changed;
 
-  pspec = g_param_spec_object ("gicon",
-                               "GIcon",
-                               "The GIcon shown by this icon actor",
-                               G_TYPE_ICON,
-                               ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class, PROP_GICON, pspec);
-
-  pspec = g_param_spec_string ("icon-name",
-                               "Icon name",
-                               "An icon name",
-                               NULL, ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class, PROP_ICON_NAME, pspec);
-
-  pspec = g_param_spec_int ("icon-size",
-                            "Icon size",
-                            "The size if the icon, if positive. Otherwise the size will be derived from the 
current style",
-                            -1, G_MAXINT, -1,
-                            ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class, PROP_ICON_SIZE, pspec);
-
-  pspec = g_param_spec_string ("fallback-icon-name",
-                               "Fallback icon name",
-                               "A fallback icon name",
-                               NULL, ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class, PROP_FALLBACK_ICON_NAME, pspec);
+  props[PROP_GICON] =
+    g_param_spec_object ("gicon",
+                         "GIcon",
+                         "The GIcon shown by this icon actor",
+                         G_TYPE_ICON,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_ICON_NAME] =
+    g_param_spec_string ("icon-name",
+                         "Icon name",
+                         "An icon name",
+                         NULL,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_ICON_SIZE] =
+    g_param_spec_int ("icon-size",
+                      "Icon size",
+                      "The size if the icon, if positive. Otherwise the size will be derived from the 
current style",
+                      -1, G_MAXINT, -1,
+                      ST_PARAM_READWRITE);
+
+  props[PROP_FALLBACK_ICON_NAME] =
+    g_param_spec_string ("fallback-icon-name",
+                         "Fallback icon name",
+                         "A fallback icon name",
+                         NULL,
+                         ST_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class, N_PROPS, props);
 }
 
 static void
@@ -528,8 +534,8 @@ st_icon_set_icon_name (StIcon      *icon,
 
   priv->gicon = gicon;
 
-  g_object_notify (G_OBJECT (icon), "gicon");
-  g_object_notify (G_OBJECT (icon), "icon-name");
+  g_object_notify_by_pspec (G_OBJECT (icon), props[PROP_GICON]);
+  g_object_notify_by_pspec (G_OBJECT (icon), props[PROP_ICON_NAME]);
 
   g_object_thaw_notify (G_OBJECT (icon));
 
@@ -573,7 +579,7 @@ st_icon_set_gicon (StIcon *icon, GIcon *gicon)
   if (gicon)
     icon->priv->gicon = g_object_ref (gicon);
 
-  g_object_notify (G_OBJECT (icon), "gicon");
+  g_object_notify_by_pspec (G_OBJECT (icon), props[PROP_GICON]);
 
   st_icon_update (icon);
 }
@@ -617,7 +623,7 @@ st_icon_set_icon_size (StIcon *icon,
       priv->prop_icon_size = size;
       if (st_icon_update_icon_size (icon))
         st_icon_update (icon);
-      g_object_notify (G_OBJECT (icon), "icon-size");
+      g_object_notify_by_pspec (G_OBJECT (icon), props[PROP_ICON_SIZE]);
     }
 }
 
@@ -660,7 +666,7 @@ st_icon_set_fallback_icon_name (StIcon      *icon,
 
   priv->fallback_gicon = gicon;
 
-  g_object_notify (G_OBJECT (icon), "fallback-icon-name");
+  g_object_notify_by_pspec (G_OBJECT (icon), props[PROP_FALLBACK_ICON_NAME]);
 
   st_icon_update (icon);
 }
diff --git a/src/st/st-label.c b/src/st/st-label.c
index ab05087d8..64127c964 100644
--- a/src/st/st-label.c
+++ b/src/st/st-label.c
@@ -51,9 +51,13 @@ enum
   PROP_0,
 
   PROP_CLUTTER_TEXT,
-  PROP_TEXT
+  PROP_TEXT,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 struct _StLabelPrivate
 {
   ClutterActor *label;
@@ -249,7 +253,6 @@ st_label_class_init (StLabelClass *klass)
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
   StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
-  GParamSpec *pspec;
 
   gobject_class->set_property = st_label_set_property;
   gobject_class->get_property = st_label_get_property;
@@ -264,20 +267,21 @@ st_label_class_init (StLabelClass *klass)
   widget_class->resource_scale_changed = st_label_resource_scale_changed;
   widget_class->get_accessible_type = st_label_accessible_get_type;
 
-  pspec = g_param_spec_object ("clutter-text",
-                              "Clutter Text",
-                              "Internal ClutterText actor",
-                              CLUTTER_TYPE_TEXT,
-                              ST_PARAM_READABLE);
-  g_object_class_install_property (gobject_class, PROP_CLUTTER_TEXT, pspec);
-
-  pspec = g_param_spec_string ("text",
-                               "Text",
-                               "Text of the label",
-                               NULL,
-                               ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
-
+  props[PROP_CLUTTER_TEXT] =
+      g_param_spec_object ("clutter-text",
+                           "Clutter Text",
+                           "Internal ClutterText actor",
+                           CLUTTER_TYPE_TEXT,
+                           ST_PARAM_READABLE);
+
+  props[PROP_TEXT] =
+      g_param_spec_string ("text",
+                           "Text",
+                           "Text of the label",
+                           NULL,
+                           ST_PARAM_READWRITE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, props);
 }
 
 static void
@@ -359,7 +363,7 @@ st_label_set_text (StLabel     *label,
 
       clutter_text_set_text (ctext, text);
 
-      g_object_notify (G_OBJECT (label), "text");
+      g_object_notify_by_pspec (G_OBJECT (label), props[PROP_TEXT]);
     }
 }
 
diff --git a/src/st/st-scroll-bar.c b/src/st/st-scroll-bar.c
index 135da76cf..2bcf47f16 100644
--- a/src/st/st-scroll-bar.c
+++ b/src/st/st-scroll-bar.c
@@ -79,9 +79,13 @@ enum
   PROP_0,
 
   PROP_ADJUSTMENT,
-  PROP_VERTICAL
+  PROP_VERTICAL,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 enum
 {
   SCROLL_START,
@@ -519,21 +523,19 @@ st_scroll_bar_class_init (StScrollBarClass *klass)
 
   widget_class->style_changed = st_scroll_bar_style_changed;
 
-  g_object_class_install_property
-                 (object_class,
-                 PROP_ADJUSTMENT,
-                 g_param_spec_object ("adjustment",
-                                      "Adjustment",
-                                      "The adjustment",
-                                      ST_TYPE_ADJUSTMENT,
-                                      ST_PARAM_READWRITE));
-
-  pspec = g_param_spec_boolean ("vertical",
-                                "Vertical Orientation",
-                                "Vertical Orientation",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class, PROP_VERTICAL, pspec);
+  props[PROP_ADJUSTMENT] =
+    g_param_spec_object ("adjustment", "Adjustment", "The adjustment",
+                         ST_TYPE_ADJUSTMENT,
+                         ST_PARAM_READWRITE);
+
+  props[PROP_VERTICAL] =
+    g_param_spec_boolean ("vertical",
+                          "Vertical Orientation",
+                          "Vertical Orientation",
+                          FALSE,
+                          ST_PARAM_READWRITE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, props);
 
   signals[SCROLL_START] =
     g_signal_new ("scroll-start",
@@ -959,7 +961,7 @@ st_scroll_bar_set_adjustment (StScrollBar  *bar,
       clutter_actor_queue_relayout (CLUTTER_ACTOR (bar));
     }
 
-  g_object_notify (G_OBJECT (bar), "adjustment");
+  g_object_notify_by_pspec (G_OBJECT (bar), props[PROP_ADJUSTMENT]);
 }
 
 /**
diff --git a/src/st/st-scroll-view-fade.c b/src/st/st-scroll-view-fade.c
index cc4a2210b..057807a84 100644
--- a/src/st/st-scroll-view-fade.c
+++ b/src/st/st-scroll-view-fade.c
@@ -59,9 +59,13 @@ enum {
 
   PROP_VFADE_OFFSET,
   PROP_HFADE_OFFSET,
-  PROP_FADE_EDGES
+  PROP_FADE_EDGES,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 static CoglTexture *
 st_scroll_view_fade_create_texture (ClutterOffscreenEffect *effect,
                                     gfloat                  min_width,
@@ -273,7 +277,7 @@ st_scroll_view_vfade_set_offset (StScrollViewFade *self,
   if (self->actor != NULL)
     clutter_actor_queue_redraw (self->actor);
 
-  g_object_notify (G_OBJECT (self), "vfade-offset");
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_VFADE_OFFSET]);
   g_object_thaw_notify (G_OBJECT (self));
 }
 
@@ -291,7 +295,7 @@ st_scroll_view_hfade_set_offset (StScrollViewFade *self,
   if (self->actor != NULL)
     clutter_actor_queue_redraw (self->actor);
 
-  g_object_notify (G_OBJECT (self), "hfade-offset");
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HFADE_OFFSET]);
   g_object_thaw_notify (G_OBJECT (self));
 }
 
@@ -309,7 +313,7 @@ st_scroll_view_fade_set_fade_edges (StScrollViewFade *self,
   if (self->actor != NULL)
     clutter_actor_queue_redraw (self->actor);
 
-  g_object_notify (G_OBJECT (self), "fade-edges");
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FADE_EDGES]);
   g_object_thaw_notify (G_OBJECT (self));
 }
 
@@ -384,29 +388,28 @@ st_scroll_view_fade_class_init (StScrollViewFadeClass *klass)
   offscreen_class->create_texture = st_scroll_view_fade_create_texture;
   offscreen_class->paint_target = st_scroll_view_fade_paint_target;
 
-  g_object_class_install_property (gobject_class,
-                                   PROP_VFADE_OFFSET,
-                                   g_param_spec_float ("vfade-offset",
-                                                       "Vertical Fade Offset",
-                                                       "The height of the area which is faded at the edge",
-                                                       0.f, G_MAXFLOAT, DEFAULT_FADE_OFFSET,
-                                                       ST_PARAM_READWRITE));
-  g_object_class_install_property (gobject_class,
-                                   PROP_HFADE_OFFSET,
-                                   g_param_spec_float ("hfade-offset",
-                                                       "Horizontal Fade Offset",
-                                                       "The width of the area which is faded at the edge",
-                                                       0.f, G_MAXFLOAT, DEFAULT_FADE_OFFSET,
-                                                       ST_PARAM_READWRITE));
-  g_object_class_install_property (gobject_class,
-                                   PROP_FADE_EDGES,
-                                   g_param_spec_boolean ("fade-edges",
-                                                         "Fade Edges",
-                                                         "Whether the faded area should extend to the edges",
-                                                         FALSE,
-                                                         ST_PARAM_READWRITE));
-
-
+  props[PROP_VFADE_OFFSET] =
+    g_param_spec_float ("vfade-offset",
+                        "Vertical Fade Offset",
+                        "The height of the area which is faded at the edge",
+                        0.f, G_MAXFLOAT, DEFAULT_FADE_OFFSET,
+                        ST_PARAM_READWRITE);
+
+  props[PROP_HFADE_OFFSET] =
+    g_param_spec_float ("hfade-offset",
+                        "Horizontal Fade Offset",
+                        "The width of the area which is faded at the edge",
+                        0.f, G_MAXFLOAT, DEFAULT_FADE_OFFSET,
+                        ST_PARAM_READWRITE);
+
+  props[PROP_FADE_EDGES] =
+    g_param_spec_boolean ("fade-edges",
+                          "Fade Edges",
+                          "Whether the faded area should extend to the edges",
+                          FALSE,
+                          ST_PARAM_READWRITE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, props);
 }
 
 static void
diff --git a/src/st/st-scroll-view.c b/src/st/st-scroll-view.c
index f6a2ac973..89b4e6cd9 100644
--- a/src/st/st-scroll-view.c
+++ b/src/st/st-scroll-view.c
@@ -116,8 +116,12 @@ enum {
   PROP_VSCROLLBAR_VISIBLE,
   PROP_MOUSE_SCROLL,
   PROP_OVERLAY_SCROLLBARS,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 static void
 st_scroll_view_get_property (GObject    *object,
                              guint       property_id,
@@ -693,7 +697,8 @@ st_scroll_view_allocate (ClutterActor          *actor,
     {
       g_object_freeze_notify (G_OBJECT (actor));
       priv->hscrollbar_visible = hscrollbar_visible;
-      g_object_notify (G_OBJECT (actor), "hscrollbar-visible");
+      g_object_notify_by_pspec (G_OBJECT (actor),
+                                props[PROP_HSCROLLBAR_VISIBLE]);
       g_object_thaw_notify (G_OBJECT (actor));
     }
 
@@ -701,7 +706,8 @@ st_scroll_view_allocate (ClutterActor          *actor,
     {
       g_object_freeze_notify (G_OBJECT (actor));
       priv->vscrollbar_visible = vscrollbar_visible;
-      g_object_notify (G_OBJECT (actor), "vscrollbar-visible");
+      g_object_notify_by_pspec (G_OBJECT (actor),
+                                props[PROP_VSCROLLBAR_VISIBLE]);
       g_object_thaw_notify (G_OBJECT (actor));
     }
 
@@ -791,7 +797,6 @@ st_scroll_view_scroll_event (ClutterActor       *self,
 static void
 st_scroll_view_class_init (StScrollViewClass *klass)
 {
-  GParamSpec *pspec;
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
   StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
@@ -810,70 +815,65 @@ st_scroll_view_class_init (StScrollViewClass *klass)
 
   widget_class->style_changed = st_scroll_view_style_changed;
 
-  g_object_class_install_property (object_class,
-                                   PROP_HSCROLL,
-                                   g_param_spec_object ("hscroll",
-                                                        "StScrollBar",
-                                                        "Horizontal scroll indicator",
-                                                        ST_TYPE_SCROLL_BAR,
-                                                        ST_PARAM_READABLE));
-
-  g_object_class_install_property (object_class,
-                                   PROP_VSCROLL,
-                                   g_param_spec_object ("vscroll",
-                                                        "StScrollBar",
-                                                        "Vertical scroll indicator",
-                                                        ST_TYPE_SCROLL_BAR,
-                                                        ST_PARAM_READABLE));
-
-
-  pspec = g_param_spec_enum ("vscrollbar-policy",
-                             "Vertical Scrollbar Policy",
-                             "When the vertical scrollbar is displayed",
-                             ST_TYPE_POLICY_TYPE,
-                             ST_POLICY_AUTOMATIC,
-                             ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class, PROP_VSCROLLBAR_POLICY, pspec);
-
-  pspec = g_param_spec_enum ("hscrollbar-policy",
-                             "Horizontal Scrollbar Policy",
-                             "When the horizontal scrollbar is displayed",
-                             ST_TYPE_POLICY_TYPE,
-                             ST_POLICY_AUTOMATIC,
-                             ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class, PROP_HSCROLLBAR_POLICY, pspec);
-
-  pspec = g_param_spec_boolean ("hscrollbar-visible",
-                                "Horizontal Scrollbar Visibility",
-                                "Whether the horizontal scrollbar is visible",
-                                TRUE,
-                                ST_PARAM_READABLE);
-  g_object_class_install_property (object_class, PROP_HSCROLLBAR_VISIBLE, pspec);
-
-  pspec = g_param_spec_boolean ("vscrollbar-visible",
-                                "Vertical Scrollbar Visibility",
-                                "Whether the vertical scrollbar is visible",
-                                TRUE,
-                                ST_PARAM_READABLE);
-  g_object_class_install_property (object_class, PROP_VSCROLLBAR_VISIBLE, pspec);
-
-  pspec = g_param_spec_boolean ("enable-mouse-scrolling",
-                                "Enable Mouse Scrolling",
-                                "Enable automatic mouse wheel scrolling",
-                                TRUE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class,
-                                   PROP_MOUSE_SCROLL,
-                                   pspec);
-
-  pspec = g_param_spec_boolean ("overlay-scrollbars",
-                                "Use Overlay Scrollbars",
-                                "Overlay scrollbars over the content",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (object_class,
-                                   PROP_OVERLAY_SCROLLBARS,
-                                   pspec);
+  props[PROP_HSCROLL] =
+    g_param_spec_object ("hscroll",
+                         "StScrollBar",
+                         "Horizontal scroll indicator",
+                         ST_TYPE_SCROLL_BAR,
+                         ST_PARAM_READABLE);
+
+  props[PROP_VSCROLL] =
+    g_param_spec_object ("vscroll",
+                         "StScrollBar",
+                         "Vertical scroll indicator",
+                         ST_TYPE_SCROLL_BAR,
+                         ST_PARAM_READABLE);
+
+  props[PROP_VSCROLLBAR_POLICY] =
+    g_param_spec_enum ("vscrollbar-policy",
+                       "Vertical Scrollbar Policy",
+                       "When the vertical scrollbar is displayed",
+                       ST_TYPE_POLICY_TYPE,
+                       ST_POLICY_AUTOMATIC,
+                       ST_PARAM_READWRITE);
+
+  props[PROP_HSCROLLBAR_POLICY] =
+    g_param_spec_enum ("hscrollbar-policy",
+                       "Horizontal Scrollbar Policy",
+                       "When the horizontal scrollbar is displayed",
+                       ST_TYPE_POLICY_TYPE,
+                       ST_POLICY_AUTOMATIC,
+                       ST_PARAM_READWRITE);
+
+  props[PROP_HSCROLLBAR_VISIBLE] =
+    g_param_spec_boolean ("hscrollbar-visible",
+                          "Horizontal Scrollbar Visibility",
+                          "Whether the horizontal scrollbar is visible",
+                          TRUE,
+                          ST_PARAM_READABLE);
+
+  props[PROP_VSCROLLBAR_VISIBLE] =
+    g_param_spec_boolean ("vscrollbar-visible",
+                          "Vertical Scrollbar Visibility",
+                          "Whether the vertical scrollbar is visible",
+                          TRUE,
+                          ST_PARAM_READABLE);
+
+  props[PROP_MOUSE_SCROLL] =
+    g_param_spec_boolean ("enable-mouse-scrolling",
+                          "Enable Mouse Scrolling",
+                          "Enable automatic mouse wheel scrolling",
+                          TRUE,
+                          ST_PARAM_READWRITE);
+
+  props[PROP_OVERLAY_SCROLLBARS] =
+    g_param_spec_boolean ("overlay-scrollbars",
+                          "Use Overlay Scrollbars",
+                          "Overlay scrollbars over the content",
+                          FALSE,
+                          ST_PARAM_READWRITE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, props);
 }
 
 static void
@@ -1156,7 +1156,8 @@ st_scroll_view_set_overlay_scrollbars (StScrollView *scroll,
   if (priv->overlay_scrollbars != enabled)
     {
       priv->overlay_scrollbars = enabled;
-      g_object_notify (G_OBJECT (scroll), "overlay-scrollbars");
+      g_object_notify_by_pspec (G_OBJECT (scroll),
+                                props[PROP_OVERLAY_SCROLLBARS]);
       clutter_actor_queue_relayout (CLUTTER_ACTOR (scroll));
     }
 }
@@ -1206,13 +1207,15 @@ st_scroll_view_set_policy (StScrollView   *scroll,
   if (priv->hscrollbar_policy != hscroll)
     {
       priv->hscrollbar_policy = hscroll;
-      g_object_notify ((GObject *) scroll, "hscrollbar-policy");
+      g_object_notify_by_pspec ((GObject *) scroll,
+                                props[PROP_HSCROLLBAR_POLICY]);
     }
 
   if (priv->vscrollbar_policy != vscroll)
     {
       priv->vscrollbar_policy = vscroll;
-      g_object_notify ((GObject *) scroll, "vscrollbar-policy");
+      g_object_notify_by_pspec ((GObject *) scroll,
+                                props[PROP_VSCROLLBAR_POLICY]);
     }
 
   clutter_actor_queue_relayout (CLUTTER_ACTOR (scroll));
diff --git a/src/st/st-widget.c b/src/st/st-widget.c
index 63e3ab9d1..7aff6e50c 100644
--- a/src/st/st-widget.c
+++ b/src/st/st-widget.c
@@ -115,9 +115,13 @@ enum
   PROP_CAN_FOCUS,
   PROP_LABEL_ACTOR,
   PROP_ACCESSIBLE_ROLE,
-  PROP_ACCESSIBLE_NAME
+  PROP_ACCESSIBLE_NAME,
+
+  N_PROPS
 };
 
+static GParamSpec *props[N_PROPS] = { NULL, };
+
 enum
 {
   STYLE_CHANGED,
@@ -834,7 +838,6 @@ st_widget_class_init (StWidgetClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
-  GParamSpec *pspec;
 
   gobject_class->set_property = st_widget_set_property;
   gobject_class->get_property = st_widget_get_property;
@@ -869,25 +872,24 @@ st_widget_class_init (StWidgetClass *klass)
    * The pseudo-class of the actor. Typical values include "hover", "active",
    * "focus".
    */
-  g_object_class_install_property (gobject_class,
-                                   PROP_PSEUDO_CLASS,
-                                   g_param_spec_string ("pseudo-class",
-                                                        "Pseudo Class",
-                                                        "Pseudo class for styling",
-                                                        "",
-                                                        ST_PARAM_READWRITE));
+  props[PROP_PSEUDO_CLASS] =
+    g_param_spec_string ("pseudo-class",
+                         "Pseudo Class",
+                         "Pseudo class for styling",
+                         "",
+                         ST_PARAM_READWRITE);
+
   /**
    * StWidget:style-class:
    *
    * The style-class of the actor for use in styling.
    */
-  g_object_class_install_property (gobject_class,
-                                   PROP_STYLE_CLASS,
-                                   g_param_spec_string ("style-class",
-                                                        "Style Class",
-                                                        "Style class for styling",
-                                                        "",
-                                                        ST_PARAM_READWRITE));
+  props[PROP_STYLE_CLASS] =
+    g_param_spec_string ("style-class",
+                         "Style Class",
+                         "Style class for styling",
+                         "",
+                         ST_PARAM_READWRITE);
 
   /**
    * StWidget:style:
@@ -895,13 +897,12 @@ st_widget_class_init (StWidgetClass *klass)
    * Inline style information for the actor as a ';'-separated list of
    * CSS properties.
    */
-  g_object_class_install_property (gobject_class,
-                                   PROP_STYLE,
-                                   g_param_spec_string ("style",
-                                                        "Style",
-                                                        "Inline style string",
-                                                        "",
-                                                        ST_PARAM_READWRITE));
+  props[PROP_STYLE] =
+     g_param_spec_string ("style",
+                          "Style",
+                          "Inline style string",
+                          "",
+                          ST_PARAM_READWRITE);
 
   /**
    * StWidget:theme:
@@ -909,13 +910,12 @@ st_widget_class_init (StWidgetClass *klass)
    * A theme set on this actor overriding the global theming for this actor
    * and its descendants
    */
-  g_object_class_install_property (gobject_class,
-                                   PROP_THEME,
-                                   g_param_spec_object ("theme",
-                                                        "Theme",
-                                                        "Theme override",
-                                                        ST_TYPE_THEME,
-                                                        ST_PARAM_READWRITE));
+  props[PROP_THEME] =
+     g_param_spec_object ("theme",
+                          "Theme",
+                          "Theme override",
+                          ST_TYPE_THEME,
+                          ST_PARAM_READWRITE);
 
   /**
    * StWidget:track-hover:
@@ -926,14 +926,12 @@ st_widget_class_init (StWidgetClass *klass)
    * adjusted automatically as the pointer moves in and out of the
    * widget.
    */
-  pspec = g_param_spec_boolean ("track-hover",
-                                "Track hover",
-                                "Determines whether the widget tracks hover state",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class,
-                                   PROP_TRACK_HOVER,
-                                   pspec);
+  props[PROP_TRACK_HOVER] =
+     g_param_spec_object ("track-hover",
+                          "Track hover",
+                          "Determines whether the widget tracks hover state",
+                          FALSE,
+                          ST_PARAM_READWRITE);
 
   /**
    * StWidget:hover:
@@ -942,68 +940,63 @@ st_widget_class_init (StWidgetClass *klass)
    * only tracked automatically if #StWidget:track-hover is %TRUE, but you can
    * adjust it manually in any case.
    */
-  pspec = g_param_spec_boolean ("hover",
-                                "Hover",
-                                "Whether the pointer is hovering over the widget",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class,
-                                   PROP_HOVER,
-                                   pspec);
+  props[PROP_HOVER] =
+     g_param_spec_boolean ("hover",
+                           "Hover",
+                           "Whether the pointer is hovering over the widget",
+                           FALSE,
+                           ST_PARAM_READWRITE);
 
   /**
    * StWidget:can-focus:
    *
    * Whether or not the widget can be focused via keyboard navigation.
    */
-  pspec = g_param_spec_boolean ("can-focus",
-                                "Can focus",
-                                "Whether the widget can be focused via keyboard navigation",
-                                FALSE,
-                                ST_PARAM_READWRITE);
-  g_object_class_install_property (gobject_class,
-                                   PROP_CAN_FOCUS,
-                                   pspec);
+  props[PROP_CAN_FOCUS] =
+     g_param_spec_boolean ("can-focus",
+                           "Can focus",
+                           "Whether the widget can be focused via keyboard navigation",
+                           FALSE,
+                           ST_PARAM_READWRITE);
 
   /**
    * ClutterActor:label-actor:
    *
    * An actor that labels this widget.
    */
-  g_object_class_install_property (gobject_class,
-                                   PROP_LABEL_ACTOR,
-                                   g_param_spec_object ("label-actor",
-                                                        "Label",
-                                                        "Label that identifies this widget",
-                                                        CLUTTER_TYPE_ACTOR,
-                                                        ST_PARAM_READWRITE));
+  props[PROP_LABEL_ACTOR] =
+     g_param_spec_object ("label-actor",
+                          "Label",
+                          "Label that identifies this widget",
+                          CLUTTER_TYPE_ACTOR,
+                          ST_PARAM_READWRITE);
+
   /**
    * StWidget:accessible-role:
    *
    * The accessible role of this object
    */
-  g_object_class_install_property (gobject_class,
-                                   PROP_ACCESSIBLE_ROLE,
-                                   g_param_spec_enum ("accessible-role",
-                                                      "Accessible Role",
-                                                      "The accessible role of this object",
-                                                      ATK_TYPE_ROLE,
-                                                      ATK_ROLE_INVALID,
-                                                      ST_PARAM_READWRITE));
-
+  props[PROP_ACCESSIBLE_ROLE] =
+     g_param_spec_enum ("accessible-role",
+                        "Accessible Role",
+                        "The accessible role of this object",
+                        ATK_TYPE_ROLE,
+                        ATK_ROLE_INVALID,
+                        ST_PARAM_READWRITE);
 
   /**
    * StWidget:accessible-name:
    *
    * Object instance's name for assistive technology access.
    */
-  g_object_class_install_property (gobject_class,
-                                   PROP_ACCESSIBLE_NAME,
-                                   g_param_spec_string ("accessible-name",
-                                                        "Accessible name",
-                                                        "Object instance's name for assistive technology 
access.",
-                                                        NULL,
-                                                        ST_PARAM_READWRITE));
+  props[PROP_ACCESSIBLE_NAME] =
+     g_param_spec_string ("accessible-name",
+                          "Accessible name",
+                          "Object instance's name for assistive technology access.",
+                          NULL,
+                          ST_PARAM_READWRITE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, props);
 
   /**
    * StWidget::style-changed:
@@ -1077,7 +1070,7 @@ st_widget_set_theme (StWidget  *actor,
 
       st_widget_style_changed (actor);
 
-      g_object_notify (G_OBJECT (actor), "theme");
+      g_object_notify_by_pspec (G_OBJECT (actor), props[PROP_THEME]);
     }
 }
 
@@ -1213,7 +1206,7 @@ st_widget_set_style_class_name (StWidget    *actor,
   if (set_class_list (&priv->style_class, style_class_list))
     {
       st_widget_style_changed (actor);
-      g_object_notify (G_OBJECT (actor), "style-class");
+      g_object_notify_by_pspec (G_OBJECT (actor), props[PROP_STYLE_CLASS]);
     }
 }
 
@@ -1239,7 +1232,7 @@ st_widget_add_style_class_name (StWidget    *actor,
   if (add_class_name (&priv->style_class, style_class))
     {
       st_widget_style_changed (actor);
-      g_object_notify (G_OBJECT (actor), "style-class");
+      g_object_notify_by_pspec (G_OBJECT (actor), props[PROP_STYLE_CLASS]);
     }
 }
 
@@ -1265,7 +1258,7 @@ st_widget_remove_style_class_name (StWidget    *actor,
   if (remove_class_name (&priv->style_class, style_class))
     {
       st_widget_style_changed (actor);
-      g_object_notify (G_OBJECT (actor), "style-class");
+      g_object_notify_by_pspec (G_OBJECT (actor), props[PROP_STYLE_CLASS]);
     }
 }
 
@@ -1376,7 +1369,7 @@ st_widget_set_style_pseudo_class (StWidget    *actor,
   if (set_class_list (&priv->pseudo_class, pseudo_class_list))
     {
       st_widget_style_changed (actor);
-      g_object_notify (G_OBJECT (actor), "pseudo-class");
+      g_object_notify_by_pspec (G_OBJECT (actor), props[PROP_PSEUDO_CLASS]);
     }
 }
 
@@ -1402,7 +1395,7 @@ st_widget_add_style_pseudo_class (StWidget    *actor,
   if (add_class_name (&priv->pseudo_class, pseudo_class))
     {
       st_widget_style_changed (actor);
-      g_object_notify (G_OBJECT (actor), "pseudo-class");
+      g_object_notify_by_pspec (G_OBJECT (actor), props[PROP_PSEUDO_CLASS]);
     }
 }
 
@@ -1427,7 +1420,7 @@ st_widget_remove_style_pseudo_class (StWidget    *actor,
   if (remove_class_name (&priv->pseudo_class, pseudo_class))
     {
       st_widget_style_changed (actor);
-      g_object_notify (G_OBJECT (actor), "pseudo-class");
+      g_object_notify_by_pspec (G_OBJECT (actor), props[PROP_PSEUDO_CLASS]);
     }
 }
 
@@ -1457,7 +1450,7 @@ st_widget_set_style (StWidget  *actor,
 
       st_widget_style_changed (actor);
 
-      g_object_notify (G_OBJECT (actor), "style");
+      g_object_notify_by_pspec (G_OBJECT (actor), props[PROP_STYLE]);
     }
 }
 
@@ -1907,7 +1900,7 @@ st_widget_set_track_hover (StWidget *widget,
   if (priv->track_hover != track_hover)
     {
       priv->track_hover = track_hover;
-      g_object_notify (G_OBJECT (widget), "track-hover");
+      g_object_notify_by_pspec (G_OBJECT (widget), props[PROP_TRACK_HOVER]);
 
       if (priv->track_hover)
         st_widget_sync_hover (widget);
@@ -1962,7 +1955,7 @@ st_widget_set_hover (StWidget *widget,
         st_widget_add_style_pseudo_class (widget, "hover");
       else
         st_widget_remove_style_pseudo_class (widget, "hover");
-      g_object_notify (G_OBJECT (widget), "hover");
+      g_object_notify_by_pspec (G_OBJECT (widget), props[PROP_HOVER]);
     }
 }
 
@@ -2029,7 +2022,7 @@ st_widget_set_can_focus (StWidget *widget,
   if (priv->can_focus != can_focus)
     {
       priv->can_focus = can_focus;
-      g_object_notify (G_OBJECT (widget), "can-focus");
+      g_object_notify_by_pspec (G_OBJECT (widget), props[PROP_CAN_FOCUS]);
     }
 }
 
@@ -2526,7 +2519,7 @@ st_widget_set_label_actor (StWidget     *widget,
       else
         priv->label_actor = NULL;
 
-      g_object_notify (G_OBJECT (widget), "label-actor");
+      g_object_notify_by_pspec (G_OBJECT (widget), props[PROP_LABEL_ACTOR]);
     }
 }
 
@@ -2559,7 +2552,7 @@ st_widget_set_accessible_name (StWidget    *widget,
     g_free (priv->accessible_name);
 
   priv->accessible_name = g_strdup (name);
-  g_object_notify (G_OBJECT (widget), "accessible-name");
+  g_object_notify_by_pspec (G_OBJECT (widget), props[PROP_ACCESSIBLE_NAME]);
 }
 
 /**
@@ -2613,7 +2606,7 @@ st_widget_set_accessible_role (StWidget *widget,
   priv = st_widget_get_instance_private (widget);
   priv->accessible_role = role;
 
-  g_object_notify (G_OBJECT (widget), "accessible-role");
+  g_object_notify_by_pspec (G_OBJECT (widget), props[PROP_ACCESSIBLE_ROLE]);
 }
 
 


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