About g_settings_bind_with_mapping usage

I have an application that uses gsettings in order to save the font as a preference. I want to bind the font property of the gsettings, which is a string, to a font property of a widget. This widget only accept a property “font-desc” which type is PangoFontDescription.

I try to use g_settings_bind_with_mapping:

void
g_settings_bind_with_mapping (GSettings *settings,
                              const gchar *key,
                              gpointer object,
                              const gchar *property,
                              GSettingsBindFlags flags,
                              GSettingsBindGetMapping get_mapping,
                              GSettingsBindSetMapping set_mapping,
                              gpointer user_data,
                              GDestroyNotify destroy);

I know the basic usage of this function will be:

g_settings_bind_with_mapping (settings, "font", 
                              mywidget, "font-desc", 
                              G_SETTINGS_BIND_GET, 
                              get_mapping,
                              NULL,
                              NULL,
                              NULL
)

but I have a hard time to figure out how to write the get_mapping function, with (pango_font_description_from_string () as the converter) following the documentation:

gboolean
(*GSettingsBindGetMapping) (GValue *value,
                            GVariant *variant,
                            gpointer user_data);

The GSettingsBindGetMapping function works by turning the data inside the GVariant instance and setting it into the GValue container—which has already been initialised with the type of the property.

So, if the GVariant coming from the settings backend contains a string, and the GValue is for a property of type PangoFontDescription, you will need something like:

static gboolean
font_string_to_font_desc (GValue   *value,
                          GVariant *variant,
                          gpointer  user_data)
{
  const char *str = NULL;

  // get a pointer out of the variant, instead of copying the string out
  g_variant_get (variant, "&s", &str);

  // empty strings are invalid
  if (str ==NULL || *str == '\0')
    return FALSE;

  // create a new PangoFontDescription from the font description string
  PangoFontDescription *font_desc = pango_font_description_from_string (s);

  if (font_desc == NULL)
    return FALSE;

  // PangoFontDescription is a boxed GType, so we use the appropriate setter
  // for GValue; we want the GValue to take ownership of the newly created
  // font description instance, since we don't care about it any more
  g_value_take_boxed (value, font_desc);

  // conversion successful
  return TRUE;
}

You can add more validation layers in between, and you can add some fallback values for empty/invalid strings if you want.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.