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.
This commit is contained in:
Wim Taymans 2025-06-20 16:31:16 +02:00
parent 7fd05e7eaa
commit fd2db174c1
4 changed files with 77 additions and 68 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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);