[Libreoffice-commits] .: 2 commits - vcl/unx

Lubos Lunak llunak at kemper.freedesktop.org
Tue Feb 22 07:33:39 PST 2011


 vcl/unx/kde4/KDESalDisplay.cxx  |   26 +++++++++++++++++++++++
 vcl/unx/kde4/KDESalDisplay.hxx  |    2 +
 vcl/unx/kde4/KDESalGraphics.cxx |   44 +++++++++++++++++++++++++++++++++++++---
 vcl/unx/kde4/KDEXLib.cxx        |   11 ++++++++++
 4 files changed, 80 insertions(+), 3 deletions(-)

New commits:
commit 871595f09d0b63997f098d6a8b9d457db989c158
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Feb 22 16:31:11 2011 +0100

    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.

diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx
index b1eb0d6..2524295 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 1a79c86..25a8b9f 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 8afc0eb..51c3295 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
commit 882e85cd8aabc28abdcbfb2dbf2bc6b54e868190
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Feb 22 16:11:10 2011 +0100

    report properly button positions in Qt scrollbars (bnc#550828)

diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 57db700..2978a64 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -156,10 +156,48 @@ BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart par
     return false;
 }
 
-BOOL KDESalGraphics::hitTestNativeControl( ControlType, ControlPart,
-                                           const Rectangle&, const Point&,
-                                           BOOL& )
+/** Test whether the position is in the native widget.
+    If the return value is TRUE, bIsInside contains information whether
+    aPos was or was not inside the native widget specified by the
+    nType/nPart combination.
+*/
+BOOL KDESalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart,
+                                           const Rectangle& rControlRegion, const Point& rPos,
+                                           BOOL& rIsInside )
 {
+    if ( nType == CTRL_SCROLLBAR )
+    {
+        if( nPart != PART_BUTTON_UP && nPart != PART_BUTTON_DOWN
+            && nPart != PART_BUTTON_LEFT && nPart != PART_BUTTON_RIGHT )
+        { // we adjust only for buttons (because some scrollbars have 3 buttons)
+            return FALSE;
+        }
+        rIsInside = FALSE;
+        bool bHorizontal = ( nPart == PART_BUTTON_LEFT || nPart == PART_BUTTON_RIGHT );
+        QRect rect = region2QRect( rControlRegion );
+        QPoint pos( rPos.X(), rPos.Y());
+        // Adjust coordinates to make the widget appear to be at (0,0), i.e. make
+        // widget and screen coordinates the same. QStyle functions should use screen
+        // coordinates but at least QPlastiqueStyle::subControlRect() is buggy
+        // and sometimes uses widget coordinates.
+        pos -= rect.topLeft();
+        rect.moveTo( 0, 0 );
+        QStyleOptionSlider options;
+        options.orientation = bHorizontal ? Qt::Horizontal : Qt::Vertical;
+        options.rect = rect;
+        // some random sensible values, since we call this code only for scrollbar buttons,
+        // the slider position does not exactly matter
+        options.maximum = 10;
+        options.minimum = 0;
+        options.sliderPosition = options.sliderValue = 4;
+        options.pageStep = 2;
+        QStyle::SubControl control = kapp->style()->hitTestComplexControl( QStyle::CC_ScrollBar, &options, pos );
+        if( nPart == PART_BUTTON_UP || nPart == PART_BUTTON_LEFT )
+            rIsInside = ( control == QStyle::SC_ScrollBarSubLine );
+        else // DOWN, RIGHT
+            rIsInside = ( control == QStyle::SC_ScrollBarAddLine );
+        return TRUE;
+    }
     return FALSE;
 }
 


More information about the Libreoffice-commits mailing list