201 lines
5.7 KiB
Diff
201 lines
5.7 KiB
Diff
From a91e5a5e6fca25f23c7dd24c6694ab1b80b6030e Mon Sep 17 00:00:00 2001
|
|
From: Takao Fujiwara <tfujiwar@redhat.com>
|
|
Date: Fri, 12 Apr 2024 10:21:41 +0900
|
|
Subject: [PATCH libX11 1/7] ximcp: Unmark to fabricate key events with
|
|
XKeyEvent serial
|
|
|
|
_XimProtoKeypressFilter() and _XimProtoKeyreleaseFilter() can
|
|
receive XKeyEvent from both the typing on the keyboard and the
|
|
callback of XIM_FORWARD_EVENT.
|
|
|
|
If the filter functions unmark to fabricate XKeyEvent from the typing
|
|
on the keyboard during receiving XKeyEvent from the callback of
|
|
XIM_FORWARD_EVENT with typing keys very quickly likes an bar code
|
|
scanner (or evemu-play), XIM server cannot receive some key events and
|
|
it causes the key typing order to get scrambled.
|
|
|
|
Now XIM client saves the serial in XKeyEvent and the filter functions
|
|
unmark to fabricate XKeyEvent from the callback of XIM_FORWARD_EVENT
|
|
only.
|
|
|
|
This and 024d229f are same patches but the regression issues will be
|
|
fixed by the later patches.
|
|
|
|
Closes: #198
|
|
Fixes: 024d229f ("ximcp: Unmark to fabricate key events with XKeyEvent serial")
|
|
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libx11/-/merge_requests/246>
|
|
(cherry picked from commit 13e9ac4d458069c81d795f6b4842814d30431b4b)
|
|
---
|
|
modules/im/ximcp/imDefFlt.c | 8 ++---
|
|
modules/im/ximcp/imDefIm.c | 1 +
|
|
modules/im/ximcp/imDefLkup.c | 58 ++++++++++++++++++++++++++++++++----
|
|
src/xlibi18n/XimintP.h | 17 +++++++++++
|
|
4 files changed, 75 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/modules/im/ximcp/imDefFlt.c b/modules/im/ximcp/imDefFlt.c
|
|
index f89d2cb0..a7948df8 100644
|
|
--- a/modules/im/ximcp/imDefFlt.c
|
|
+++ b/modules/im/ximcp/imDefFlt.c
|
|
@@ -142,9 +142,9 @@ _XimProtoKeypressFilter(
|
|
{
|
|
Xim im = (Xim)ic->core.im;
|
|
|
|
- if ((ev->keycode == 0) || IS_FABRICATED(im)) {
|
|
+ if ((ev->keycode == 0) || _XimIsFabricatedSerial(im, ev->serial)) {
|
|
_XimPendingFilter(ic);
|
|
- UNMARK_FABRICATED(im);
|
|
+ _XimUnfabricateSerial(im, ev->serial);
|
|
return NOTFILTERD;
|
|
}
|
|
|
|
@@ -203,9 +203,9 @@ _XimProtoKeyreleaseFilter(
|
|
{
|
|
Xim im = (Xim)ic->core.im;
|
|
|
|
- if (IS_FABRICATED(im)) {
|
|
+ if (_XimIsFabricatedSerial(im, ev->serial)) {
|
|
_XimPendingFilter(ic);
|
|
- UNMARK_FABRICATED(im);
|
|
+ _XimUnfabricateSerial(im, ev->serial);
|
|
return NOTFILTERD;
|
|
}
|
|
|
|
diff --git a/modules/im/ximcp/imDefIm.c b/modules/im/ximcp/imDefIm.c
|
|
index ccdf14c1..a231a0ac 100644
|
|
--- a/modules/im/ximcp/imDefIm.c
|
|
+++ b/modules/im/ximcp/imDefIm.c
|
|
@@ -430,6 +430,7 @@ _XimPreConnect(
|
|
return False;
|
|
|
|
im->private.proto.im_window = im_window;
|
|
+ im->private.proto.fabricated_serial = 0;
|
|
return True;
|
|
}
|
|
|
|
diff --git a/modules/im/ximcp/imDefLkup.c b/modules/im/ximcp/imDefLkup.c
|
|
index 18289a80..a6923d5b 100644
|
|
--- a/modules/im/ximcp/imDefLkup.c
|
|
+++ b/modules/im/ximcp/imDefLkup.c
|
|
@@ -351,6 +351,54 @@ _XimForwardEvent(
|
|
return _XimForwardEventCore(ic, ev, sync);
|
|
}
|
|
|
|
+Bool
|
|
+_XimFabricateSerial(
|
|
+ Xim im,
|
|
+ unsigned long serial)
|
|
+{
|
|
+ if (!serial)
|
|
+ return False;
|
|
+ if (serial == im->private.proto.fabricated_serial) {
|
|
+ fprintf(stderr, "%s,%d: The key event is already fabricated.\n", __FILE__, __LINE__);
|
|
+ return False;
|
|
+ }
|
|
+ if (im->private.proto.fabricated_serial)
|
|
+ fprintf(stderr, "%s,%d: Tried to fabricate a wrong key event.\n", __FILE__, __LINE__);
|
|
+
|
|
+ MARK_FABRICATED(im);
|
|
+ im->private.proto.fabricated_serial = serial;
|
|
+ return True;
|
|
+}
|
|
+
|
|
+Bool
|
|
+_XimUnfabricateSerial(
|
|
+ Xim im,
|
|
+ unsigned long serial)
|
|
+{
|
|
+ if (!serial)
|
|
+ return False;
|
|
+ if (!im->private.proto.fabricated_serial) {
|
|
+ fprintf(stderr, "%s,%d: The key event is already unfabricated.\n", __FILE__, __LINE__);
|
|
+ return False;
|
|
+ }
|
|
+ if (serial != im->private.proto.fabricated_serial)
|
|
+ fprintf(stderr, "%s,%d: Tried to unfabricate a wrong key event.\n", __FILE__, __LINE__);
|
|
+
|
|
+ im->private.proto.fabricated_serial = 0;
|
|
+ UNMARK_FABRICATED(im);
|
|
+ return True;
|
|
+}
|
|
+
|
|
+Bool
|
|
+_XimIsFabricatedSerial(
|
|
+ Xim im,
|
|
+ unsigned long serial)
|
|
+{
|
|
+ if (!serial)
|
|
+ return False;
|
|
+ return (serial == im->private.proto.fabricated_serial);
|
|
+}
|
|
+
|
|
static void
|
|
_XimProcEvent(
|
|
Display *d,
|
|
@@ -365,7 +413,7 @@ _XimProcEvent(
|
|
ev->xany.serial |= serial << 16;
|
|
ev->xany.send_event = False;
|
|
ev->xany.display = d;
|
|
- MARK_FABRICATED(ic->core.im);
|
|
+ _XimFabricateSerial((Xim)ic->core.im, ev->xany.serial);
|
|
return;
|
|
}
|
|
|
|
@@ -727,10 +775,6 @@ _XimCommitRecv(
|
|
|
|
(void)_XimRespSyncReply(ic, flag);
|
|
|
|
- if (ic->private.proto.registed_filter_event
|
|
- & (KEYPRESS_MASK | KEYRELEASE_MASK))
|
|
- MARK_FABRICATED(im);
|
|
-
|
|
bzero(&ev, sizeof(ev)); /* uninitialized : found when running kterm under valgrind */
|
|
|
|
ev.type = KeyPress;
|
|
@@ -742,6 +786,10 @@ _XimCommitRecv(
|
|
|
|
ev.time = 0L;
|
|
ev.serial = LastKnownRequestProcessed(im->core.display);
|
|
+
|
|
+ if (ic->private.proto.registed_filter_event
|
|
+ & (KEYPRESS_MASK | KEYRELEASE_MASK))
|
|
+ _XimFabricateSerial(im, ev.serial);
|
|
/* FIXME :
|
|
I wish there were COMMENTs (!) about the data passed around.
|
|
*/
|
|
diff --git a/src/xlibi18n/XimintP.h b/src/xlibi18n/XimintP.h
|
|
index 14a7e6d5..7f5b107a 100644
|
|
--- a/src/xlibi18n/XimintP.h
|
|
+++ b/src/xlibi18n/XimintP.h
|
|
@@ -149,6 +149,8 @@ typedef struct _XimProtoPrivateRec {
|
|
XimTransRegDispatcher register_dispatcher;
|
|
XimTransCallDispatcher call_dispatcher;
|
|
XPointer spec;
|
|
+
|
|
+ unsigned long fabricated_serial;
|
|
} XimProtoPrivateRec;
|
|
|
|
/*
|
|
@@ -307,4 +309,19 @@ typedef struct _XicProtoPrivateRec {
|
|
#define XIM_MAXIMNAMELEN 64
|
|
#define XIM_MAXLCNAMELEN 64
|
|
|
|
+Bool
|
|
+_XimFabricateSerial(
|
|
+ Xim im,
|
|
+ unsigned long serial);
|
|
+
|
|
+Bool
|
|
+_XimUnfabricateSerial(
|
|
+ Xim im,
|
|
+ unsigned long serial);
|
|
+
|
|
+Bool
|
|
+_XimIsFabricatedSerial(
|
|
+ Xim im,
|
|
+ unsigned long serial);
|
|
+
|
|
#endif /* _XIMINTP_H */
|
|
--
|
|
2.47.1
|
|
|