mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-06-05 20:30:07 +02:00
GDBus: Catch up with new PropertiesChanged signal
After a long discussion, this has finally been standardized in the D-Bus spec. See http://lists.freedesktop.org/archives/dbus/2010-May/012667.html http://lists.freedesktop.org/archives/dbus/2010-May/012712.html Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
parent
2d75583fb2
commit
82158afdad
@ -3549,6 +3549,7 @@ static const gchar introspect_standard_interfaces[] =
|
|||||||
" <signal name=\"PropertiesChanged\">\n"
|
" <signal name=\"PropertiesChanged\">\n"
|
||||||
" <arg type=\"s\" name=\"interface_name\"/>\n"
|
" <arg type=\"s\" name=\"interface_name\"/>\n"
|
||||||
" <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"
|
" <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"
|
||||||
|
" <arg type=\"as\" name=\"invalidated_properties\"/>\n"
|
||||||
" </signal>\n"
|
" </signal>\n"
|
||||||
" </interface>\n"
|
" </interface>\n"
|
||||||
" <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
|
" <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
|
||||||
|
@ -387,10 +387,17 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
|
|||||||
/**
|
/**
|
||||||
* GDBusProxy::g-properties-changed:
|
* GDBusProxy::g-properties-changed:
|
||||||
* @proxy: The #GDBusProxy emitting the signal.
|
* @proxy: The #GDBusProxy emitting the signal.
|
||||||
* @changed_properties: A #GVariant containing the properties that changed.
|
* @changed_properties: A #GVariant containing the properties that
|
||||||
|
* changed or %NULL if no properties changed.
|
||||||
|
* @invalidated_properties: A %NULL terminated list of properties that was
|
||||||
|
* invalidated or %NULL if no properties was invalidated.
|
||||||
*
|
*
|
||||||
* Emitted when one or more D-Bus properties on @proxy changes. The cached properties
|
* Emitted when one or more D-Bus properties on @proxy changes. The
|
||||||
* are already replaced when this signal fires.
|
* local cache has already been updated when this signal fires.
|
||||||
|
*
|
||||||
|
* This signal corresponds to the
|
||||||
|
* <literal>PropertiesChanged</literal> D-Bus signal on the
|
||||||
|
* <literal>org.freedesktop.DBus.Properties</literal> interface.
|
||||||
*
|
*
|
||||||
* Since: 2.26
|
* Since: 2.26
|
||||||
*/
|
*/
|
||||||
@ -400,10 +407,11 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
|
|||||||
G_STRUCT_OFFSET (GDBusProxyClass, g_properties_changed),
|
G_STRUCT_OFFSET (GDBusProxyClass, g_properties_changed),
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
g_cclosure_marshal_VOID__BOXED,
|
_gio_marshal_VOID__BOXED_BOXED,
|
||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
1,
|
2,
|
||||||
G_TYPE_VARIANT);
|
G_TYPE_VARIANT,
|
||||||
|
G_TYPE_STRV);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GDBusProxy::g-signal:
|
* GDBusProxy::g-signal:
|
||||||
@ -669,12 +677,17 @@ on_properties_changed (GDBusConnection *connection,
|
|||||||
GError *error;
|
GError *error;
|
||||||
const gchar *interface_name_for_signal;
|
const gchar *interface_name_for_signal;
|
||||||
GVariantIter *iter;
|
GVariantIter *iter;
|
||||||
|
GVariantIter *invalidated_iter;
|
||||||
GVariant *item;
|
GVariant *item;
|
||||||
GVariant *changed_properties;
|
GVariant *changed_properties;
|
||||||
GVariantBuilder *builder;
|
GVariantBuilder *builder;
|
||||||
|
GPtrArray *p;
|
||||||
|
const gchar *str;
|
||||||
|
gchar **invalidated_properties;
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
iter = NULL;
|
iter = NULL;
|
||||||
|
invalidated_iter = NULL;
|
||||||
|
|
||||||
#if 0 // TODO!
|
#if 0 // TODO!
|
||||||
/* Ignore this signal if properties are not yet available
|
/* Ignore this signal if properties are not yet available
|
||||||
@ -686,27 +699,31 @@ on_properties_changed (GDBusConnection *connection,
|
|||||||
goto out;
|
goto out;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (strcmp (g_variant_get_type_string (parameters), "(sa{sv})") != 0)
|
if (strcmp (g_variant_get_type_string (parameters), "(sa{sv}as)") != 0)
|
||||||
{
|
{
|
||||||
g_warning ("Value for PropertiesChanged signal with type `%s' does not match `(sa{sv})'",
|
g_warning ("Value for PropertiesChanged signal with type `%s' does not match `(sa{sv}as)'",
|
||||||
g_variant_get_type_string (parameters));
|
g_variant_get_type_string (parameters));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_variant_get (parameters,
|
g_variant_get (parameters,
|
||||||
"(sa{sv})",
|
"(sa{sv}as)",
|
||||||
&interface_name_for_signal,
|
&interface_name_for_signal,
|
||||||
&iter);
|
&iter,
|
||||||
|
&invalidated_iter);
|
||||||
|
|
||||||
if (g_strcmp0 (interface_name_for_signal, proxy->priv->interface_name) != 0)
|
if (g_strcmp0 (interface_name_for_signal, proxy->priv->interface_name) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
|
builder = NULL;
|
||||||
while ((item = g_variant_iter_next_value (iter)))
|
while ((item = g_variant_iter_next_value (iter)))
|
||||||
{
|
{
|
||||||
const gchar *key;
|
const gchar *key;
|
||||||
GVariant *value;
|
GVariant *value;
|
||||||
|
|
||||||
|
if (builder == NULL)
|
||||||
|
builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
|
||||||
|
|
||||||
g_variant_get (item,
|
g_variant_get (item,
|
||||||
"{sv}",
|
"{sv}",
|
||||||
&key,
|
&key,
|
||||||
@ -721,16 +738,45 @@ on_properties_changed (GDBusConnection *connection,
|
|||||||
g_strdup (key),
|
g_strdup (key),
|
||||||
g_variant_ref (value));
|
g_variant_ref (value));
|
||||||
}
|
}
|
||||||
changed_properties = g_variant_builder_end (builder);
|
if (builder != NULL)
|
||||||
|
changed_properties = g_variant_builder_end (builder);
|
||||||
|
else
|
||||||
|
changed_properties = NULL;
|
||||||
|
|
||||||
|
p = NULL;
|
||||||
|
while (g_variant_iter_loop (invalidated_iter, "s", &str))
|
||||||
|
{
|
||||||
|
if (p == NULL)
|
||||||
|
p = g_ptr_array_new ();
|
||||||
|
g_ptr_array_add (p, (gpointer) str);
|
||||||
|
}
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
g_ptr_array_add (p, NULL);
|
||||||
|
invalidated_properties = (gchar **) g_ptr_array_free (p, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
invalidated_properties = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* emit signal */
|
/* emit signal */
|
||||||
g_signal_emit (proxy, signals[PROPERTIES_CHANGED_SIGNAL], 0, changed_properties);
|
g_signal_emit (proxy, signals[PROPERTIES_CHANGED_SIGNAL],
|
||||||
|
0,
|
||||||
|
changed_properties,
|
||||||
|
invalidated_properties);
|
||||||
|
|
||||||
g_variant_unref (changed_properties);
|
if (changed_properties != NULL)
|
||||||
|
g_variant_unref (changed_properties);
|
||||||
|
if (invalidated_properties != NULL)
|
||||||
|
g_free (invalidated_properties);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (iter != NULL)
|
if (iter != NULL)
|
||||||
g_variant_iter_free (iter);
|
g_variant_iter_free (iter);
|
||||||
|
if (invalidated_iter != NULL)
|
||||||
|
g_variant_iter_free (invalidated_iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
@ -69,12 +69,13 @@ struct _GDBusProxyClass
|
|||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
/* Signals */
|
/* Signals */
|
||||||
void (*g_properties_changed) (GDBusProxy *proxy,
|
void (*g_properties_changed) (GDBusProxy *proxy,
|
||||||
GVariant *changed_properties);
|
GVariant *changed_properties,
|
||||||
void (*g_signal) (GDBusProxy *proxy,
|
const gchar* const *invalidated_properties);
|
||||||
const gchar *sender_name,
|
void (*g_signal) (GDBusProxy *proxy,
|
||||||
const gchar *signal_name,
|
const gchar *sender_name,
|
||||||
GVariant *parameters);
|
const gchar *signal_name,
|
||||||
|
GVariant *parameters);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* Padding for future expansion */
|
/* Padding for future expansion */
|
||||||
|
@ -8,3 +8,4 @@ BOOL:POINTER,INT
|
|||||||
BOOL:UINT
|
BOOL:UINT
|
||||||
VOID:STRING,STRING,BOXED
|
VOID:STRING,STRING,BOXED
|
||||||
VOID:BOOL,BOXED
|
VOID:BOOL,BOXED
|
||||||
|
VOID:BOXED,BOXED
|
||||||
|
@ -233,9 +233,11 @@ send_property_change (GObject *obj,
|
|||||||
GDBusConnection *connection)
|
GDBusConnection *connection)
|
||||||
{
|
{
|
||||||
GVariantBuilder *builder;
|
GVariantBuilder *builder;
|
||||||
|
GVariantBuilder *invalidated_builder;
|
||||||
MyObject *myobj = (MyObject *)obj;
|
MyObject *myobj = (MyObject *)obj;
|
||||||
|
|
||||||
builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
|
builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
|
||||||
|
invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
|
||||||
|
|
||||||
if (g_strcmp0 (pspec->name, "count") == 0)
|
if (g_strcmp0 (pspec->name, "count") == 0)
|
||||||
g_variant_builder_add (builder,
|
g_variant_builder_add (builder,
|
||||||
@ -251,9 +253,10 @@ send_property_change (GObject *obj,
|
|||||||
"/org/myorg/MyObject",
|
"/org/myorg/MyObject",
|
||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"PropertiesChanged",
|
"PropertiesChanged",
|
||||||
g_variant_new ("(sa{sv})",
|
g_variant_new ("(sa{sv}as)",
|
||||||
"org.myorg.MyObject",
|
"org.myorg.MyObject",
|
||||||
builder),
|
builder,
|
||||||
|
invalidated_builder),
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,27 +202,31 @@ accounts_user_g_signal (GDBusProxy *proxy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
accounts_user_g_properties_changed (GDBusProxy *proxy,
|
accounts_user_g_properties_changed (GDBusProxy *proxy,
|
||||||
GVariant *changed_properties)
|
GVariant *changed_properties,
|
||||||
|
const gchar* const *invalidated_properties)
|
||||||
{
|
{
|
||||||
AccountsUser *user = ACCOUNTS_USER (proxy);
|
AccountsUser *user = ACCOUNTS_USER (proxy);
|
||||||
GVariantIter *iter;
|
GVariantIter *iter;
|
||||||
GVariant *item;
|
GVariant *item;
|
||||||
|
|
||||||
g_variant_get (changed_properties, "a{sv}", &iter);
|
if (changed_properties != NULL)
|
||||||
while ((item = g_variant_iter_next_value (iter)) != NULL)
|
|
||||||
{
|
{
|
||||||
const gchar *key;
|
g_variant_get (changed_properties, "a{sv}", &iter);
|
||||||
g_variant_get (item,
|
while ((item = g_variant_iter_next_value (iter)) != NULL)
|
||||||
"{sv}",
|
{
|
||||||
&key,
|
const gchar *key;
|
||||||
NULL);
|
g_variant_get (item,
|
||||||
if (g_strcmp0 (key, "AutomaticLogin") == 0)
|
"{sv}",
|
||||||
g_object_notify (G_OBJECT (user), "automatic-login");
|
&key,
|
||||||
else if (g_strcmp0 (key, "RealName") == 0)
|
NULL);
|
||||||
g_object_notify (G_OBJECT (user), "real-name");
|
if (g_strcmp0 (key, "AutomaticLogin") == 0)
|
||||||
else if (g_strcmp0 (key, "UserName") == 0)
|
g_object_notify (G_OBJECT (user), "automatic-login");
|
||||||
g_object_notify (G_OBJECT (user), "user-name");
|
else if (g_strcmp0 (key, "RealName") == 0)
|
||||||
|
g_object_notify (G_OBJECT (user), "real-name");
|
||||||
|
else if (g_strcmp0 (key, "UserName") == 0)
|
||||||
|
g_object_notify (G_OBJECT (user), "user-name");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,9 +243,10 @@ handle_set_property (GDBusConnection *connection,
|
|||||||
object_path,
|
object_path,
|
||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"PropertiesChanged",
|
"PropertiesChanged",
|
||||||
g_variant_new ("(sa{sv})",
|
g_variant_new ("(sa{sv}as)",
|
||||||
interface_name,
|
interface_name,
|
||||||
builder),
|
builder,
|
||||||
|
NULL),
|
||||||
&local_error);
|
&local_error);
|
||||||
g_assert_no_error (local_error);
|
g_assert_no_error (local_error);
|
||||||
}
|
}
|
||||||
@ -283,12 +284,14 @@ on_timeout_cb (gpointer user_data)
|
|||||||
{
|
{
|
||||||
GDBusConnection *connection = G_DBUS_CONNECTION (user_data);
|
GDBusConnection *connection = G_DBUS_CONNECTION (user_data);
|
||||||
GVariantBuilder *builder;
|
GVariantBuilder *builder;
|
||||||
|
GVariantBuilder *invalidated_builder;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
swap_a_and_b = !swap_a_and_b;
|
swap_a_and_b = !swap_a_and_b;
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
|
builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
|
||||||
|
invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
|
||||||
g_variant_builder_add (builder,
|
g_variant_builder_add (builder,
|
||||||
"{sv}",
|
"{sv}",
|
||||||
"Foo",
|
"Foo",
|
||||||
@ -302,9 +305,10 @@ on_timeout_cb (gpointer user_data)
|
|||||||
"/org/gtk/GDBus/TestObject",
|
"/org/gtk/GDBus/TestObject",
|
||||||
"org.freedesktop.DBus.Properties",
|
"org.freedesktop.DBus.Properties",
|
||||||
"PropertiesChanged",
|
"PropertiesChanged",
|
||||||
g_variant_new ("(sa{sv})",
|
g_variant_new ("(sa{sv}as)",
|
||||||
"org.gtk.GDBus.TestInterface",
|
"org.gtk.GDBus.TestInterface",
|
||||||
builder),
|
builder,
|
||||||
|
invalidated_builder),
|
||||||
&error);
|
&error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
@ -42,32 +42,45 @@ print_properties (GDBusProxy *proxy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_properties_changed (GDBusProxy *proxy,
|
on_properties_changed (GDBusProxy *proxy,
|
||||||
GVariant *changed_properties,
|
GVariant *changed_properties,
|
||||||
gpointer user_data)
|
const gchar* const *invalidated_properties,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GVariantIter *iter;
|
|
||||||
GVariant *item;
|
|
||||||
|
|
||||||
g_print (" *** Properties Changed:\n");
|
if (changed_properties != NULL)
|
||||||
|
|
||||||
g_variant_get (changed_properties,
|
|
||||||
"a{sv}",
|
|
||||||
&iter);
|
|
||||||
while ((item = g_variant_iter_next_value (iter)))
|
|
||||||
{
|
{
|
||||||
const gchar *key;
|
GVariantIter *iter;
|
||||||
GVariant *value;
|
GVariant *item;
|
||||||
gchar *value_str;
|
|
||||||
|
|
||||||
g_variant_get (item,
|
g_print (" *** Properties Changed:\n");
|
||||||
"{sv}",
|
g_variant_get (changed_properties,
|
||||||
&key,
|
"a{sv}",
|
||||||
&value);
|
&iter);
|
||||||
|
while ((item = g_variant_iter_next_value (iter)))
|
||||||
|
{
|
||||||
|
const gchar *key;
|
||||||
|
GVariant *value;
|
||||||
|
gchar *value_str;
|
||||||
|
g_variant_get (item,
|
||||||
|
"{sv}",
|
||||||
|
&key,
|
||||||
|
&value);
|
||||||
|
value_str = g_variant_print (value, TRUE);
|
||||||
|
g_print (" %s -> %s\n", key, value_str);
|
||||||
|
g_free (value_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
value_str = g_variant_print (value, TRUE);
|
if (invalidated_properties != NULL)
|
||||||
g_print (" %s -> %s\n", key, value_str);
|
{
|
||||||
g_free (value_str);
|
guint n;
|
||||||
|
g_print (" *** Properties Invalidated:\n");
|
||||||
|
for (n = 0; invalidated_properties[n] != NULL; n++)
|
||||||
|
{
|
||||||
|
const gchar *key = invalidated_properties[n];
|
||||||
|
g_print (" %s\n", key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +187,7 @@ class TestService(dbus.service.Object):
|
|||||||
"PropertiesChanged")
|
"PropertiesChanged")
|
||||||
message.append("com.example.Frob")
|
message.append("com.example.Frob")
|
||||||
message.append({prop_name : prop_value})
|
message.append({prop_name : prop_value})
|
||||||
|
message.append([], signature="as")
|
||||||
session_bus.send_message(message)
|
session_bus.send_message(message)
|
||||||
# ----------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user