diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2010-01-01 23:03:42 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2010-01-01 23:03:42 (GMT) |
commit | aa4c765febd5c742dbc658574c6a06d4e94fdc59 (patch) | |
tree | fe2654888e979765a3b62105e2c73fdee4cf4442 | |
parent | 5834454dfdb57f33bae61fb49206c33584e05ee6 (diff) | |
download | tk-aa4c765febd5c742dbc658574c6a06d4e94fdc59.zip tk-aa4c765febd5c742dbc658574c6a06d4e94fdc59.tar.gz tk-aa4c765febd5c742dbc658574c6a06d4e94fdc59.tar.bz2 |
[Bug 1924761]: Consolidate calls to XFilterEvent to make input methods work.
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | generic/tkEvent.c | 78 | ||||
-rw-r--r-- | generic/tkInt.h | 7 | ||||
-rw-r--r-- | unix/tkUnixEvent.c | 32 |
4 files changed, 67 insertions, 75 deletions
@@ -1,13 +1,28 @@ +2010-01-01 Donal K. Fellows <dkf@users.sf.net> + + * unix/tkUnixEvent.c (TransferXEventsToTcl): [Bug 1924761]: Move the + * generic/tkEvent.c (Tk_HandleEvent): passing of key events to + XFilterEvent to the low level point where all other events are + handled, where it should have been all along. This makes more input + methods work, stops [event generate] from interfering with input + methods, and allows the simplification of tkEvent.c by removing half + of InvokeInputMethods and allowing the rest - which was not full input + method handling - to be rolled back into Tk_HandleEvent. Introduces a + small potential bug when a focus change and input method handling are + too close together in the Tk event queue, but that should be less + deadly to usability than the previous problems where input methods + could fail completely or reorder key presses... + 2009-12-30 Pat Thoyts <patthoyts@users.sourceforge.net> - * generic/tkMenu.c: Torn off menu items are only activated over - * tests/menu.tcl: a limited region of the window. Fixed to make - the whole width of a menu item activate the entry. [Patch 2879789] + * generic/tkMenu.c: [Patch 2879789]: Torn off menu items are only + * tests/menu.tcl: activated over a limited region of the window. + Fixed to make the whole width of a menu item activate the entry. 2009-12-27 Pat Thoyts <patthoyts@users.sourceforge.net> - * win/tkWinMenu.c: Highlight for cascade items in torn-off menus - is incorrect on Windows. Applied patch from [Bug 2879927]. + * win/tkWinMenu.c: [Bug 2879927]: Highlight for cascade items in + torn-off menus is incorrect on Windows. 2009-12-25 Donal K. Fellows <dkf@users.sf.net> diff --git a/generic/tkEvent.c b/generic/tkEvent.c index 2a13871..d298f46 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkEvent.c,v 1.35.2.2 2009/01/11 19:29:42 georgeps Exp $ + * RCS: @(#) $Id: tkEvent.c,v 1.35.2.3 2010/01/01 23:03:42 dkf Exp $ */ #include "tkInt.h" @@ -212,7 +212,6 @@ static int TkXErrorHandler(ClientData clientData, static void UpdateButtonEventState(XEvent *eventPtr); static int WindowEventProc(Tcl_Event *evPtr, int flags); #ifdef TK_USE_INPUT_METHODS -static int InvokeInputMethods(TkWindow *winPtr, XEvent *eventPtr); static void CreateXIC(TkWindow *winPtr); #endif /* TK_USE_INPUT_METHODS */ @@ -379,62 +378,6 @@ CreateXIC( /* *---------------------------------------------------------------------- * - * InvokeInputMethods -- - * - * Pass the event to the input method(s), if there are any, and discard - * the event if the input method(s) insist. Create the input context for - * the window if it hasn't already been done (XFilterEvent needs this - * context). - * - * When the event is a FocusIn event, set the input context focus to the - * receiving window. - * - * Results: - * 1 when we are done with the event. - * 0 when the event can be processed further. - * - * Side effects: - * Input contexts/methods may be created. - * - *---------------------------------------------------------------------- - */ - -#ifdef TK_USE_INPUT_METHODS -static int -InvokeInputMethods( - TkWindow *winPtr, - XEvent *eventPtr) -{ - TkDisplay *dispPtr = winPtr->dispPtr; - - if ((dispPtr->flags & TK_DISPLAY_USE_IM)) { - if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) { - winPtr->flags |= TK_CHECKED_IC; - if (dispPtr->inputMethod != NULL) { - CreateXIC(winPtr); - } - } - switch (eventPtr->type) { - case FocusIn: - if (winPtr->inputContext != NULL) { - XSetICFocus(winPtr->inputContext); - } - break; - case KeyPress: - case KeyRelease: - if (XFilterEvent(eventPtr, None)) { - return 1; - } - break; - } - } - return 0; -} -#endif /*TK_USE_INPUT_METHODS*/ - -/* - *---------------------------------------------------------------------- - * * GetTkWindowFromXEvent -- * * Attempt to find which TkWindow is associated with an event. If it @@ -1346,9 +1289,24 @@ Tk_HandleEvent( } } + /* + * Create the input context for the window if it hasn't already been done + * (XFilterEvent needs this context). When the event is a FocusIn event, + * set the input context focus to the receiving window. This code is only + * ever active for X11. + */ + #ifdef TK_USE_INPUT_METHODS - if (InvokeInputMethods(winPtr, eventPtr)) { - goto releaseInterpreter; + if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) { + if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) { + winPtr->flags |= TK_CHECKED_IC; + if (winPtr->dispPtr->inputMethod != NULL) { + CreateXIC(winPtr); + } + } + if (eventPtr->type == FocusIn && winPtr->inputContext != NULL) { + XSetICFocus(winPtr->inputContext); + } } #endif diff --git a/generic/tkInt.h b/generic/tkInt.h index c929f05..9cec9ab 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: $Id: tkInt.h,v 1.82.2.4 2009/06/27 19:53:16 nijtmans Exp $ + * RCS: $Id: tkInt.h,v 1.82.2.5 2010/01/01 23:03:42 dkf Exp $ */ #ifndef _TKINT @@ -313,8 +313,9 @@ typedef struct TkDisplay { * multiple applications on the display have * the focus, this will refer to the innermost * window in the innermost application. This - * information isn't used under Unix or - * Windows, but it's needed on the Mac. */ + * information isn't used on Windows, but it's + * needed on the Mac, and also on X11 when XIM + * processing is being done. */ /* * Information used by tkGC.c only: diff --git a/unix/tkUnixEvent.c b/unix/tkUnixEvent.c index bb66552..52e5673 100644 --- a/unix/tkUnixEvent.c +++ b/unix/tkUnixEvent.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnixEvent.c,v 1.27 2008/03/26 19:04:10 jenglish Exp $ + * RCS: @(#) $Id: tkUnixEvent.c,v 1.27.2.1 2010/01/01 23:03:42 dkf Exp $ */ #include "tkUnixInt.h" @@ -279,21 +279,39 @@ TransferXEventsToTcl( Display *display) { XEvent event; + Window w; /* * Transfer events from the X event queue to the Tk event queue after XIM - * event filtering. KeyPress and KeyRelease events are filtered in - * Tk_HandleEvent instead of here, so that Tk's focus management code can - * redirect them. + * event filtering. KeyPress and KeyRelease events need special treatment + * so that they get directed according to Tk's focus rules during XIM + * handling. Theoretically they can go to the wrong place still (if + * there's a focus change in the queue) but if we push the handling off + * until Tk_HandleEvent then many input methods actually cease to work + * correctly. Most of the time, Tk processes its event queue fast enough + * for this to not be an issue anyway. [Bug 1924761] */ while (QLength(display) > 0) { XNextEvent(display, &event); - if (event.type != KeyPress && event.type != KeyRelease) { - if (XFilterEvent(&event, None)) { - continue; + w = None; + if (event.x.type == KeyPress || event.x.type == KeyRelease) { + TkDisplay *dispPtr; + + for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { + if (dispPtr == NULL) { + break; + } else if (dispPtr->display == event.x.xany.display) { + if (dispPtr->focusPtr != NULL) { + w = dispPtr->focusPtr->window; + } + break; + } } } + if (XFilterEvent(&event.x, w)) { + continue; + } Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } } |