imDefIc: Clear fabricated state on unfocus.

When unsetting focus, the event filter is removed. This means a pending
fabricated event may not yet be sent to filter.

All the fabricated event state should be cleared and the pending sync
reply sent back as if the state is unfabricated.

Fix #235

Part-of: <https://gitlab.freedesktop.org/xorg/lib/libx11/-/merge_requests/283>
This commit is contained in:
Weng Xuetian 2025-04-18 02:22:06 -07:00 committed by Alan Coopersmith
parent 59917d28a3
commit 7f8305c779
3 changed files with 24 additions and 2 deletions

View file

@ -122,7 +122,7 @@ _XimOffKeysCheck(
return False;
}
static void
void
_XimPendingFilter(
Xic ic)
{
@ -363,8 +363,18 @@ void
_XimUnregisterFilter(
Xic ic)
{
Xim im = (Xim)ic->core.im;
_XimUnregisterKeyPressFilter(ic);
_XimUnregisterKeyReleaseFilter(ic);
/* It is possible that the event from IM is received after unregister
* the filter.
* Reset any existing fabricated state since we will not be able to
* clear the fabricated state for those event in filter.
*/
im->private.proto.fabricated_serial = 0;
im->private.proto.fabricated_time = 0;
UNMARK_FABRICATED(im);
_XimPendingFilter(ic);
return;
}

View file

@ -442,7 +442,6 @@ _XimProcEvent(
ev->xany.serial |= serial << 16;
ev->xany.send_event = False;
ev->xany.display = d;
_XimFabricateSerial((Xim)ic->core.im, &ev->xkey);
return;
}
@ -460,6 +459,16 @@ _XimForwardEventRecv(
(void)_XimRespSyncReply(ic, buf_s[0]);
/* If no event filter is registered, the event will not be sent back
* to filter for _XimUnfabricateSerial, so simply bypass it.
*/
if (ic->private.proto.registed_filter_event
& (KEYPRESS_MASK | KEYRELEASE_MASK)) {
_XimFabricateSerial((Xim)ic->core.im, &ev.xkey);
} else {
_XimPendingFilter(ic);
}
XPutBackEvent(d, &ev);
return True;

View file

@ -327,4 +327,7 @@ _XimIsFabricatedSerial(
Xim im,
XKeyEvent *event);
_X_HIDDEN void
_XimPendingFilter(
Xic ic);
#endif /* _XIMINTP_H */