From 52178e4d779d93d70bbd9bf6996c9e2eac65cc76 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Sat, 28 Feb 2026 11:47:14 +0100 Subject: [PATCH] add socket manager protocol --- include/labwc.h | 1 + include/protocols/xi_socket_manager_v1.h | 21 +++++ protocols/meson.build | 1 + protocols/xi-socket-manager-unstable-v1.xml | 51 +++++++++++++ src/protocols/meson.build | 1 + src/protocols/xi-socket-manager/meson.build | 3 + .../xi-socket-manager/xi_socket_manager_v1.c | 76 +++++++++++++++++++ src/server.c | 4 + 8 files changed, 158 insertions(+) create mode 100644 include/protocols/xi_socket_manager_v1.h create mode 100644 protocols/xi-socket-manager-unstable-v1.xml create mode 100644 src/protocols/xi-socket-manager/meson.build create mode 100644 src/protocols/xi-socket-manager/xi_socket_manager_v1.c diff --git a/include/labwc.h b/include/labwc.h index 88860de2..8d6ce892 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -299,6 +299,7 @@ struct server { struct wlr_tablet_manager_v2 *tablet_manager; struct wlr_security_context_manager_v1 *security_context_manager_v1; + struct xi_socket_manager_v1 *xi_socket_manager_v1; /* Set when in cycle (alt-tab) mode */ struct cycle_state cycle; diff --git a/include/protocols/xi_socket_manager_v1.h b/include/protocols/xi_socket_manager_v1.h new file mode 100644 index 00000000..e69ab5f1 --- /dev/null +++ b/include/protocols/xi_socket_manager_v1.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_PROTOCOLS_XI_SOCKET_MANAGER_H +#define LABWC_PROTOCOLS_XI_SOCKET_MANAGER_H + +#include + +struct xi_socket_manager_v1 { + struct wl_global *global; + + struct { + struct wl_signal destroy; + struct wl_signal register_socket; + } events; + + struct wl_listener display_destroy; +}; + +struct xi_socket_manager_v1 *xi_socket_manager_v1_create( + struct wl_display *display); + +#endif diff --git a/protocols/meson.build b/protocols/meson.build index 67c0d3d2..f87e0231 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -28,6 +28,7 @@ server_protocols = [ 'cosmic-workspace-unstable-v1.xml', 'wlr-layer-shell-unstable-v1.xml', 'wlr-output-power-management-unstable-v1.xml', + 'xi-socket-manager-unstable-v1.xml', ] server_protos_src = [] diff --git a/protocols/xi-socket-manager-unstable-v1.xml b/protocols/xi-socket-manager-unstable-v1.xml new file mode 100644 index 00000000..80ec9afa --- /dev/null +++ b/protocols/xi-socket-manager-unstable-v1.xml @@ -0,0 +1,51 @@ + + + + Copyright © 2026 Tobias Bengfort + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + + If a client has received a privileged socket via WAYLAND_SOCKET, it can + use this interface to register additional privileged sockets to pass to + child processes. + + + + + Destroy the manager. This doesn't destroy objects created with the + manager. + + + + + + Registers a new socket with the same permissions as the current one. + The socket must be created by the client. After registraton, it can then + be passed to a child process via WAYLAND_SOCKET. + + + + + diff --git a/src/protocols/meson.build b/src/protocols/meson.build index d9d17bf5..47eb9b0b 100644 --- a/src/protocols/meson.build +++ b/src/protocols/meson.build @@ -4,3 +4,4 @@ labwc_sources += files( subdir('cosmic_workspaces') subdir('ext-workspace') +subdir('xi-socket-manager') diff --git a/src/protocols/xi-socket-manager/meson.build b/src/protocols/xi-socket-manager/meson.build new file mode 100644 index 00000000..b271cd44 --- /dev/null +++ b/src/protocols/xi-socket-manager/meson.build @@ -0,0 +1,3 @@ +labwc_sources += files( + 'xi_socket_manager_v1.c', +) diff --git a/src/protocols/xi-socket-manager/xi_socket_manager_v1.c b/src/protocols/xi-socket-manager/xi_socket_manager_v1.c new file mode 100644 index 00000000..561441fd --- /dev/null +++ b/src/protocols/xi-socket-manager/xi_socket_manager_v1.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include "permissions.h" +#include "xi-socket-manager-unstable-v1-protocol.h" + +#define XI_SOCKET_MANAGER_V1_VERSION 1 + +static void +manager_handle_destroy(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +manager_handle_register_socket(struct wl_client *client, + struct wl_resource *manager_resource, int fd) +{ + permissions_context_clone(client, fd); +} + +static const struct xi_socket_manager_v1_interface manager_impl = { + .destroy = manager_handle_destroy, + .register_socket = manager_handle_register_socket, +}; + +static void +manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct xi_socket_manager_v1 *manager = data; + + struct wl_resource *resource = + wl_resource_create(client, &xi_socket_manager_v1_interface, version, id); + if (!resource) { + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(resource, &manager_impl, manager, NULL); +} + +static void +handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct xi_socket_manager_v1 *manager = + wl_container_of(listener, manager, display_destroy); + wl_signal_emit_mutable(&manager->events.destroy, manager); + + wl_global_destroy(manager->global); + wl_list_remove(&manager->display_destroy.link); + free(manager); +} + +struct xi_socket_manager_v1 * +xi_socket_manager_v1_create(struct wl_display *display) +{ + struct xi_socket_manager_v1 *manager = calloc(1, sizeof(*manager)); + if (!manager) { + return NULL; + } + + manager->global = wl_global_create(display, + &xi_socket_manager_v1_interface, + XI_SOCKET_MANAGER_V1_VERSION, manager, manager_bind); + if (!manager->global) { + free(manager); + return NULL; + } + + wl_signal_init(&manager->events.destroy); + wl_signal_init(&manager->events.register_socket); + + manager->display_destroy.notify = handle_display_destroy; + wl_display_add_destroy_listener(display, &manager->display_destroy); + + return manager; +} diff --git a/src/server.c b/src/server.c index 21ee513f..f34ec80e 100644 --- a/src/server.c +++ b/src/server.c @@ -68,6 +68,7 @@ #include "view.h" #include "workspaces.h" #include "xwayland.h" +#include "protocols/xi_socket_manager_v1.h" #define LAB_EXT_DATA_CONTROL_VERSION 1 #define LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION 1 @@ -287,6 +288,7 @@ allow_for_sandbox(const struct wlr_security_context_v1_state *security_state, "zwp_idle_inhibit_manager_v1", "zwp_pointer_constraints_v1", "zxdg_output_manager_v1", + "xi_socket_manager_v1", }; for (size_t i = 0; i < ARRAY_SIZE(allowed_protocols); i++) { @@ -668,6 +670,8 @@ server_init(struct server *server) LAB_EXT_DATA_CONTROL_VERSION); server->security_context_manager_v1 = wlr_security_context_manager_v1_create(server->wl_display); + server->xi_socket_manager_v1 = + xi_socket_manager_v1_create(server->wl_display); wlr_viewporter_create(server->wl_display); wlr_single_pixel_buffer_manager_v1_create(server->wl_display); wlr_fractional_scale_manager_v1_create(server->wl_display,