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
This commit is contained in:
Ferdinand Bachmann 2024-07-17 23:25:46 +02:00
parent db76fefd0c
commit 934018253c
4 changed files with 38 additions and 10 deletions

View file

@ -155,7 +155,7 @@ extern struct sway_debug debug;
extern bool allow_unsupported_gpu; 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); void server_fini(struct sway_server *server);
bool server_start(struct sway_server *server); bool server_start(struct sway_server *server);
void server_run(struct sway_server *server); void server_run(struct sway_server *server);

View file

@ -196,6 +196,8 @@ static const struct option long_options[] = {
{"verbose", no_argument, NULL, 'V'}, {"verbose", no_argument, NULL, 'V'},
{"get-socketpath", no_argument, NULL, 'p'}, {"get-socketpath", no_argument, NULL, 'p'},
{"unsupported-gpu", no_argument, NULL, 'u'}, {"unsupported-gpu", no_argument, NULL, 'u'},
{"socket", required_argument, NULL, 's'},
{"wayland-fd", required_argument, NULL, 'S'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
@ -209,12 +211,16 @@ static const char usage[] =
" -v, --version Show the version number and quit.\n" " -v, --version Show the version number and quit.\n"
" -V, --verbose Enables more verbose logging.\n" " -V, --verbose Enables more verbose logging.\n"
" --get-socketpath Gets the IPC socket path and prints it, then exits.\n" " --get-socketpath Gets the IPC socket path and prints it, then exits.\n"
" --socket <name> Sets the Wayland socket name (for Wayland socket handover)\n"
" --wayland-fd <fd> Sets the Wayland socket fd (for Wayland socket handover)\n"
"\n"; "\n";
int main(int argc, char **argv) { int main(int argc, char **argv) {
static bool verbose = false, debug = false, validate = false; static bool verbose = false, debug = false, validate = false;
char *config_path = NULL; char *config_path = NULL;
char *socket_name = NULL;
int socket_fd = -1;
int c; int c;
while (1) { while (1) {
@ -260,6 +266,13 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
break; break;
case 's': // --socket
free(socket_name);
socket_name = strdup(optarg);
break;
case 'S': // --wayland-fd
socket_fd = atoi(optarg);
break;
default: default:
fprintf(stderr, "%s", usage); fprintf(stderr, "%s", usage);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -331,7 +344,7 @@ int main(int argc, char **argv) {
sway_log(SWAY_INFO, "Starting sway version " SWAY_VERSION); sway_log(SWAY_INFO, "Starting sway version " SWAY_VERSION);
if (!server_init(&server)) { if (!server_init(&server, socket_name, socket_fd)) {
return 1; return 1;
} }

View file

@ -2,6 +2,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <fcntl.h>
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include <wlr/backend.h> #include <wlr/backend.h>
#include <wlr/backend/headless.h> #include <wlr/backend/headless.h>
@ -215,7 +216,7 @@ static void handle_renderer_lost(struct wl_listener *listener, void *data) {
wlr_renderer_destroy(old_renderer); 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"); sway_log(SWAY_DEBUG, "Initializing Wayland server");
server->wl_display = wl_display_create(); server->wl_display = wl_display_create();
server->wl_event_loop = wl_display_get_event_loop(server->wl_display); server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
@ -406,6 +407,13 @@ bool server_init(struct sway_server *server) {
wl_list_init(&server->pending_launcher_ctxs); wl_list_init(&server->pending_launcher_ctxs);
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 // Avoid using "wayland-0" as display socket
char name_candidate[16]; char name_candidate[16];
for (unsigned int i = 1; i <= 32; ++i) { for (unsigned int i = 1; i <= 32; ++i) {
@ -415,6 +423,7 @@ bool server_init(struct sway_server *server) {
break; break;
} }
} }
}
if (!server->socket) { if (!server->socket) {
sway_log(SWAY_ERROR, "Unable to open wayland socket"); sway_log(SWAY_ERROR, "Unable to open wayland socket");

View file

@ -31,6 +31,12 @@ sway - An i3-compatible Wayland compositor
*--get-socketpath* *--get-socketpath*
Gets the IPC socket path and prints it, then exits. 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 # DESCRIPTION
sway was created to fill the need of an i3-like window manager for Wayland. The sway was created to fill the need of an i3-like window manager for Wayland. The