From 9c2f18905b367a18307d20154269ff43bb029d84 Mon Sep 17 00:00:00 2001 From: Ferdinand Bachmann Date: Wed, 17 Jul 2024 23:25:46 +0200 Subject: [PATCH] sway/server: implement wayland socket handover This commit implements the compositor side of the Wayland socket handover protocol as described in the [KDE Wiki]. The CLI options are chosen so that they are compatible with Kwin. [KDE Wiki]: https://invent.kde.org/plasma/kwin/-/wikis/Restarting --- include/sway/server.h | 2 +- sway/main.c | 15 ++++++++++++++- sway/server.c | 25 +++++++++++++++++-------- sway/sway.1.scd | 6 ++++++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/include/sway/server.h b/include/sway/server.h index ccf4a9cc2..e3771d326 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -155,7 +155,7 @@ extern struct sway_debug debug; extern bool allow_unsupported_gpu; -bool server_init(struct sway_server *server); +bool server_init(struct sway_server *server, const char * socket_name, int socket_fd); void server_fini(struct sway_server *server); bool server_start(struct sway_server *server); void server_run(struct sway_server *server); diff --git a/sway/main.c b/sway/main.c index 1c4939aa0..f9fb04805 100644 --- a/sway/main.c +++ b/sway/main.c @@ -196,6 +196,8 @@ static const struct option long_options[] = { {"verbose", no_argument, NULL, 'V'}, {"get-socketpath", no_argument, NULL, 'p'}, {"unsupported-gpu", no_argument, NULL, 'u'}, + {"socket", required_argument, NULL, 's'}, + {"wayland-fd", required_argument, NULL, 'S'}, {0, 0, 0, 0} }; @@ -209,12 +211,16 @@ static const char usage[] = " -v, --version Show the version number and quit.\n" " -V, --verbose Enables more verbose logging.\n" " --get-socketpath Gets the IPC socket path and prints it, then exits.\n" + " --socket Sets the Wayland socket name (for Wayland socket handover)\n" + " --wayland-fd Sets the Wayland socket fd (for Wayland socket handover)\n" "\n"; int main(int argc, char **argv) { static bool verbose = false, debug = false, validate = false; char *config_path = NULL; + char *socket_name = NULL; + int socket_fd = -1; int c; while (1) { @@ -260,6 +266,13 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } break; + case 's': // --socket + free(socket_name); + socket_name = strdup(optarg); + break; + case 'S': // --wayland-fd + socket_fd = atoi(optarg); + break; default: fprintf(stderr, "%s", usage); exit(EXIT_FAILURE); @@ -331,7 +344,7 @@ int main(int argc, char **argv) { sway_log(SWAY_INFO, "Starting sway version " SWAY_VERSION); - if (!server_init(&server)) { + if (!server_init(&server, socket_name, socket_fd)) { return 1; } diff --git a/sway/server.c b/sway/server.c index 30896baf6..858734098 100644 --- a/sway/server.c +++ b/sway/server.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -214,7 +215,7 @@ static void handle_renderer_lost(struct wl_listener *listener, void *data) { wlr_renderer_destroy(old_renderer); } -bool server_init(struct sway_server *server) { +bool server_init(struct sway_server *server, const char * socket_name, int socket_fd) { sway_log(SWAY_DEBUG, "Initializing Wayland server"); server->wl_display = wl_display_create(); server->wl_event_loop = wl_display_get_event_loop(server->wl_display); @@ -403,13 +404,21 @@ bool server_init(struct sway_server *server) { wl_list_init(&server->pending_launcher_ctxs); - // Avoid using "wayland-0" as display socket - char name_candidate[16]; - for (unsigned int i = 1; i <= 32; ++i) { - snprintf(name_candidate, sizeof(name_candidate), "wayland-%u", i); - if (wl_display_add_socket(server->wl_display, name_candidate) >= 0) { - server->socket = strdup(name_candidate); - break; + if (socket_name != NULL && socket_fd != -1) { + // Add the passed socket + fcntl(socket_fd, F_SETFD, FD_CLOEXEC); + if (wl_display_add_socket_fd(server->wl_display, socket_fd) >= 0) { + server->socket = strdup(socket_name); + } + } else { + // Avoid using "wayland-0" as display socket + char name_candidate[16]; + for (unsigned int i = 1; i <= 32; ++i) { + snprintf(name_candidate, sizeof(name_candidate), "wayland-%u", i); + if (wl_display_add_socket(server->wl_display, name_candidate) >= 0) { + server->socket = strdup(name_candidate); + break; + } } } diff --git a/sway/sway.1.scd b/sway/sway.1.scd index 75df5b013..86753908d 100644 --- a/sway/sway.1.scd +++ b/sway/sway.1.scd @@ -31,6 +31,12 @@ sway - An i3-compatible Wayland compositor *--get-socketpath* Gets the IPC socket path and prints it, then exits. +*--socket NAME* + Sets the Wayland socket name (for Wayland socket handover) + +*--wayland-fd FD* + Sets the Wayland socket file descriptor (for Wayland socket handover) + # DESCRIPTION sway was created to fill the need of an i3-like window manager for Wayland. The