summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2011-02-22 16:31:11 +0100
committerLuboš Luňák <l.lunak@suse.cz>2011-02-23 12:18:33 +0100
commitf52762f330ea6a6cb46e03b6960a1cbddd80112d (patch)
treeeb1c8fee8893c8acff063599f0ad6a5b8161ffc7 /vcl
parent71f7ea152bb4e5f1d40d37e704ddbea952f55119 (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. ACK by Petr Mladek.
Diffstat (limited to 'vcl')
-rw-r--r--vcl/unx/kde4/KDESalDisplay.cxx26
-rw-r--r--vcl/unx/kde4/KDESalDisplay.hxx2
-rw-r--r--vcl/unx/kde4/KDEXLib.cxx11
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 6544dd86be74..c61a00240721 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -205,8 +205,19 @@ static GPollFunc old_gpoll = NULL;
static gint gpoll_wrapper( GPollFD*, guint, gint );
#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