diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2011-02-22 16:31:11 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2011-02-22 16:33:28 +0100 |
commit | b81e2789d7d5a20900c79f69c69cd6a7cd4408e8 (patch) | |
tree | 5eabdee08a3219680a5011462720e132c22bef51 | |
parent | 8f0c8a2d3701f02c070117d08ee997ba4ea48d38 (diff) |
try to work around IM problems with KDE4 integration (bnc#665112)
See comment for SalKDEDisplay::checkDirectInputEvent(). This was
introduced when switching to using Qt event loop, Qt processes
IM handling before LO gets a chance to do something and this conflicts.
This is rather hackish but I have no better idea and as long as
the IM protocol does not change it should be fine.
-rw-r--r-- | vcl/unx/kde4/KDESalDisplay.cxx | 26 | ||||
-rw-r--r-- | vcl/unx/kde4/KDESalDisplay.hxx | 2 | ||||
-rw-r--r-- | vcl/unx/kde4/KDEXLib.cxx | 11 |
3 files changed, 39 insertions, 0 deletions
diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx index dbfba3d4da6c..29292b68f142 100644 --- a/vcl/unx/kde4/KDESalDisplay.cxx +++ b/vcl/unx/kde4/KDESalDisplay.cxx @@ -41,6 +41,7 @@ SalKDEDisplay::SalKDEDisplay( Display* pDisp ) { assert( selfptr == NULL ); selfptr = this; + xim_protocol = XInternAtom( pDisp_, "_XIM_PROTOCOL", False ); } SalKDEDisplay::~SalKDEDisplay() @@ -65,7 +66,32 @@ void SalKDEDisplay::Yield() XEvent event; XNextEvent( pDisp_, &event ); + if( checkDirectInputEvent( &event )) + return; qApp->x11ProcessEvent( &event ); } +// HACK: When using Qt event loop, input methods (japanese, etc.) will get broken because +// of XFilterEvent() getting called twice, once by Qt, once by LO (bnc#665112). +// This function is therefore called before any XEvent is passed to Qt event handling +// and if it is a keyboard event and no Qt widget is the active window (i.e. we are +// processing events for some LO window), then feed the event only to LO directly and skip Qt +// completely. Skipped events are KeyPress, KeyRelease and also _XIM_PROTOCOL client message +// (seems to be necessary too, hopefully there are not other internal XIM messages that +// would need this handling). +bool SalKDEDisplay::checkDirectInputEvent( XEvent* ev ) +{ + if( ev->xany.type == XLIB_KeyPress || ev->xany.type == KeyRelease + || ( ev->xany.type == ClientMessage && ev->xclient.message_type == xim_protocol )) + { + if( qApp->activeWindow() == NULL ) + { + Dispatch(ev); + return true; + } + } + return false; +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/kde4/KDESalDisplay.hxx b/vcl/unx/kde4/KDESalDisplay.hxx index 37a097f5051f..3b7117684942 100644 --- a/vcl/unx/kde4/KDESalDisplay.hxx +++ b/vcl/unx/kde4/KDESalDisplay.hxx @@ -41,7 +41,9 @@ class SalKDEDisplay : public SalX11Display inline void EventGuardRelease() { osl_releaseMutex( hEventGuard_ ); } // virtual long Dispatch( XEvent *event ); virtual void Yield(); + bool checkDirectInputEvent( XEvent* ev ); private: + Atom xim_protocol; static SalKDEDisplay* selfptr; }; diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx index 77a667ad34d4..13c39528b3ae 100644 --- a/vcl/unx/kde4/KDEXLib.cxx +++ b/vcl/unx/kde4/KDEXLib.cxx @@ -209,8 +209,19 @@ static int lo_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept const struct timeval *orig_timeout); #endif +static bool ( *old_qt_event_filter )( void* ); +static bool qt_event_filter( void* m ) +{ + if( old_qt_event_filter != NULL && old_qt_event_filter( m )) + return true; + if( SalKDEDisplay::self() && SalKDEDisplay::self()->checkDirectInputEvent( static_cast< XEvent* >( m ))) + return true; + return false; +} + void KDEXLib::setupEventLoop() { + old_qt_event_filter = QAbstractEventDispatcher::instance()->setEventFilter( qt_event_filter ); #ifdef GLIB_EVENT_LOOP_SUPPORT // Glib is simple, it has g_main_context_set_poll_func() for wrapping the sleep call. // The catch is that Qt has a bug that allows triggering timers even when they should |