From 92cd2c7ce0ec16eb96ba470a53c78b3addb3282f Mon Sep 17 00:00:00 2001 From: Packit Bot Date: May 06 2021 14:18:57 +0000 Subject: Apply patch 0001-gdbus-codegen-honor-Property.EmitsChangedSignal-anno.patch patch_name: 0001-gdbus-codegen-honor-Property.EmitsChangedSignal-anno.patch present_in_specfile: true location_in_specfile: 10 --- diff --git a/gio/gdbus-2.0/codegen/codegen.py b/gio/gdbus-2.0/codegen/codegen.py index f6892af..442bd3f 100644 --- a/gio/gdbus-2.0/codegen/codegen.py +++ b/gio/gdbus-2.0/codegen/codegen.py @@ -665,7 +665,8 @@ class CodeGenerator: '{\n' ' GDBusPropertyInfo parent_struct;\n' ' const gchar *hyphen_name;\n' - ' gboolean use_gvariant;\n' + ' guint use_gvariant : 1;\n' + ' guint emits_changed_signal : 1;\n' '} _ExtendedGDBusPropertyInfo;\n' '\n') @@ -960,9 +961,13 @@ class CodeGenerator: ' "%s",\n' %(p.name_hyphen)) if not utils.lookup_annotation(p.annotations, 'org.gtk.GDBus.C.ForceGVariant'): - self.outfile.write(' FALSE\n') + self.outfile.write(' FALSE,\n') else: + self.outfile.write(' TRUE,\n') + if p.emits_changed_signal: self.outfile.write(' TRUE\n') + else: + self.outfile.write(' FALSE\n') self.outfile.write('};\n' '\n') @@ -2595,14 +2600,17 @@ class CodeGenerator: ' const GValue *value,\n' ' GParamSpec *pspec)\n' '{\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' + ' info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n' ' g_mutex_lock (&skeleton->priv->lock);\n' ' g_object_freeze_notify (object);\n' ' if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))\n' ' {\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' + ' if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL &&\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_object_notify_by_pspec (object, pspec);\n' ' }\n' diff --git a/gio/gdbus-2.0/codegen/dbustypes.py b/gio/gdbus-2.0/codegen/dbustypes.py index bfc69f5..359880f 100644 --- a/gio/gdbus-2.0/codegen/dbustypes.py +++ b/gio/gdbus-2.0/codegen/dbustypes.py @@ -327,6 +327,7 @@ class Property: self.doc_string = '' self.since = '' self.deprecated = False + self.emits_changed_signal = True def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface): if len(self.doc_string) == 0: @@ -356,6 +357,12 @@ class Property: if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true': self.deprecated = True + # 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: def __init__(self, name): self.name = name diff --git a/gio/tests/gdbus-test-codegen.c b/gio/tests/gdbus-test-codegen.c index 1c4e83c..c906d05 100644 --- a/gio/tests/gdbus-test-codegen.c +++ b/gio/tests/gdbus-test-codegen.c @@ -1767,9 +1767,9 @@ on_object_proxy_removed (GDBusObjectManagerClient *manager, } static void -property_d_changed (GObject *object, - GParamSpec *pspec, - gpointer user_data) +property_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) { gboolean *changed = user_data; @@ -1782,6 +1782,8 @@ om_check_property_and_signal_emission (GMainLoop *loop, FooiGenBar *proxy) { gboolean d_changed = FALSE; + gboolean quiet_changed = FALSE; + gboolean quiet_too_changed = FALSE; guint handler; /* First PropertiesChanged */ @@ -1803,13 +1805,35 @@ om_check_property_and_signal_emission (GMainLoop *loop, * notifications are serialized. */ 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_i (skeleton, 2); _g_assert_property_notify (proxy, "i"); g_assert (d_changed == FALSE); 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 */ foo_igen_bar_emit_another_signal (skeleton, "word"); _g_assert_signal_received (proxy, "another-signal"); @@ -2151,7 +2175,7 @@ check_object_manager (void) * that ObjectManager.GetManagedObjects() works */ om_check_get_all (c, loop, - "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': , 'b': , 'n': , 'q': , 'i': <0>, 'u': , 'x': , 't': , 'd': <0.0>, 's': <''>, 'o': , 'g': , 'ay': , 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': , 'unset_g': , 'unset_ay': , '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': , 'b': , 'n': , 'q': , 'i': <0>, 'u': , 'x': , 't': , 'd': <0.0>, 's': <''>, 'o': , 'g': , 'ay': , 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'quiet': <''>, 'quiet_too': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': , 'unset_g': , 'unset_ay': , '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 * then set the connection back.. and then check things still work @@ -2163,7 +2187,7 @@ check_object_manager (void) g_dbus_object_manager_server_set_connection (manager, c); om_check_get_all (c, loop, - "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': , 'b': , 'n': , 'q': , 'i': <0>, 'u': , 'x': , 't': , 'd': <0.0>, 's': <''>, 'o': , 'g': , 'ay': , 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': , 'unset_g': , 'unset_ay': , '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': , 'b': , 'n': , 'q': , 'i': <0>, 'u': , 'x': , 't': , 'd': <0.0>, 's': <''>, 'o': , 'g': , 'ay': , 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'quiet': <''>, 'quiet_too': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': , 'unset_g': , 'unset_ay': , '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 * that they are of the right GType cf. what was requested via diff --git a/gio/tests/test-codegen.xml b/gio/tests/test-codegen.xml index 885a21f..39d8769 100644 --- a/gio/tests/test-codegen.xml +++ b/gio/tests/test-codegen.xml @@ -106,6 +106,12 @@ + + + + + +