diff options
author | Weng Xuetian <wengxt@gmail.com> | 2025-04-18 02:22:06 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2025-05-24 13:46:13 -0700 |
commit | 7f8305c779ac6948d7261764f5ffb8ae9aa975b1 (patch) | |
tree | 7a1451bd3e4bdd7656f4262ca7f7084802f95d05 | |
parent | 59917d28a3c41ad22d6fc52e323cafe2cdd596d5 (diff) |
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>
-rw-r--r-- | modules/im/ximcp/imDefFlt.c | 12 | ||||
-rw-r--r-- | modules/im/ximcp/imDefLkup.c | 11 | ||||
-rw-r--r-- | src/xlibi18n/XimintP.h | 3 |
3 files changed, 24 insertions, 2 deletions
diff --git a/modules/im/ximcp/imDefFlt.c b/modules/im/ximcp/imDefFlt.c index 9bd4f97f..54e738b2 100644 --- a/modules/im/ximcp/imDefFlt.c +++ b/modules/im/ximcp/imDefFlt.c @@ -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; } diff --git a/modules/im/ximcp/imDefLkup.c b/modules/im/ximcp/imDefLkup.c index 8ccaee26..f5ba3405 100644 --- a/modules/im/ximcp/imDefLkup.c +++ b/modules/im/ximcp/imDefLkup.c @@ -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; diff --git a/src/xlibi18n/XimintP.h b/src/xlibi18n/XimintP.h index 525e1ddb..2957e3a0 100644 --- a/src/xlibi18n/XimintP.h +++ b/src/xlibi18n/XimintP.h @@ -327,4 +327,7 @@ _XimIsFabricatedSerial( Xim im, XKeyEvent *event); +_X_HIDDEN void +_XimPendingFilter( + Xic ic); #endif /* _XIMINTP_H */ |