libX11/0004-ximcp-Add-fabricated_time-in-XimProtoPrivate-for-tim.patch

217 lines
6.7 KiB
Diff

From 24f2fdba4e5162ebcb011ce41104fb195b163169 Mon Sep 17 00:00:00 2001
From: Takao Fujiwara <tfujiwar@redhat.com>
Date: Fri, 26 Apr 2024 00:49:14 +0900
Subject: [PATCH libX11 4/7] ximcp: Add fabricated_time in XimProtoPrivate for
timeout
When users type keys quickly, some applications using Steam or Java
do not call XNextEvent() for a key event but _XimFilterKeypress()
and _XimFilterKeyrelease() expect to receive the key events
forwarded by input methods.
Now fabricated_time Time value is added to XimProtoPrivate to check
the timeout value.
Closes: #205
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 5a14178c7cc408f425fe298aeade3dee749b1ca1)
---
modules/im/ximcp/imDefFlt.c | 8 +++---
modules/im/ximcp/imDefIm.c | 2 ++
modules/im/ximcp/imDefLkup.c | 48 ++++++++++++++++++++++++++----------
src/xlibi18n/XimintP.h | 10 +++++---
4 files changed, 47 insertions(+), 21 deletions(-)
diff --git a/modules/im/ximcp/imDefFlt.c b/modules/im/ximcp/imDefFlt.c
index a7948df8..ad8a272b 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) || _XimIsFabricatedSerial(im, ev->serial)) {
+ if ((ev->keycode == 0) || _XimIsFabricatedSerial(im, ev)) {
_XimPendingFilter(ic);
- _XimUnfabricateSerial(im, ev->serial);
+ _XimUnfabricateSerial(im, ev);
return NOTFILTERD;
}
@@ -203,9 +203,9 @@ _XimProtoKeyreleaseFilter(
{
Xim im = (Xim)ic->core.im;
- if (_XimIsFabricatedSerial(im, ev->serial)) {
+ if (_XimIsFabricatedSerial(im, ev)) {
_XimPendingFilter(ic);
- _XimUnfabricateSerial(im, ev->serial);
+ _XimUnfabricateSerial(im, ev);
return NOTFILTERD;
}
diff --git a/modules/im/ximcp/imDefIm.c b/modules/im/ximcp/imDefIm.c
index a231a0ac..7eba0b34 100644
--- a/modules/im/ximcp/imDefIm.c
+++ b/modules/im/ximcp/imDefIm.c
@@ -431,6 +431,8 @@ _XimPreConnect(
im->private.proto.im_window = im_window;
im->private.proto.fabricated_serial = 0;
+ im->private.proto.fabricated_time = 0;
+ im->private.proto.enable_fabricated_order = True;
return True;
}
diff --git a/modules/im/ximcp/imDefLkup.c b/modules/im/ximcp/imDefLkup.c
index 53cf1f87..6b2d27dc 100644
--- a/modules/im/ximcp/imDefLkup.c
+++ b/modules/im/ximcp/imDefLkup.c
@@ -354,14 +354,14 @@ _XimForwardEvent(
Bool
_XimFabricateSerial(
Xim im,
- unsigned long serial)
+ XKeyEvent *event)
{
/* GTK2 XIM module sets serial=0. */
- if (!serial) {
+ if (!event->serial || !im->private.proto.enable_fabricated_order) {
MARK_FABRICATED(im);
return True;
}
- if (serial == im->private.proto.fabricated_serial) {
+ if (event->serial == im->private.proto.fabricated_serial) {
fprintf(stderr, "%s,%d: The key event is already fabricated.\n", __FILE__, __LINE__);
return False;
}
@@ -369,17 +369,18 @@ _XimFabricateSerial(
fprintf(stderr, "%s,%d: Tried to fabricate a wrong key event.\n", __FILE__, __LINE__);
MARK_FABRICATED(im);
- im->private.proto.fabricated_serial = serial;
+ im->private.proto.fabricated_serial = event->serial;
+ im->private.proto.fabricated_time = event->time;
return True;
}
Bool
_XimUnfabricateSerial(
Xim im,
- unsigned long serial)
+ XKeyEvent *event)
{
/* GTK2 XIM module sets serial=0. */
- if (!serial) {
+ if (!event->serial || !im->private.proto.enable_fabricated_order) {
UNMARK_FABRICATED(im);
return True;
}
@@ -387,10 +388,11 @@ _XimUnfabricateSerial(
fprintf(stderr, "%s,%d: The key event is already unfabricated.\n", __FILE__, __LINE__);
return False;
}
- if (serial != im->private.proto.fabricated_serial)
+ if (event->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;
+ im->private.proto.fabricated_time = 0;
UNMARK_FABRICATED(im);
return True;
}
@@ -398,12 +400,32 @@ _XimUnfabricateSerial(
Bool
_XimIsFabricatedSerial(
Xim im,
- unsigned long serial)
+ XKeyEvent *event)
{
/* GTK2 XIM module sets serial=0. */
- if (!serial)
- return IS_FABRICATED(im);
- return (serial == im->private.proto.fabricated_serial);
+ if (!event->serial || !im->private.proto.enable_fabricated_order)
+ return IS_FABRICATED(im) ? True : False;
+ if (event->serial == im->private.proto.fabricated_serial)
+ return True;
+ if (!im->private.proto.fabricated_serial)
+ return False;
+ /* Rotate time */
+ if (event->time < im->private.proto.fabricated_time) {
+ if (event->time >= 1000)
+ im->private.proto.fabricated_time = 0;
+ } else if (event->time - im->private.proto.fabricated_time > 1000) {
+ fprintf(stderr,
+ "%s,%d: The application disposed a key event with %ld serial.\n",
+ __FILE__, __LINE__,
+ im->private.proto.fabricated_serial);
+ im->private.proto.enable_fabricated_order = False;
+ if (IS_FABRICATED(im)) {
+ if (event->serial)
+ im->private.proto.fabricated_serial = event->serial;
+ return True;
+ }
+ }
+ return False;
}
static void
@@ -420,7 +442,7 @@ _XimProcEvent(
ev->xany.serial |= serial << 16;
ev->xany.send_event = False;
ev->xany.display = d;
- _XimFabricateSerial((Xim)ic->core.im, ev->xany.serial);
+ _XimFabricateSerial((Xim)ic->core.im, &ev->xkey);
return;
}
@@ -834,7 +856,7 @@ _XimCommitRecv(
if (ic->private.proto.registed_filter_event
& (KEYPRESS_MASK | KEYRELEASE_MASK))
- _XimFabricateSerial(im, ev.serial);
+ _XimFabricateSerial(im, &ev);
/* FIXME :
I wish there were COMMENTs (!) about the data passed around.
*/
diff --git a/src/xlibi18n/XimintP.h b/src/xlibi18n/XimintP.h
index 7f5b107a..715800c7 100644
--- a/src/xlibi18n/XimintP.h
+++ b/src/xlibi18n/XimintP.h
@@ -150,7 +150,9 @@ typedef struct _XimProtoPrivateRec {
XimTransCallDispatcher call_dispatcher;
XPointer spec;
- unsigned long fabricated_serial;
+ unsigned long fabricated_serial;
+ Time fabricated_time;
+ Bool enable_fabricated_order;
} XimProtoPrivateRec;
/*
@@ -312,16 +314,16 @@ typedef struct _XicProtoPrivateRec {
Bool
_XimFabricateSerial(
Xim im,
- unsigned long serial);
+ XKeyEvent *event);
Bool
_XimUnfabricateSerial(
Xim im,
- unsigned long serial);
+ XKeyEvent *event);
Bool
_XimIsFabricatedSerial(
Xim im,
- unsigned long serial);
+ XKeyEvent *event);
#endif /* _XIMINTP_H */
--
2.47.1