~exec64/imv#11: 
Input only works on the first enumerated seat on Wayland

I'm on sway and I use 2 seats: one for my regular peripherals and one for my pentablet+second keyboard. I use this to navigate references (which I then display using imv) and my drawing application separately.

This causes seat_capabilities in wl_window.c to be called twice, but the function only registers the first set of inputs.

How to replicate:

  • Create two seats with a keyboard and mouse each
  • Attempt to use imv navigation with both of them
  • One will not work

Expected:

  • Mouse and keyboard input work

Current:

  • Inputs only work from the first seat that gets passed in seat_capabilities

Workaround:

  • Add the listeners despite wl_keyboard and wl_pointer already being set. This causes the inputs to work as expected. However, proper cleanup requires imv_window to account for multiple seats.

Here is the workaround I use:

From 549b0c35e6c70f94f2f37f8e8b7dc8b24b4640dd Mon Sep 17 00:00:00 2001
From: sleepy <>
Date: Fri, 8 Apr 2022 17:23:46 +0200
Subject: [PATCH 1/1] Multiseat Input on Wayland

---
 src/wl_window.c | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/src/wl_window.c b/src/wl_window.c
index 5efa42f..5b37577 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -414,28 +414,14 @@ static void seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabil
   struct imv_window *window = data;
 
   if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
-    if (!window->wl_pointer) {
-      window->wl_pointer = wl_seat_get_pointer(window->wl_seat);
+    window->wl_pointer = wl_seat_get_pointer(seat);
       wl_pointer_add_listener(window->wl_pointer, &pointer_listener, window);
     }
-  } else {
-    if (window->wl_pointer) {
-      wl_pointer_release(window->wl_pointer);
-      window->wl_pointer = NULL;
-    }
-  }
 
   if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
-    if (!window->wl_keyboard) {
-      window->wl_keyboard = wl_seat_get_keyboard(window->wl_seat);
+    window->wl_keyboard = wl_seat_get_keyboard(seat);
       wl_keyboard_add_listener(window->wl_keyboard, &keyboard_listener, window);
     }
-  } else {
-    if (window->wl_keyboard) {
-      wl_keyboard_release(window->wl_keyboard);
-      window->wl_keyboard = NULL;
-    }
-  }
 }
 
 static void seat_name(void *data, struct wl_seat *seat, const char *name)
-- 
2.35.1
Status
REPORTED
Submitter
~sleepy
Assigned to
No-one
Submitted
2 months ago
Updated
2 months ago
Labels
No labels applied.