mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
gdbus-codegen: honor "Property.EmitsChangedSignal" annotations
Co-Authored-by: Andy Holmes <andrew.g.r.holmes@gmail.com>
This commit is contained in:
parent
27369def50
commit
5731f06541
@ -959,7 +959,8 @@ class CodeGenerator:
|
|||||||
'{\n'
|
'{\n'
|
||||||
' GDBusPropertyInfo parent_struct;\n'
|
' GDBusPropertyInfo parent_struct;\n'
|
||||||
' const gchar *hyphen_name;\n'
|
' const gchar *hyphen_name;\n'
|
||||||
' gboolean use_gvariant;\n'
|
' guint use_gvariant : 1;\n'
|
||||||
|
' guint emits_changed_signal : 1;\n'
|
||||||
'} _ExtendedGDBusPropertyInfo;\n'
|
'} _ExtendedGDBusPropertyInfo;\n'
|
||||||
'\n')
|
'\n')
|
||||||
|
|
||||||
@ -1254,9 +1255,13 @@ class CodeGenerator:
|
|||||||
' "%s",\n'
|
' "%s",\n'
|
||||||
%(p.name_hyphen))
|
%(p.name_hyphen))
|
||||||
if not utils.lookup_annotation(p.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
|
if not utils.lookup_annotation(p.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
|
||||||
self.outfile.write(' FALSE\n')
|
self.outfile.write(' FALSE,\n')
|
||||||
else:
|
else:
|
||||||
|
self.outfile.write(' TRUE,\n')
|
||||||
|
if p.emits_changed_signal:
|
||||||
self.outfile.write(' TRUE\n')
|
self.outfile.write(' TRUE\n')
|
||||||
|
else:
|
||||||
|
self.outfile.write(' FALSE\n')
|
||||||
self.outfile.write('};\n'
|
self.outfile.write('};\n'
|
||||||
'\n')
|
'\n')
|
||||||
|
|
||||||
@ -2892,14 +2897,17 @@ class CodeGenerator:
|
|||||||
' const GValue *value,\n'
|
' const GValue *value,\n'
|
||||||
' GParamSpec *pspec)\n'
|
' GParamSpec *pspec)\n'
|
||||||
'{\n'%(i.name_lower))
|
'{\n'%(i.name_lower))
|
||||||
self.outfile.write(' %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
|
self.outfile.write(' const _ExtendedGDBusPropertyInfo *info;\n'
|
||||||
|
' %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
|
||||||
' g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
|
' g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
|
||||||
|
' info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n'
|
||||||
' g_mutex_lock (&skeleton->priv->lock);\n'
|
' g_mutex_lock (&skeleton->priv->lock);\n'
|
||||||
' g_object_freeze_notify (object);\n'
|
' g_object_freeze_notify (object);\n'
|
||||||
' if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))\n'
|
' if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))\n'
|
||||||
' {\n'
|
' {\n'
|
||||||
' if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL)\n'
|
' if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL &&\n'
|
||||||
' _%s_schedule_emit_changed (skeleton, (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1], prop_id, &skeleton->priv->properties[prop_id - 1]);\n'
|
' info->emits_changed_signal)\n'
|
||||||
|
' _%s_schedule_emit_changed (skeleton, info, prop_id, &skeleton->priv->properties[prop_id - 1]);\n'
|
||||||
' g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);\n'
|
' g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);\n'
|
||||||
' g_object_notify_by_pspec (object, pspec);\n'
|
' g_object_notify_by_pspec (object, pspec);\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
|
@ -354,6 +354,7 @@ class Property:
|
|||||||
self.doc_string = ''
|
self.doc_string = ''
|
||||||
self.since = ''
|
self.since = ''
|
||||||
self.deprecated = False
|
self.deprecated = False
|
||||||
|
self.emits_changed_signal = True
|
||||||
|
|
||||||
def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface):
|
def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface):
|
||||||
if len(self.doc_string) == 0:
|
if len(self.doc_string) == 0:
|
||||||
@ -386,6 +387,12 @@ class Property:
|
|||||||
for a in self.annotations:
|
for a in self.annotations:
|
||||||
a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
|
a.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
|
||||||
|
|
||||||
|
# FIXME: for now we only support 'false' and 'const' on the signal itself, see #674913 and
|
||||||
|
# http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
|
||||||
|
# for details
|
||||||
|
if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Property.EmitsChangedSignal') in ('false', 'const'):
|
||||||
|
self.emits_changed_signal = False
|
||||||
|
|
||||||
class Interface:
|
class Interface:
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -1768,9 +1768,9 @@ on_object_proxy_removed (GDBusObjectManagerClient *manager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
property_d_changed (GObject *object,
|
property_changed (GObject *object,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
gboolean *changed = user_data;
|
gboolean *changed = user_data;
|
||||||
|
|
||||||
@ -1783,6 +1783,8 @@ om_check_property_and_signal_emission (GMainLoop *loop,
|
|||||||
FooiGenBar *proxy)
|
FooiGenBar *proxy)
|
||||||
{
|
{
|
||||||
gboolean d_changed = FALSE;
|
gboolean d_changed = FALSE;
|
||||||
|
gboolean quiet_changed = FALSE;
|
||||||
|
gboolean quiet_too_changed = FALSE;
|
||||||
guint handler;
|
guint handler;
|
||||||
|
|
||||||
/* First PropertiesChanged */
|
/* First PropertiesChanged */
|
||||||
@ -1804,13 +1806,35 @@ om_check_property_and_signal_emission (GMainLoop *loop,
|
|||||||
* notifications are serialized.
|
* notifications are serialized.
|
||||||
*/
|
*/
|
||||||
handler = g_signal_connect (proxy, "notify::d",
|
handler = g_signal_connect (proxy, "notify::d",
|
||||||
G_CALLBACK (property_d_changed), &d_changed);
|
G_CALLBACK (property_changed), &d_changed);
|
||||||
foo_igen_bar_set_d (skeleton, 1.0);
|
foo_igen_bar_set_d (skeleton, 1.0);
|
||||||
foo_igen_bar_set_i (skeleton, 2);
|
foo_igen_bar_set_i (skeleton, 2);
|
||||||
_g_assert_property_notify (proxy, "i");
|
_g_assert_property_notify (proxy, "i");
|
||||||
g_assert (d_changed == FALSE);
|
g_assert (d_changed == FALSE);
|
||||||
g_signal_handler_disconnect (proxy, handler);
|
g_signal_handler_disconnect (proxy, handler);
|
||||||
|
|
||||||
|
/* Verify that re-setting a property with the "EmitsChangedSignal"
|
||||||
|
* set to false doesn't emit a signal. */
|
||||||
|
handler = g_signal_connect (proxy, "notify::quiet",
|
||||||
|
G_CALLBACK (property_changed), &quiet_changed);
|
||||||
|
foo_igen_bar_set_quiet (skeleton, "hush!");
|
||||||
|
foo_igen_bar_set_i (skeleton, 3);
|
||||||
|
_g_assert_property_notify (proxy, "i");
|
||||||
|
g_assert (quiet_changed == FALSE);
|
||||||
|
g_assert_cmpstr (foo_igen_bar_get_quiet (skeleton), ==, "hush!");
|
||||||
|
g_signal_handler_disconnect (proxy, handler);
|
||||||
|
|
||||||
|
/* Also verify that re-setting a property with the "EmitsChangedSignal"
|
||||||
|
* set to 'const' doesn't emit a signal. */
|
||||||
|
handler = g_signal_connect (proxy, "notify::quiet-too",
|
||||||
|
G_CALLBACK (property_changed), &quiet_changed);
|
||||||
|
foo_igen_bar_set_quiet_too (skeleton, "hush too!");
|
||||||
|
foo_igen_bar_set_i (skeleton, 4);
|
||||||
|
_g_assert_property_notify (proxy, "i");
|
||||||
|
g_assert (quiet_too_changed == FALSE);
|
||||||
|
g_assert_cmpstr (foo_igen_bar_get_quiet_too (skeleton), ==, "hush too!");
|
||||||
|
g_signal_handler_disconnect (proxy, handler);
|
||||||
|
|
||||||
/* Then just a regular signal */
|
/* Then just a regular signal */
|
||||||
foo_igen_bar_emit_another_signal (skeleton, "word");
|
foo_igen_bar_emit_another_signal (skeleton, "word");
|
||||||
_g_assert_signal_received (proxy, "another-signal");
|
_g_assert_signal_received (proxy, "another-signal");
|
||||||
@ -2152,7 +2176,7 @@ check_object_manager (void)
|
|||||||
* that ObjectManager.GetManagedObjects() works
|
* that ObjectManager.GetManagedObjects() works
|
||||||
*/
|
*/
|
||||||
om_check_get_all (c, loop,
|
om_check_get_all (c, loop,
|
||||||
"({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)");
|
"({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'quiet': <''>, 'quiet_too': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)");
|
||||||
|
|
||||||
/* Set connection to NULL, causing everything to be unexported.. verify this.. and
|
/* Set connection to NULL, causing everything to be unexported.. verify this.. and
|
||||||
* then set the connection back.. and then check things still work
|
* then set the connection back.. and then check things still work
|
||||||
@ -2164,7 +2188,7 @@ check_object_manager (void)
|
|||||||
|
|
||||||
g_dbus_object_manager_server_set_connection (manager, c);
|
g_dbus_object_manager_server_set_connection (manager, c);
|
||||||
om_check_get_all (c, loop,
|
om_check_get_all (c, loop,
|
||||||
"({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)");
|
"({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'quiet': <''>, 'quiet_too': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)");
|
||||||
|
|
||||||
/* Also check that the ObjectManagerClient returns these objects - and
|
/* Also check that the ObjectManagerClient returns these objects - and
|
||||||
* that they are of the right GType cf. what was requested via
|
* that they are of the right GType cf. what was requested via
|
||||||
|
@ -106,6 +106,12 @@
|
|||||||
<property name="FinallyNormalName" type="s" access="readwrite"/>
|
<property name="FinallyNormalName" type="s" access="readwrite"/>
|
||||||
<property name="ReadonlyProperty" type="s" access="read"/>
|
<property name="ReadonlyProperty" type="s" access="read"/>
|
||||||
<property name="WriteonlyProperty" type="s" access="write"/>
|
<property name="WriteonlyProperty" type="s" access="write"/>
|
||||||
|
<property name="quiet" type="s" access="readwrite">
|
||||||
|
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
|
||||||
|
</property>
|
||||||
|
<property name="quiet_too" type="s" access="readwrite">
|
||||||
|
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
<!-- unset properties -->
|
<!-- unset properties -->
|
||||||
<property name="unset_i" type="i" access="readwrite"/>
|
<property name="unset_i" type="i" access="readwrite"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user