217 lines
6.7 KiB
Diff
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
|
|
|