From fd2db174c1e866e70833ec358ba6cef668441eb5 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 20 Jun 2025 16:31:16 +0200 Subject: [PATCH] pipewire: update global properties When the properties of an object change, update the properties on the global as well. There is no way to notify clients of a changed global but they are supposed to listen to the object specific events for that. The global properties are meant to be a snapshot at the time of enumerating the registry and can change later. --- src/pipewire/impl-client.c | 20 +++++++++-------- src/pipewire/impl-device.c | 34 +++++++++++++++------------- src/pipewire/impl-node.c | 46 ++++++++++++++++++++------------------ src/pipewire/impl-port.c | 45 ++++++++++++++++++++----------------- 4 files changed, 77 insertions(+), 68 deletions(-) diff --git a/src/pipewire/impl-client.c b/src/pipewire/impl-client.c index d46e07939..06234e2b7 100644 --- a/src/pipewire/impl-client.c +++ b/src/pipewire/impl-client.c @@ -27,6 +27,13 @@ struct impl { unsigned int registered:1; }; +static const char * const global_keys[] = { + PW_KEY_ACCESS, + PW_KEY_CLIENT_ACCESS, + PW_KEY_APP_NAME, + NULL +}; + #define pw_client_resource(r,m,v,...) pw_resource_call(r,struct pw_client_events,m,v,__VA_ARGS__) #define pw_client_resource_info(r,...) pw_client_resource(r,info,0,__VA_ARGS__) #define pw_client_resource_permissions(r,...) pw_client_resource(r,permissions,0,__VA_ARGS__) @@ -220,9 +227,11 @@ static int update_properties(struct pw_impl_client *client, const struct spa_dic pw_impl_client_emit_info_changed(client, &client->info); - if (client->global) + if (client->global) { + pw_global_update_keys(client->global, client->info.props, global_keys); spa_list_for_each(resource, &client->global->resource_list, link) pw_client_resource_info(resource, &client->info); + } client->info.change_mask = 0; @@ -238,13 +247,6 @@ static void update_busy(struct pw_impl_client *client) static int finish_register(struct pw_impl_client *client) { - static const char * const keys[] = { - PW_KEY_ACCESS, - PW_KEY_CLIENT_ACCESS, - PW_KEY_APP_NAME, - NULL - }; - struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this); struct pw_impl_client *current; @@ -260,7 +262,7 @@ static int finish_register(struct pw_impl_client *client) update_busy(client); - pw_global_update_keys(client->global, client->info.props, keys); + pw_global_update_keys(client->global, client->info.props, global_keys); pw_global_register(client->global); #ifdef OLD_MEDIA_SESSION_WORKAROUND diff --git a/src/pipewire/impl-device.c b/src/pipewire/impl-device.c index 71e2e266b..73af60cdf 100644 --- a/src/pipewire/impl-device.c +++ b/src/pipewire/impl-device.c @@ -27,6 +27,19 @@ struct impl { unsigned int cache_params:1; }; +static const char * const global_keys[] = { + PW_KEY_OBJECT_PATH, + PW_KEY_MODULE_ID, + PW_KEY_FACTORY_ID, + PW_KEY_CLIENT_ID, + PW_KEY_DEVICE_API, + PW_KEY_DEVICE_DESCRIPTION, + PW_KEY_DEVICE_NAME, + PW_KEY_DEVICE_NICK, + PW_KEY_MEDIA_CLASS, + NULL +}; + #define pw_device_resource(r,m,v,...) pw_resource_call(r,struct pw_device_events,m,v,__VA_ARGS__) #define pw_device_resource_info(r,...) pw_device_resource(r,info,0,__VA_ARGS__) #define pw_device_resource_param(r,...) pw_device_resource(r,param,0,__VA_ARGS__) @@ -581,19 +594,6 @@ SPA_EXPORT int pw_impl_device_register(struct pw_impl_device *device, struct pw_properties *properties) { - static const char * const keys[] = { - PW_KEY_OBJECT_PATH, - PW_KEY_MODULE_ID, - PW_KEY_FACTORY_ID, - PW_KEY_CLIENT_ID, - PW_KEY_DEVICE_API, - PW_KEY_DEVICE_DESCRIPTION, - PW_KEY_DEVICE_NAME, - PW_KEY_DEVICE_NICK, - PW_KEY_MEDIA_CLASS, - NULL - }; - struct pw_context *context = device->context; struct object_data *od; @@ -619,7 +619,7 @@ int pw_impl_device_register(struct pw_impl_device *device, pw_global_get_serial(device->global)); device->info.props = &device->properties->dict; - pw_global_update_keys(device->global, device->info.props, keys); + pw_global_update_keys(device->global, device->info.props, global_keys); pw_impl_device_emit_initialized(device); @@ -668,10 +668,12 @@ static void emit_info_changed(struct pw_impl_device *device) pw_impl_device_emit_info_changed(device, &device->info); - if (device->global) + if (device->global) { + if (device->info.change_mask & PW_DEVICE_CHANGE_MASK_PROPS) + pw_global_update_keys(device->global, device->info.props, global_keys); spa_list_for_each(resource, &device->global->resource_list, link) pw_device_resource_info(resource, &device->info); - + } device->info.change_mask = 0; } diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index b30b99f8b..822c86b21 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -55,6 +55,27 @@ struct impl { char *sync_group; }; +static const char * const global_keys[] = { + PW_KEY_OBJECT_PATH, + PW_KEY_MODULE_ID, + PW_KEY_FACTORY_ID, + PW_KEY_CLIENT_ID, + PW_KEY_CLIENT_API, + PW_KEY_DEVICE_ID, + PW_KEY_PRIORITY_SESSION, + PW_KEY_PRIORITY_DRIVER, + PW_KEY_APP_NAME, + PW_KEY_NODE_DESCRIPTION, + PW_KEY_NODE_NAME, + PW_KEY_NODE_NICK, + PW_KEY_NODE_SESSION, + PW_KEY_MEDIA_CLASS, + PW_KEY_MEDIA_TYPE, + PW_KEY_MEDIA_CATEGORY, + PW_KEY_MEDIA_ROLE, + NULL +}; + #define pw_node_resource(r,m,v,...) pw_resource_call(r,struct pw_node_events,m,v,__VA_ARGS__) #define pw_node_resource_info(r,...) pw_node_resource(r,info,0,__VA_ARGS__) #define pw_node_resource_param(r,...) pw_node_resource(r,param,0,__VA_ARGS__) @@ -357,6 +378,8 @@ static void emit_info_changed(struct pw_impl_node *node, bool flags_changed) if (node->global && node->info.change_mask != 0) { struct pw_resource *resource; + if (node->info.change_mask & PW_NODE_CHANGE_MASK_PROPS) + pw_global_update_keys(node->global, node->info.props, global_keys); spa_list_for_each(resource, &node->global->resource_list, link) pw_node_resource_info(resource, &node->info); } @@ -929,27 +952,6 @@ SPA_EXPORT int pw_impl_node_register(struct pw_impl_node *this, struct pw_properties *properties) { - static const char * const keys[] = { - PW_KEY_OBJECT_PATH, - PW_KEY_MODULE_ID, - PW_KEY_FACTORY_ID, - PW_KEY_CLIENT_ID, - PW_KEY_CLIENT_API, - PW_KEY_DEVICE_ID, - PW_KEY_PRIORITY_SESSION, - PW_KEY_PRIORITY_DRIVER, - PW_KEY_APP_NAME, - PW_KEY_NODE_DESCRIPTION, - PW_KEY_NODE_NAME, - PW_KEY_NODE_NICK, - PW_KEY_NODE_SESSION, - PW_KEY_MEDIA_CLASS, - PW_KEY_MEDIA_TYPE, - PW_KEY_MEDIA_CATEGORY, - PW_KEY_MEDIA_ROLE, - NULL - }; - struct pw_context *context = this->context; struct pw_impl_port *port; @@ -985,7 +987,7 @@ int pw_impl_node_register(struct pw_impl_node *this, pw_global_get_serial(this->global)); this->info.props = &this->properties->dict; - pw_global_update_keys(this->global, &this->properties->dict, keys); + pw_global_update_keys(this->global, &this->properties->dict, global_keys); pw_impl_node_initialized(this); diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index 0bcff9f4c..f5fb70997 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -42,6 +42,25 @@ struct impl { unsigned int cache_params:1; }; +static const char * const global_keys[] = { + PW_KEY_OBJECT_PATH, + PW_KEY_FORMAT_DSP, + PW_KEY_NODE_ID, + PW_KEY_AUDIO_CHANNEL, + PW_KEY_PORT_ID, + PW_KEY_PORT_NAME, + PW_KEY_PORT_DIRECTION, + PW_KEY_PORT_MONITOR, + PW_KEY_PORT_PHYSICAL, + PW_KEY_PORT_TERMINAL, + PW_KEY_PORT_CONTROL, + PW_KEY_PORT_ALIAS, + PW_KEY_PORT_EXTRA, + PW_KEY_PORT_IGNORE_LATENCY, + PW_KEY_PORT_GROUP, + NULL +}; + #define pw_port_resource(r,m,v,...) pw_resource_call(r,struct pw_port_events,m,v,__VA_ARGS__) #define pw_port_resource_info(r,...) pw_port_resource(r,info,0,__VA_ARGS__) #define pw_port_resource_param(r,...) pw_port_resource(r,param,0,__VA_ARGS__) @@ -70,9 +89,12 @@ static void emit_info_changed(struct pw_impl_port *port) if (port->node) pw_impl_node_emit_port_info_changed(port->node, port, &port->info); - if (port->global) + if (port->global) { + if (port->info.change_mask & PW_PORT_CHANGE_MASK_PROPS) + pw_global_update_keys(port->global, port->info.props, global_keys); spa_list_for_each(resource, &port->global->resource_list, link) pw_port_resource_info(resource, &port->info); + } port->info.change_mask = 0; } @@ -1115,25 +1137,6 @@ static const struct pw_global_events global_events = { int pw_impl_port_register(struct pw_impl_port *port, struct pw_properties *properties) { - static const char * const keys[] = { - PW_KEY_OBJECT_PATH, - PW_KEY_FORMAT_DSP, - PW_KEY_NODE_ID, - PW_KEY_AUDIO_CHANNEL, - PW_KEY_PORT_ID, - PW_KEY_PORT_NAME, - PW_KEY_PORT_DIRECTION, - PW_KEY_PORT_MONITOR, - PW_KEY_PORT_PHYSICAL, - PW_KEY_PORT_TERMINAL, - PW_KEY_PORT_CONTROL, - PW_KEY_PORT_ALIAS, - PW_KEY_PORT_EXTRA, - PW_KEY_PORT_IGNORE_LATENCY, - PW_KEY_PORT_GROUP, - NULL - }; - struct pw_impl_node *node = port->node; if (node == NULL || node->global == NULL) @@ -1158,7 +1161,7 @@ int pw_impl_port_register(struct pw_impl_port *port, pw_global_get_serial(port->global)); port->info.props = &port->properties->dict; - pw_global_update_keys(port->global, &port->properties->dict, keys); + pw_global_update_keys(port->global, &port->properties->dict, global_keys); pw_impl_port_emit_initialized(port);