169 lines
5.4 KiB
Diff
169 lines
5.4 KiB
Diff
From b3157722535db692d54b8fe7d26d07f94d49daf3 Mon Sep 17 00:00:00 2001
|
|
From: Takao Fujiwara <tfujiwar@redhat.com>
|
|
Date: Fri, 26 Apr 2024 01:29:26 +0900
|
|
Subject: [PATCH libX11 5/7] Accept anon windows in XFilterEvent to update XIM
|
|
state
|
|
|
|
When input focuses are switched quickly with shortcut keys in a Java
|
|
window, the focus is sometimes lost and the Window=0 is assigned in
|
|
XFilterEvent() but the XKeyEvent was forwarded by a XIM serer(IBus)
|
|
with XIM_FORWARD_EVENT -> XNextEvent() -> XFilterEvent() and the event
|
|
needs to be forwarded to the XIM XKeyEvent press and release filters
|
|
to update the XIM state with Window=0 likes _XimPendingFilter() and
|
|
_XimUnfabricateSerial().
|
|
|
|
Closes: #205, #206
|
|
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 5a1e62d77b65ba148b1c6d1d22a81dc2b07e7d9e)
|
|
---
|
|
modules/im/ximcp/imDefFlt.c | 34 ++++++++++++++++++++++++++++++----
|
|
src/FilterEv.c | 25 +++++++++++++++++++++++++
|
|
2 files changed, 55 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/modules/im/ximcp/imDefFlt.c b/modules/im/ximcp/imDefFlt.c
|
|
index ad8a272b..76d63e88 100644
|
|
--- a/modules/im/ximcp/imDefFlt.c
|
|
+++ b/modules/im/ximcp/imDefFlt.c
|
|
@@ -138,7 +138,8 @@ _XimPendingFilter(
|
|
static Bool
|
|
_XimProtoKeypressFilter(
|
|
Xic ic,
|
|
- XKeyEvent *ev)
|
|
+ XKeyEvent *ev,
|
|
+ Window w)
|
|
{
|
|
Xim im = (Xim)ic->core.im;
|
|
|
|
@@ -147,6 +148,9 @@ _XimProtoKeypressFilter(
|
|
_XimUnfabricateSerial(im, ev);
|
|
return NOTFILTERD;
|
|
}
|
|
+ /* w=0 is used for _XimIsFabricatedSerial() only */
|
|
+ if (!w)
|
|
+ return NOTFILTERD;
|
|
|
|
if (IS_NEGLECT_EVENT(ic, KeyPressMask))
|
|
return FILTERD;
|
|
@@ -193,13 +197,14 @@ _XimFilterKeypress(
|
|
XEvent *ev,
|
|
XPointer client_data)
|
|
{
|
|
- return _XimProtoKeypressFilter((Xic)client_data, (XKeyEvent *)ev );
|
|
+ return _XimProtoKeypressFilter((Xic)client_data, (XKeyEvent *)ev, w);
|
|
}
|
|
|
|
static Bool
|
|
_XimProtoKeyreleaseFilter(
|
|
Xic ic,
|
|
- XKeyEvent *ev)
|
|
+ XKeyEvent *ev,
|
|
+ Window w)
|
|
{
|
|
Xim im = (Xim)ic->core.im;
|
|
|
|
@@ -208,6 +213,9 @@ _XimProtoKeyreleaseFilter(
|
|
_XimUnfabricateSerial(im, ev);
|
|
return NOTFILTERD;
|
|
}
|
|
+ /* w=0 is used for _XimIsFabricatedSerial() only */
|
|
+ if (!w)
|
|
+ return NOTFILTERD;
|
|
|
|
if (IS_NEGLECT_EVENT(ic, KeyReleaseMask))
|
|
return FILTERD;
|
|
@@ -254,7 +262,7 @@ _XimFilterKeyrelease(
|
|
XEvent *ev,
|
|
XPointer client_data)
|
|
{
|
|
- return _XimProtoKeyreleaseFilter((Xic)client_data, (XKeyEvent *)ev);
|
|
+ return _XimProtoKeyreleaseFilter((Xic)client_data, (XKeyEvent *)ev, w);
|
|
}
|
|
|
|
static void
|
|
@@ -263,6 +271,11 @@ _XimRegisterKeyPressFilter(
|
|
{
|
|
if (ic->core.focus_window) {
|
|
if (!(ic->private.proto.registed_filter_event & KEYPRESS_MASK)) {
|
|
+ _XRegisterFilterByType (ic->core.im->core.display,
|
|
+ 0,
|
|
+ KeyPress, KeyPress,
|
|
+ _XimFilterKeypress,
|
|
+ (XPointer)ic);
|
|
_XRegisterFilterByType (ic->core.im->core.display,
|
|
ic->core.focus_window,
|
|
KeyPress, KeyPress,
|
|
@@ -280,6 +293,11 @@ _XimRegisterKeyReleaseFilter(
|
|
{
|
|
if (ic->core.focus_window) {
|
|
if (!(ic->private.proto.registed_filter_event & KEYRELEASE_MASK)) {
|
|
+ _XRegisterFilterByType (ic->core.im->core.display,
|
|
+ 0,
|
|
+ KeyRelease, KeyRelease,
|
|
+ _XimFilterKeyrelease,
|
|
+ (XPointer)ic);
|
|
_XRegisterFilterByType (ic->core.im->core.display,
|
|
ic->core.focus_window,
|
|
KeyRelease, KeyRelease,
|
|
@@ -301,6 +319,10 @@ _XimUnregisterKeyPressFilter(
|
|
ic->core.focus_window,
|
|
_XimFilterKeypress,
|
|
(XPointer)ic);
|
|
+ _XUnregisterFilter (ic->core.im->core.display,
|
|
+ 0,
|
|
+ _XimFilterKeypress,
|
|
+ (XPointer)ic);
|
|
ic->private.proto.registed_filter_event &= ~KEYPRESS_MASK;
|
|
}
|
|
}
|
|
@@ -317,6 +339,10 @@ _XimUnregisterKeyReleaseFilter(
|
|
ic->core.focus_window,
|
|
_XimFilterKeyrelease,
|
|
(XPointer)ic);
|
|
+ _XUnregisterFilter (ic->core.im->core.display,
|
|
+ 0,
|
|
+ _XimFilterKeyrelease,
|
|
+ (XPointer)ic);
|
|
ic->private.proto.registed_filter_event &= ~KEYRELEASE_MASK;
|
|
}
|
|
}
|
|
diff --git a/src/FilterEv.c b/src/FilterEv.c
|
|
index 0a48e548..07845bcc 100644
|
|
--- a/src/FilterEv.c
|
|
+++ b/src/FilterEv.c
|
|
@@ -100,6 +100,31 @@ XFilterEvent(
|
|
}
|
|
}
|
|
}
|
|
+ for (p = ev->xany.display->im_filters; p != NULL; p = p->next) {
|
|
+ /* Java sometimes calls XFilterEvent() with window=0 and ev come from
|
|
+ * XNextEvent() when users type some keys quickly and switch multiple
|
|
+ * input focuses in a Java window with the keys.
|
|
+ * But XKeyEvent filters need to receive the event with window=0 for
|
|
+ * _XimPendingFilter() and _XimUnfabricateSerial() to clear the
|
|
+ * fowarded XKeyEvent with XIM_FORWARD_EVENT.
|
|
+ *
|
|
+ * The case of p->window == 0 is checkekd after all cases of p->window
|
|
+ * != 0 are checked because all input contexts share
|
|
+ * Display->im_filters but each input context has
|
|
+ * Xic->private.proto.registed_filter_event for the filters
|
|
+ * and same p->filter could be registerd to Display->im_filters twice
|
|
+ * with different p->window.
|
|
+ */
|
|
+ if (p->window == 0 && window == 0) {
|
|
+ if ((mask & p->event_mask) ||
|
|
+ (ev->type >= p->start_type && ev->type <= p->end_type)) {
|
|
+ UnlockDisplay(ev->xany.display);
|
|
+ ret = (*(p->filter))(ev->xany.display, p->window, ev,
|
|
+ p->client_data);
|
|
+ return(ret);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
UnlockDisplay(ev->xany.display);
|
|
#endif
|
|
return(False);
|
|
--
|
|
2.47.1
|
|
|