From 516f86c32984be88bb91f1cbcc4ceca953468492 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 29 Jan 2025 12:59:45 +0100 Subject: [PATCH] protocol: improve manager socket handling Some of the tools would like to connect to the manager socket first because they are manager style apps. They however completely ignore any of the configured sockets in the config and assume everything is the default. Fix this by adding a remote.intention = "manager" to those apps. This instructs the protocol to first try to connect to a socket with the -manager extension before attempting the regular configured socket. This makes things work when you have sockets configured in /tmp and have remote.name = /tmp/pipewire-0 in the config. --- .../module-protocol-native/local-socket.c | 16 +++++++++++++--- src/pipewire/keys.h | 6 ++++-- src/tools/pw-container.c | 4 ++-- src/tools/pw-dump.c | 4 ++-- src/tools/pw-mon.c | 4 ++-- src/tools/pw-top.c | 4 ++-- 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/modules/module-protocol-native/local-socket.c b/src/modules/module-protocol-native/local-socket.c index 7064a30de..ebe10ff1f 100644 --- a/src/modules/module-protocol-native/local-socket.c +++ b/src/modules/module-protocol-native/local-socket.c @@ -122,13 +122,20 @@ error: } static int try_connect_name(struct pw_protocol_client *client, - const char *name, + const char *name, bool manager, void (*done_callback) (void *data, int res), void *data) { const char *runtime_dir; + char path[PATH_MAX]; int res; + if (manager && !spa_strendswith(name, "-manager")) { + snprintf(path, sizeof(path), "%s-manager", name); + res = try_connect_name(client, path, false, done_callback, data); + if (res >= 0) + return res; + } if (name[0] == '/') { return try_connect(client, NULL, name, done_callback, data); } else { @@ -155,16 +162,19 @@ int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, struct spa_json it[1]; char path[PATH_MAX]; int res = -EINVAL; + bool manager; + + manager = props && spa_streq(spa_dict_lookup(props, PW_KEY_REMOTE_INTENTION), "manager"); name = get_remote(props); if (name == NULL) return -EINVAL; if (spa_json_begin_array(&it[0], name, strlen(name)) <= 0) - return try_connect_name(client, name, done_callback, data); + return try_connect_name(client, name, manager, done_callback, data); while (spa_json_get_string(&it[0], path, sizeof(path)) > 0) { - res = try_connect_name(client, path, done_callback, data); + res = try_connect_name(client, path, manager, done_callback, data); if (res < 0) continue; break; diff --git a/src/pipewire/keys.h b/src/pipewire/keys.h index 600b2fa61..de4a9d408 100644 --- a/src/pipewire/keys.h +++ b/src/pipewire/keys.h @@ -104,9 +104,11 @@ extern "C" { * default pipewire-0, overwritten by * env(PIPEWIRE_REMOTE). May also be * a SPA-JSON array of sockets, to be tried - * in order. */ + * in order. The "internal" remote name and + * "generic" intention connects to the local + * PipeWire instance. */ #define PW_KEY_REMOTE_INTENTION "remote.intention" /**< The intention of the remote connection, - * "generic", "screencast" */ + * "generic", "screencast", "manager" */ /** application keys */ #define PW_KEY_APP_NAME "application.name" /**< application name. Ex: "Totem Music Player" */ diff --git a/src/tools/pw-container.c b/src/tools/pw-container.c index 606f43370..02b7c8815 100644 --- a/src/tools/pw-container.c +++ b/src/tools/pw-container.c @@ -209,8 +209,8 @@ int main(int argc, char *argv[]) data.core = pw_context_connect(data.context, pw_properties_new( - PW_KEY_REMOTE_NAME, opt_remote ? opt_remote : - ("[" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE "]"), + PW_KEY_REMOTE_INTENTION, "manager", + PW_KEY_REMOTE_NAME, opt_remote, NULL), 0); if (data.core == NULL) { diff --git a/src/tools/pw-dump.c b/src/tools/pw-dump.c index f3fd86540..179e0c673 100644 --- a/src/tools/pw-dump.c +++ b/src/tools/pw-dump.c @@ -1604,8 +1604,8 @@ int main(int argc, char *argv[]) data.core = pw_context_connect(data.context, pw_properties_new( - PW_KEY_REMOTE_NAME, opt_remote ? opt_remote : - ("[" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE "]"), + PW_KEY_REMOTE_INTENTION, "manager", + PW_KEY_REMOTE_NAME, opt_remote, NULL), 0); if (data.core == NULL) { diff --git a/src/tools/pw-mon.c b/src/tools/pw-mon.c index 381778b3f..e66de979c 100644 --- a/src/tools/pw-mon.c +++ b/src/tools/pw-mon.c @@ -886,8 +886,8 @@ int main(int argc, char *argv[]) data.core = pw_context_connect(data.context, pw_properties_new( - PW_KEY_REMOTE_NAME, opt_remote ? opt_remote : - ("[" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE "]"), + PW_KEY_REMOTE_INTENTION, "manager", + PW_KEY_REMOTE_NAME, opt_remote, NULL), 0); if (data.core == NULL) { diff --git a/src/tools/pw-top.c b/src/tools/pw-top.c index 3f9a71729..fc4da9239 100644 --- a/src/tools/pw-top.c +++ b/src/tools/pw-top.c @@ -870,8 +870,8 @@ int main(int argc, char *argv[]) data.core = pw_context_connect(data.context, pw_properties_new( - PW_KEY_REMOTE_NAME, opt_remote ? opt_remote : - ("[" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE "]"), + PW_KEY_REMOTE_INTENTION, "manager", + PW_KEY_REMOTE_NAME, opt_remote, NULL), 0); if (data.core == NULL) {