mirror of
https://gitlab.freedesktop.org/xorg/lib/libx11.git
synced 2026-05-05 01:48:00 +02:00
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>
This commit is contained in:
parent
1181abd6ff
commit
5a14178c7c
4 changed files with 47 additions and 21 deletions
|
|
@ -142,9 +142,9 @@ _XimProtoKeypressFilter(
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -344,14 +344,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;
|
||||
}
|
||||
|
|
@ -359,17 +359,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;
|
||||
}
|
||||
|
|
@ -377,10 +378,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;
|
||||
}
|
||||
|
|
@ -388,12 +390,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
|
||||
|
|
@ -410,7 +432,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;
|
||||
}
|
||||
|
||||
|
|
@ -811,7 +833,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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue