From 08a68e9e0f85213259ef259c77f9110a8fb2d4c0 Mon Sep 17 00:00:00 2001
From: Sivecano <sivecano@gmail.com>
Date: Mon, 2 Nov 2026 17:13:36 +0100
Subject: [PATCH] wayland wl_seat: add an environment variable GLFW_SEAT_NAME
 to select the wayland seat used. we still only use a single seat but at least
 now we can choose which one

---
 src/wl_init.c     | 25 +++++++++++++++++--------
 src/wl_platform.h |  1 +
 src/wl_window.c   | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/src/wl_init.c b/src/wl_init.c
index 3aff476d..4c9f1ec1 100644
--- a/src/wl_init.c
+++ b/src/wl_init.c
@@ -131,13 +131,18 @@ static void registryHandleGlobal(void* userData,
     }
     else if (strcmp(interface, "wl_seat") == 0)
     {
-        if (!_glfw.wl.seat)
-        {
-            _glfw.wl.seat =
-                wl_registry_bind(registry, name, &wl_seat_interface,
+        unsigned int len = 0;
+        if (_glfw.wl.seats != NULL) while (*(_glfw.wl.seats + len) != NULL) len++;
+
+        len++;
+
+        _glfw.wl.seats = reallocarray(_glfw.wl.seats, len + 1, sizeof(struct wl_seat*));
+        _glfw.wl.seats[len] = NULL;
+        _glfw.wl.seats[len - 1] = wl_registry_bind(registry, name, &wl_seat_interface,
                                  _glfw_min(4, version));
-            _glfwAddSeatListenerWayland(_glfw.wl.seat);
-        }
+        _glfwAddSeatListenerWayland(_glfw.wl.seats[len - 1]);
+
+        if (!_glfw.wl.seat) _glfw.wl.seat = _glfw.wl.seats[len - 1];
     }
     else if (strcmp(interface, "wl_data_device_manager") == 0)
     {
@@ -971,8 +976,12 @@ void _glfwTerminateWayland(void)
         wl_pointer_destroy(_glfw.wl.pointer);
     if (_glfw.wl.keyboard)
         wl_keyboard_destroy(_glfw.wl.keyboard);
-    if (_glfw.wl.seat)
-        wl_seat_destroy(_glfw.wl.seat);
+    if (_glfw.wl.seats) {
+        for (struct wl_seat** seat = _glfw.wl.seats; *seat; seat++) {
+            wl_seat_destroy(*seat);
+        }
+        free(_glfw.wl.seats);
+    }
     if (_glfw.wl.relativePointerManager)
         zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager);
     if (_glfw.wl.pointerConstraints)
diff --git a/src/wl_platform.h b/src/wl_platform.h
index 149cd241..14ada0a9 100644
--- a/src/wl_platform.h
+++ b/src/wl_platform.h
@@ -425,6 +425,7 @@ typedef struct _GLFWlibraryWayland
     struct wl_subcompositor*    subcompositor;
     struct wl_shm*              shm;
     struct wl_seat*             seat;
+    struct wl_seat**            seats;
     struct wl_pointer*          pointer;
     struct wl_keyboard*         keyboard;
     struct wl_data_device_manager*          dataDeviceManager;
diff --git a/src/wl_window.c b/src/wl_window.c
index 5b491ffb..4e30c863 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -1881,6 +1881,8 @@ static void seatHandleCapabilities(void* userData,
                                    struct wl_seat* seat,
                                    enum wl_seat_capability caps)
 {
+    if (seat != _glfw.wl.seat) return;
+
     if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer)
     {
         _glfw.wl.pointer = wl_seat_get_pointer(seat);
@@ -1908,6 +1910,38 @@ static void seatHandleName(void* userData,
                            struct wl_seat* seat,
                            const char* name)
 {
+
+    const char* chosen_name = getenv("GLFW_SEAT_NAME");
+    if (!chosen_name) return;
+    if (strcmp(chosen_name, name) != 0) return;
+
+    _glfw.wl.seat = seat;
+
+    if (_glfw.wl.keyboard){
+        if (wl_keyboard_get_version(_glfw.wl.keyboard) >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
+            wl_keyboard_release(_glfw.wl.keyboard);
+        else
+            wl_keyboard_destroy(_glfw.wl.keyboard);
+
+        _glfw.wl.keyboard = NULL;
+    }
+
+    if (_glfw.wl.pointer) {
+        if (wl_pointer_get_version(_glfw.wl.pointer) >= WL_POINTER_RELEASE_SINCE_VERSION)
+            wl_pointer_release(_glfw.wl.pointer);
+        else
+            wl_pointer_destroy(_glfw.wl.pointer);
+
+        _glfw.wl.pointer = NULL;
+    }
+
+    if (_glfw.wl.dataDeviceManager) {
+        if (_glfw.wl.dataDevice) wl_data_device_destroy(_glfw.wl.dataDevice);
+        _glfw.wl.dataDevice =
+            wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
+                                                   _glfw.wl.seat);
+        _glfwAddDataDeviceListenerWayland(_glfw.wl.dataDevice);
+    }
 }
 
 static const struct wl_seat_listener seatListener =
-- 
2.56.0

