git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit672ffa8a58f689bc8dfc05192d32879a01e6741c
parent58db873bae
authorKirill Primak <[email protected]>
date2026-04-25 00:51
river: add xdg-foreign-v2 support

 build.zig        | 5 ++++-
 river/Server.zig | 8 ++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/build.zig b/build.zig
index 97392e1..39e179a 100644
--- a/build.zig
+++ b/build.zig
@@ -85,6 +85,7 @@ pub fn build(b: *Build) !void {
     scanner.addSystemProtocol("unstable/pointer-constraints/pointer-constraints-unstable-v1.xml");
     scanner.addSystemProtocol("unstable/pointer-gestures/pointer-gestures-unstable-v1.xml");
     scanner.addSystemProtocol("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml");
+    scanner.addSystemProtocol("unstable/xdg-foreign/xdg-foreign-unstable-v2.xml");
 
     scanner.addCustomProtocol(b.path("protocol/river-window-management-v1.xml"));
     scanner.addCustomProtocol(b.path("protocol/river-xkb-bindings-v1.xml"));
@@ -100,7 +101,7 @@ pub fn build(b: *Build) !void {
     // Some of these versions may be out of date with what wlroots implements.
     // This is not a problem in practice though as long as river successfully compiles.
     // These versions control Zig code generation and have no effect on anything internal
-    // to wlroots. Therefore, the only thnig that can happen due to a version being too
+    // to wlroots. Therefore, the only thing that can happen due to a version being too
     // old is that river fails to compile.
     scanner.generate("wl_compositor", 4);
     scanner.generate("wl_subcompositor", 1);
@@ -114,6 +115,8 @@ pub fn build(b: *Build) !void {
     scanner.generate("zwp_pointer_constraints_v1", 1);
     scanner.generate("zwp_tablet_manager_v2", 1);
     scanner.generate("zxdg_decoration_manager_v1", 1);
+    scanner.generate("zxdg_importer_v2", 1);
+    scanner.generate("zxdg_exporter_v2", 1);
     scanner.generate("ext_session_lock_manager_v1", 1);
     scanner.generate("wp_cursor_shape_manager_v1", 1);
     scanner.generate("wp_tearing_control_manager_v1", 1);
diff --git a/river/Server.zig b/river/Server.zig
index 9fb6846..7f4ccb0 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -71,6 +71,8 @@ cursor_shape_manager: *wlr.CursorShapeManagerV1,
 xdg_shell: *wlr.XdgShell,
 xdg_decoration_manager: *wlr.XdgDecorationManagerV1,
 xdg_activation: *wlr.XdgActivationV1,
+xdg_foreign_registry: *wlr.XdgForeignRegistry,
+xdg_foreign_v2: *wlr.XdgForeignV2,
 
 data_device_manager: *wlr.DataDeviceManager,
 primary_selection_manager: *wlr.PrimarySelectionDeviceManagerV1,
@@ -125,6 +127,8 @@ pub fn init(server: *Server, runtime_xwayland: bool) !void {
 
     const compositor = try wlr.Compositor.create(wl_server, 6, renderer);
 
+    const xdg_foreign_registry = try wlr.XdgForeignRegistry.create(wl_server);
+
     server.* = .{
         .wl_server = wl_server,
         .sigint_source = try loop.addSignal(*wl.Server, @intFromEnum(posix.SIG.INT), terminate, wl_server),
@@ -154,6 +158,8 @@ pub fn init(server: *Server, runtime_xwayland: bool) !void {
         .xdg_shell = try wlr.XdgShell.create(wl_server, 5),
         .xdg_decoration_manager = try wlr.XdgDecorationManagerV1.create(wl_server),
         .xdg_activation = try wlr.XdgActivationV1.create(wl_server),
+        .xdg_foreign_registry = xdg_foreign_registry,
+        .xdg_foreign_v2 = try wlr.XdgForeignV2.create(wl_server, xdg_foreign_registry),
 
         .data_device_manager = try wlr.DataDeviceManager.create(wl_server),
         .primary_selection_manager = try wlr.PrimarySelectionDeviceManagerV1.create(wl_server),
@@ -343,6 +349,8 @@ fn allowlist(server: *Server, global: *const wl.Global) bool {
         global == server.xdg_shell.global or
         global == server.xdg_decoration_manager.global or
         global == server.xdg_activation.global or
+        global == server.xdg_foreign_v2.exporter.global or
+        global == server.xdg_foreign_v2.importer.global or
         global == server.data_device_manager.global or
         global == server.primary_selection_manager.global or
         global == server.tearing_control_manager.global or