add socket manager protocol

This commit is contained in:
Tobias Bengfort 2026-02-28 11:47:14 +01:00
parent 178803b34e
commit 52178e4d77
8 changed files with 158 additions and 0 deletions

View file

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

View file

@ -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 <wayland-server-core.h>
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

View file

@ -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 = []

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="xi_socket_manager_unstable_v1">
<copyright>
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.
</copyright>
<interface name="xi_socket_manager_v1" version="1">
<description summary="register privileged sockets">
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.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the manager object">
Destroy the manager. This doesn't destroy objects created with the
manager.
</description>
</request>
<request name="register_socket">
<description summary="register a socket with the same permissions as the current one">
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.
</description>
<arg name="fd" type="fd"/>
</request>
</interface>
</protocol>

View file

@ -4,3 +4,4 @@ labwc_sources += files(
subdir('cosmic_workspaces')
subdir('ext-workspace')
subdir('xi-socket-manager')

View file

@ -0,0 +1,3 @@
labwc_sources += files(
'xi_socket_manager_v1.c',
)

View file

@ -0,0 +1,76 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <stdlib.h>
#include <protocols/xi_socket_manager_v1.h>
#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;
}

View file

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