Blob Blame History Raw
From 822cd458d0027fddc9f391587d8e6db1a4ce8002 Mon Sep 17 00:00:00 2001
From: Jamie Zawinski <jwz@jwz.org>
Date: Tue, 4 May 2021 10:05:18 +0900
Subject: [PATCH] init_xinput: remove duplicate event for multiple screen

---
 driver/xinput.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/driver/xinput.c b/driver/xinput.c
index 3b21db02..c64ee212 100644
--- a/driver/xinput.c
+++ b/driver/xinput.c
@@ -117,6 +117,28 @@ init_xinput (Display *dpy, int *opcode_ret)
 }


+/* If there is more than one Screen on the Display, XInput2 sends an event for
+   each Screen.  You'd think that they would have the 'root' member set to the
+   root window of that screen, so that we could ignore events not destined for
+   our screen, but no, they have the same root window.  But they also have the
+   same 'serial' and 'time', so we can ignore the duplicates by noticing
+   recently-duplicated event serial numbers, which ought never happen.
+ */
+static Bool
+duplicate_xinput_event_p (XIDeviceEvent *in)
+{
+  static unsigned long dups[50] = { 0, };   /* No more than N screens */
+  int i;
+  for (i = 0; i < countof(dups); i++)
+    if (dups[i] == in->serial)
+      return True;
+  for (i = 0; i < countof(dups)-1; i++)
+    dups[i] = dups[i+1];
+  dups[i] = in->serial;
+  return False;
+}
+
+
 /* Convert an XInput2 event to corresponding old-school Xlib event.
    Returns true on success.
  */
@@ -225,6 +247,9 @@ xinput_event_to_xlib (int evtype, XIDeviceEvent *in, XEvent *out)
     break;
   }

+  if (duplicate_xinput_event_p (in))
+    ok = False;
+
   return ok;
 }

-- 
2.31.1