diff --git a/src/modules/module-protocol-pulse/manager.c b/src/modules/module-protocol-pulse/manager.c index 00d6cf7ad..940e969ad 100644 --- a/src/modules/module-protocol-pulse/manager.c +++ b/src/modules/module-protocol-pulse/manager.c @@ -675,6 +675,7 @@ int pw_manager_set_metadata(struct pw_manager *manager, struct object *s; va_list args; char buf[1024]; + char *value; if ((s = find_object(m, subject)) == NULL) return -ENOENT; @@ -686,12 +687,18 @@ int pw_manager_set_metadata(struct pw_manager *manager, if (!SPA_FLAG_IS_SET(metadata->permissions, PW_PERM_W|PW_PERM_X)) return -EACCES; - va_start(args, format); - vsnprintf(buf, sizeof(buf)-1, format, args); - va_end(args); + if (type != NULL) { + va_start(args, format); + vsnprintf(buf, sizeof(buf)-1, format, args); + va_end(args); + value = buf; + } else { + spa_assert(format == NULL); + value = NULL; + } pw_metadata_set_property(metadata->proxy, - subject, key, type, buf); + subject, key, type, value); return 0; } diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index 38830e2d8..a56d60298 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -4340,7 +4340,7 @@ static int do_move_stream(struct client *client, uint32_t command, uint32_t tag, { struct impl *impl = client->impl; struct pw_manager *manager = client->manager; - struct pw_manager_object *o, *dev; + struct pw_manager_object *o, *dev, *dev_default; uint32_t id, id_device; const char *name_device; struct selector sel; @@ -4378,6 +4378,24 @@ static int do_move_stream(struct client *client, uint32_t command, uint32_t tag, SPA_TYPE_INFO_BASE"Id", "%d", dev->id)) < 0) return res; + dev_default = find_device(client, SPA_ID_INVALID, NULL, sink); + if (dev == dev_default) { + /* + * When moving streams to a node that is equal to the default, + * Pulseaudio understands this to mean '... and unset preferred sink/source', + * forgetting target.node. Follow that behavior here. + * + * XXX: We set target.node key above regardless, to make policy-node + * XXX: to always see the unset event. The metadata is currently not + * XXX: always set when the node has explicit target. + */ + if ((res = pw_manager_set_metadata(manager, client->metadata_default, + o->id, + METADATA_TARGET_NODE, + NULL, NULL)) < 0) + return res; + } + return reply_simple_ack(client, tag); }