From 24f2fdba4e5162ebcb011ce41104fb195b163169 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara 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: (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