diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-10-01 12:30:51 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-10-06 12:42:22 +0200 |
commit | a49a0165bbc7fce216256bc8ee8ca8b0db757c1c (patch) | |
tree | a490e1aeaac37dabf247114463da12618335695e /vcl | |
parent | a9291f02c6eb9aa97a287dd5a99ad4b4d9448572 (diff) |
Related: tdf#134566 split signalIMPreeditChanged to extract a reusable piece
Change-Id: Iff979921629a0e1c8d2b3fbd51a9f2f7270a3d53
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103763
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
(cherry picked from commit 5f0492debf068c62604b936e68191257656ecbde)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103990
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 1 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkframe.cxx | 74 |
2 files changed, 42 insertions, 33 deletions
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index aad22afa85e2..e42e1649a618 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -526,6 +526,7 @@ public: static SalWheelMouseEvent GetWheelEvent(GdkEventScroll& rEvent); static gboolean NativeWidgetHelpPressed(GtkAccelGroup*, GObject*, guint, GdkModifierType, gpointer pFrame); + static OUString GetPreeditDetails(GtkIMContext* pIMContext, std::vector<ExtTextInputAttr>& rInputFlags, sal_Int32& rCursorPos, sal_uInt8& rCursorFlags); }; #define OOO_TYPE_FIXED ooo_fixed_get_type() diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index 803ae198de2e..d818ec137096 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -4112,45 +4112,27 @@ void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* /*pContext*/, gchar* } } -void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_handler ) +OUString GtkSalFrame::GetPreeditDetails(GtkIMContext* pIMContext, std::vector<ExtTextInputAttr>& rInputFlags, sal_Int32& rCursorPos, sal_uInt8& rCursorFlags) { - GtkSalFrame::IMHandler* pThis = static_cast<GtkSalFrame::IMHandler*>(im_handler); - char* pText = nullptr; PangoAttrList* pAttrs = nullptr; gint nCursorPos = 0; - gtk_im_context_get_preedit_string( pThis->m_pIMContext, + gtk_im_context_get_preedit_string( pIMContext, &pText, &pAttrs, &nCursorPos ); - if( pText && ! *pText ) // empty string - { - // change from nothing to nothing -> do not start preedit - // e.g. this will activate input into a calc cell without - // user input - if( pThis->m_aInputEvent.maText.getLength() == 0 ) - { - g_free( pText ); - pango_attr_list_unref( pAttrs ); - return; - } - } - - pThis->m_bPreeditJustChanged = true; - bool bEndPreedit = (!pText || !*pText) && pThis->m_aInputEvent.mpTextAttr != nullptr; gint nUtf8Len = pText ? strlen(pText) : 0; - pThis->m_aInputEvent.maText = pText ? OUString(pText, nUtf8Len, RTL_TEXTENCODING_UTF8) : OUString(); - const OUString& rText = pThis->m_aInputEvent.maText; + OUString sText = pText ? OUString(pText, nUtf8Len, RTL_TEXTENCODING_UTF8) : OUString(); std::vector<sal_Int32> aUtf16Offsets; - for (sal_Int32 nUtf16Offset = 0; nUtf16Offset < rText.getLength(); rText.iterateCodePoints(&nUtf16Offset)) + for (sal_Int32 nUtf16Offset = 0; nUtf16Offset < sText.getLength(); sText.iterateCodePoints(&nUtf16Offset)) aUtf16Offsets.push_back(nUtf16Offset); sal_Int32 nUtf32Len = aUtf16Offsets.size(); // from the above loop filling aUtf16Offsets, we know that its size() fits into sal_Int32 - aUtf16Offsets.push_back(rText.getLength()); + aUtf16Offsets.push_back(sText.getLength()); // sanitize the CurPos which is in utf-32 if (nCursorPos < 0) @@ -4158,10 +4140,10 @@ void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_ else if (nCursorPos > nUtf32Len) nCursorPos = nUtf32Len; - pThis->m_aInputEvent.mnCursorPos = aUtf16Offsets[nCursorPos]; - pThis->m_aInputEvent.mnCursorFlags = 0; + rCursorPos = aUtf16Offsets[nCursorPos]; + rCursorFlags = 0; - pThis->m_aInputFlags = std::vector<ExtTextInputAttr>( std::max( 1, static_cast<int>(rText.getLength()) ), ExtTextInputAttr::NONE ); + rInputFlags.resize(std::max(1, static_cast<int>(sText.getLength())), ExtTextInputAttr::NONE); PangoAttrIterator *iter = pango_attr_list_get_iterator(pAttrs); do @@ -4204,7 +4186,7 @@ void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_ { case PANGO_ATTR_BACKGROUND: sal_attr |= ExtTextInputAttr::Highlight; - pThis->m_aInputEvent.mnCursorFlags |= EXTTEXTINPUT_CURSOR_INVISIBLE; + rCursorFlags |= EXTTEXTINPUT_CURSOR_INVISIBLE; break; case PANGO_ATTR_UNDERLINE: sal_attr |= ExtTextInputAttr::Underline; @@ -4226,22 +4208,48 @@ void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_ // rhbz#1648281 apply over our utf-16 range derived from the input utf-32 range for (sal_Int32 i = aUtf16Offsets[nUtf32Start]; i < aUtf16Offsets[nUtf32End]; ++i) { - SAL_WARN_IF(i >= static_cast<int>(pThis->m_aInputFlags.size()), + SAL_WARN_IF(i >= static_cast<int>(rInputFlags.size()), "vcl.gtk3", "pango attrib out of range. Broken range: " << aUtf16Offsets[nUtf32Start] << "," << aUtf16Offsets[nUtf32End] << " Legal range: 0," - << pThis->m_aInputFlags.size()); - if (i >= static_cast<int>(pThis->m_aInputFlags.size())) + << rInputFlags.size()); + if (i >= static_cast<int>(rInputFlags.size())) continue; - pThis->m_aInputFlags[i] |= sal_attr; + rInputFlags[i] |= sal_attr; } } while (pango_attr_iterator_next (iter)); pango_attr_iterator_destroy(iter); - pThis->m_aInputEvent.mpTextAttr = pThis->m_aInputFlags.data(); - g_free( pText ); pango_attr_list_unref( pAttrs ); + return sText; +} + +void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext* pIMContext, gpointer im_handler ) +{ + GtkSalFrame::IMHandler* pThis = static_cast<GtkSalFrame::IMHandler*>(im_handler); + + sal_Int32 nCursorPos(0); + sal_uInt8 nCursorFlags(0); + std::vector<ExtTextInputAttr> aInputFlags; + OUString sText = GtkSalFrame::GetPreeditDetails(pIMContext, aInputFlags, nCursorPos, nCursorFlags); + if (sText.isEmpty() && pThis->m_aInputEvent.maText.isEmpty()) + { + // change from nothing to nothing -> do not start preedit + // e.g. this will activate input into a calc cell without + // user input + return; + } + + pThis->m_bPreeditJustChanged = true; + + bool bEndPreedit = sText.isEmpty() && pThis->m_aInputEvent.mpTextAttr != nullptr; + pThis->m_aInputEvent.maText = sText; + pThis->m_aInputEvent.mnCursorPos = nCursorPos; + pThis->m_aInputEvent.mnCursorFlags = nCursorFlags; + pThis->m_aInputFlags = aInputFlags; + pThis->m_aInputEvent.mpTextAttr = pThis->m_aInputFlags.data(); + SolarMutexGuard aGuard; vcl::DeletionListener aDel( pThis->m_pFrame ); |