[Libreoffice-commits] core.git: vcl/inc vcl/qt5

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Thu May 9 08:39:01 UTC 2019


 vcl/inc/qt5/Qt5Widget.hxx |    3 +++
 vcl/qt5/Qt5Frame.cxx      |    4 +++-
 vcl/qt5/Qt5Widget.cxx     |   38 +++++++++++++++++++++++++++++++-------
 3 files changed, 37 insertions(+), 8 deletions(-)

New commits:
commit c1bcdf9aa5d8ea99435906ffa9787232a909ff0f
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Wed May 8 11:51:15 2019 +0000
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Thu May 9 10:37:47 2019 +0200

    Qt5 IM handle (spurious?) all-empty IM events
    
    2nd attempt to fix the bug described in commit 00221089800c ("Qt5
    IM allow committing empty strings") and various siblings of it.
    This also reverts it.
    
    What I see is calls with "all-empty" events (preedit, commit and
    replacementLength() == 0; no QInputMethodEvent::Attribute), some
    from QIBusPlatformInputContext::updatePreeditText.
    
    There are various Writer document edit states with (selected)
    text, undo, cursor position and focus changes to other windows via
    Ctrl+Tab, which will result in inputMethodEvent calls totally in
    contrast to the expected text state, all somehow always related to
    all-empty events. They currently result in wrongly deleted
    selected text, change of selection, cursor movement or general
    change of text from old preedit. Most time on focus out / window
    change, some times at first meta-key press after focus in.
    
    This patch tries hard not to corrupt Writers edit state with these
    all-empty events. No idea if this is some bug on LO's qt5 side or
    expected, but KDE kate and VCL gtk3 and gen work fine, so I assume
    Qt's behaviour is correct. FWIW gtk3 also does some extended IM
    handling with focus, so probably this is the Qt equivalent of it.
    But then I couldn't find some eqivalent code in Qt's source code.
    I actually expected an even more complex solution (if this really
    fixes all cases).
    
    Works for a multitude of tests I tried to come up with, but is
    quite probably not the final fix to this, as qt5 current doesn't
    handle replacementStart() and replacementLength() at all.
    Also never saw a call to Qt5Frame::EndExtTextInput.
    
    Change-Id: I4210e0588041cfb4d80dbdfdb937e430a5f7cbfb
    Reviewed-on: https://gerrit.libreoffice.org/71988
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/vcl/inc/qt5/Qt5Widget.hxx b/vcl/inc/qt5/Qt5Widget.hxx
index 30998a8a1c6d..8879bc10aef2 100644
--- a/vcl/inc/qt5/Qt5Widget.hxx
+++ b/vcl/inc/qt5/Qt5Widget.hxx
@@ -43,6 +43,7 @@ class Qt5Widget : public QWidget
     Q_OBJECT
 
     Qt5Frame& m_rFrame;
+    bool m_bNonEmptyIMPreeditSeen;
 
     bool handleKeyEvent(QKeyEvent*, bool);
     void handleMouseButtonEvent(QMouseEvent*, bool);
@@ -51,6 +52,7 @@ class Qt5Widget : public QWidget
 
     virtual void focusInEvent(QFocusEvent*) override;
     virtual void focusOutEvent(QFocusEvent*) override;
+    // keyPressEvent(QKeyEvent*) is handled via event(QEvent*); see comment
     virtual void keyReleaseEvent(QKeyEvent*) override;
     virtual void mouseMoveEvent(QMouseEvent*) override;
     virtual void mousePressEvent(QMouseEvent*) override;
@@ -76,6 +78,7 @@ public:
 
     Qt5Frame& getFrame() const { return m_rFrame; }
     void startDrag(sal_Int8 nSourceActions);
+    void endExtTextInput();
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index b07ea360a1cc..07ae9f055bb1 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -723,7 +723,9 @@ void Qt5Frame::SetInputContext(SalInputContext* pContext)
 
 void Qt5Frame::EndExtTextInput(EndExtTextInputFlags /*nFlags*/)
 {
-    // TODO fwd to IM handler
+    Qt5Widget* pQt5Widget = static_cast<Qt5Widget*>(m_pQWidget);
+    if (pQt5Widget)
+        pQt5Widget->endExtTextInput();
 }
 
 OUString Qt5Frame::GetKeyName(sal_uInt16 nKeyCode)
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index 865f36b0a567..a4c01cdede32 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -433,7 +433,11 @@ void Qt5Widget::keyReleaseEvent(QKeyEvent* pEvent)
 
 void Qt5Widget::focusInEvent(QFocusEvent*) { m_rFrame.CallCallback(SalEvent::GetFocus, nullptr); }
 
-void Qt5Widget::focusOutEvent(QFocusEvent*) { m_rFrame.CallCallback(SalEvent::LoseFocus, nullptr); }
+void Qt5Widget::focusOutEvent(QFocusEvent*)
+{
+    endExtTextInput();
+    m_rFrame.CallCallback(SalEvent::LoseFocus, nullptr);
+}
 
 void Qt5Widget::showTooltip(const OUString& rTooltip)
 {
@@ -444,6 +448,7 @@ void Qt5Widget::showTooltip(const OUString& rTooltip)
 Qt5Widget::Qt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f)
     : QWidget(Q_NULLPTR, f)
     , m_rFrame(rFrame)
+    , m_bNonEmptyIMPreeditSeen(false)
 {
     create();
     setMouseTracking(true);
@@ -475,13 +480,14 @@ void Qt5Widget::inputMethodEvent(QInputMethodEvent* pEvent)
     aInputEvent.mpTextAttr = nullptr;
     aInputEvent.mnCursorFlags = 0;
 
-    if (!pEvent->commitString().isNull())
+    vcl::DeletionListener aDel(&m_rFrame);
+
+    if (!pEvent->commitString().isEmpty())
     {
-        vcl::DeletionListener aDel(&m_rFrame);
         aInputEvent.maText = toOUString(pEvent->commitString());
         aInputEvent.mnCursorPos = aInputEvent.maText.getLength();
-        m_rFrame.CallCallback(SalEvent::ExtTextInput, &aInputEvent);
-        pEvent->accept();
+        if (!aDel.isDeleted())
+            m_rFrame.CallCallback(SalEvent::ExtTextInput, &aInputEvent);
         if (!aDel.isDeleted())
             m_rFrame.CallCallback(SalEvent::EndExtTextInput, nullptr);
     }
@@ -531,9 +537,18 @@ void Qt5Widget::inputMethodEvent(QInputMethodEvent* pEvent)
             }
         }
 
-        m_rFrame.CallCallback(SalEvent::ExtTextInput, &aInputEvent);
-        pEvent->accept();
+        const bool bIsEmpty = aInputEvent.maText.isEmpty();
+        if (m_bNonEmptyIMPreeditSeen || !bIsEmpty)
+        {
+            if (!aDel.isDeleted())
+                m_rFrame.CallCallback(SalEvent::ExtTextInput, &aInputEvent);
+            if (!aDel.isDeleted() && bIsEmpty)
+                m_rFrame.CallCallback(SalEvent::EndExtTextInput, nullptr);
+            m_bNonEmptyIMPreeditSeen = !bIsEmpty;
+        }
     }
+
+    pEvent->accept();
 }
 
 QVariant Qt5Widget::inputMethodQuery(Qt::InputMethodQuery property) const
@@ -552,4 +567,13 @@ QVariant Qt5Widget::inputMethodQuery(Qt::InputMethodQuery property) const
     }
 }
 
+void Qt5Widget::endExtTextInput()
+{
+    if (m_bNonEmptyIMPreeditSeen)
+    {
+        m_rFrame.CallCallback(SalEvent::EndExtTextInput, nullptr);
+        m_bNonEmptyIMPreeditSeen = false;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list