diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2022-10-25 14:42:06 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2022-10-25 17:28:38 +0200 |
commit | 2c05c6ead206659b1cbd7b794aa81e87694a251a (patch) | |
tree | 66b1b64cbd39a2db286cfd9da6a46603fc627ae1 /vcl/unx/gtk3/gtkinst.cxx | |
parent | 51d366712c55c61bea5169c238098d7007e4ce20 (diff) |
Address a constexpr template point of instantiation issue
...that hits at least when building with Clang and --with-latest-c++ against
recent libc++ or MSVC standard library (where C++20 and esp. C++23 made more and
more class template member functions constexpr). My understanding is that there
is some leeway at what point a compiler should instantiate such function
specializations, and Clang decides to instantiate constexpr ones early (cf.
<https://github.com/llvm/llvm-project/commit/242ad89a15d5466d166d47978bfff983d40ab511>
"C++11 half of r147023: In C++11, additionally eagerly instantiate:" and its "Do
not defer instantiations of constexpr functions" comment, and the discussion at
<https://discourse.llvm.org/t/point-of-instantiation-of-constexpr-function-template/65129>).
> In file included from vcl/unx/gtk3/gtkinst.cxx:12:
> In file included from ~/llvm/inst/bin/../include/c++/v1/deque:181:
> ~/llvm/inst/bin/../include/c++/v1/__memory/unique_ptr.h:47:19: error: invalid application of 'sizeof' to an incomplete type '(anonymous namespace)::IMHandler'
> static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type");
> ^~~~~~~~~~~
> ~/llvm/inst/bin/../include/c++/v1/__memory/unique_ptr.h:281:7: note: in instantiation of member function 'std::default_delete<(anonymous namespace)::IMHandler>::operator()' requested here
> __ptr_.second()(__tmp);
> ^
> ~/llvm/inst/bin/../include/c++/v1/__memory/unique_ptr.h:247:75: note: in instantiation of member function 'std::unique_ptr<(anonymous namespace)::IMHandler>::reset' requested here
> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
> ^
> vcl/unx/gtk3/gtkinst.cxx:18108:5: note: in instantiation of member function 'std::unique_ptr<(anonymous namespace)::IMHandler>::~unique_ptr' requested here
> GtkInstanceDrawingArea(GtkDrawingArea* pDrawingArea, GtkInstanceBuilder* pBuilder, a11yref xA11y, bool bTakeOwnership)
> ^
> vcl/unx/gtk3/gtkinst.cxx:17947:7: note: forward declaration of '(anonymous namespace)::IMHandler'
> class IMHandler;
> ^
Change-Id: I555fc974762ba75f28705a3c4673956db275009f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141823
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'vcl/unx/gtk3/gtkinst.cxx')
-rw-r--r-- | vcl/unx/gtk3/gtkinst.cxx | 403 |
1 files changed, 223 insertions, 180 deletions
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 9f012a86c39d..3ba69b9fdb53 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -17960,8 +17960,66 @@ public: namespace { +class GtkInstanceDrawingArea; + // IMHandler -class IMHandler; +class IMHandler +{ +private: + GtkInstanceDrawingArea* m_pArea; +#if GTK_CHECK_VERSION(4, 0, 0) + GtkEventController* m_pFocusController; +#endif + GtkIMContext* m_pIMContext; + OUString m_sPreeditText; + gulong m_nFocusInSignalId; + gulong m_nFocusOutSignalId; + bool m_bExtTextInput; + +public: + IMHandler(GtkInstanceDrawingArea* pArea); + + void signalFocus(bool bIn); + +#if GTK_CHECK_VERSION(4, 0, 0) + static void signalFocusIn(GtkEventControllerFocus*, gpointer im_handler); +#else + static gboolean signalFocusIn(GtkWidget*, GdkEvent*, gpointer im_handler); +#endif + +#if GTK_CHECK_VERSION(4, 0, 0) + static void signalFocusOut(GtkEventControllerFocus*, gpointer im_handler); +#else + static gboolean signalFocusOut(GtkWidget*, GdkEvent*, gpointer im_handler); +#endif + + ~IMHandler(); + + void updateIMSpotLocation(); + + void set_cursor_location(const tools::Rectangle& rRect); + + static void signalIMCommit(GtkIMContext* /*pContext*/, gchar* pText, gpointer im_handler); + + static void signalIMPreeditChanged(GtkIMContext* pIMContext, gpointer im_handler); + + static gboolean signalIMRetrieveSurrounding(GtkIMContext* pContext, gpointer im_handler); + + static gboolean signalIMDeleteSurrounding(GtkIMContext*, gint nOffset, gint nChars, + gpointer im_handler); + + void StartExtTextInput(); + + static void signalIMPreeditStart(GtkIMContext*, gpointer im_handler); + + void EndExtTextInput(); + + static void signalIMPreeditEnd(GtkIMContext*, gpointer im_handler); + +#if !GTK_CHECK_VERSION(4, 0, 0) + bool im_context_filter_keypress(const GdkEventKey* pEvent); +#endif +}; #if !GTK_CHECK_VERSION(4, 0, 0) AtkObject* (*default_drawing_area_get_accessible)(GtkWidget *widget); @@ -18382,246 +18440,231 @@ IMPL_LINK(GtkInstanceDrawingArea, SettingsChangedHdl, VclWindowEvent&, rEvent, v signal_style_updated(); } -class IMHandler +IMHandler::IMHandler(GtkInstanceDrawingArea* pArea) + : m_pArea(pArea) + , m_pIMContext(gtk_im_multicontext_new()) + , m_bExtTextInput(false) { -private: - GtkInstanceDrawingArea* m_pArea; -#if GTK_CHECK_VERSION(4, 0, 0) - GtkEventController* m_pFocusController; -#endif - GtkIMContext* m_pIMContext; - OUString m_sPreeditText; - gulong m_nFocusInSignalId; - gulong m_nFocusOutSignalId; - bool m_bExtTextInput; - -public: - IMHandler(GtkInstanceDrawingArea* pArea) - : m_pArea(pArea) - , m_pIMContext(gtk_im_multicontext_new()) - , m_bExtTextInput(false) - { - GtkWidget* pWidget = m_pArea->getWidget(); + GtkWidget* pWidget = m_pArea->getWidget(); #if GTK_CHECK_VERSION(4, 0, 0) - m_pFocusController = gtk_event_controller_focus_new(); - gtk_widget_add_controller(pWidget, m_pFocusController); + m_pFocusController = gtk_event_controller_focus_new(); + gtk_widget_add_controller(pWidget, m_pFocusController); - m_nFocusInSignalId = g_signal_connect(m_pFocusController, "enter", G_CALLBACK(signalFocusIn), this); - m_nFocusOutSignalId = g_signal_connect(m_pFocusController, "leave", G_CALLBACK(signalFocusOut), this); + m_nFocusInSignalId = g_signal_connect(m_pFocusController, "enter", G_CALLBACK(signalFocusIn), this); + m_nFocusOutSignalId = g_signal_connect(m_pFocusController, "leave", G_CALLBACK(signalFocusOut), this); #else - m_nFocusInSignalId = g_signal_connect(pWidget, "focus-in-event", G_CALLBACK(signalFocusIn), this); - m_nFocusOutSignalId = g_signal_connect(pWidget, "focus-out-event", G_CALLBACK(signalFocusOut), this); + m_nFocusInSignalId = g_signal_connect(pWidget, "focus-in-event", G_CALLBACK(signalFocusIn), this); + m_nFocusOutSignalId = g_signal_connect(pWidget, "focus-out-event", G_CALLBACK(signalFocusOut), this); #endif - g_signal_connect(m_pIMContext, "preedit-start", G_CALLBACK(signalIMPreeditStart), this); - g_signal_connect(m_pIMContext, "preedit-end", G_CALLBACK(signalIMPreeditEnd), this); - g_signal_connect(m_pIMContext, "commit", G_CALLBACK(signalIMCommit), this); - g_signal_connect(m_pIMContext, "preedit-changed", G_CALLBACK(signalIMPreeditChanged), this); - g_signal_connect(m_pIMContext, "retrieve-surrounding", G_CALLBACK(signalIMRetrieveSurrounding), this); - g_signal_connect(m_pIMContext, "delete-surrounding", G_CALLBACK(signalIMDeleteSurrounding), this); + g_signal_connect(m_pIMContext, "preedit-start", G_CALLBACK(signalIMPreeditStart), this); + g_signal_connect(m_pIMContext, "preedit-end", G_CALLBACK(signalIMPreeditEnd), this); + g_signal_connect(m_pIMContext, "commit", G_CALLBACK(signalIMCommit), this); + g_signal_connect(m_pIMContext, "preedit-changed", G_CALLBACK(signalIMPreeditChanged), this); + g_signal_connect(m_pIMContext, "retrieve-surrounding", G_CALLBACK(signalIMRetrieveSurrounding), this); + g_signal_connect(m_pIMContext, "delete-surrounding", G_CALLBACK(signalIMDeleteSurrounding), this); - if (!gtk_widget_get_realized(pWidget)) - gtk_widget_realize(pWidget); - im_context_set_client_widget(m_pIMContext, pWidget); - if (gtk_widget_has_focus(m_pArea->getWidget())) - gtk_im_context_focus_in(m_pIMContext); - } + if (!gtk_widget_get_realized(pWidget)) + gtk_widget_realize(pWidget); + im_context_set_client_widget(m_pIMContext, pWidget); + if (gtk_widget_has_focus(m_pArea->getWidget())) + gtk_im_context_focus_in(m_pIMContext); +} - void signalFocus(bool bIn) - { - if (bIn) - gtk_im_context_focus_in(m_pIMContext); - else - gtk_im_context_focus_out(m_pIMContext); - } +void IMHandler::signalFocus(bool bIn) +{ + if (bIn) + gtk_im_context_focus_in(m_pIMContext); + else + gtk_im_context_focus_out(m_pIMContext); +} #if GTK_CHECK_VERSION(4, 0, 0) - static void signalFocusIn(GtkEventControllerFocus*, gpointer im_handler) +void IMHandler::signalFocusIn(GtkEventControllerFocus*, gpointer im_handler) #else - static gboolean signalFocusIn(GtkWidget*, GdkEvent*, gpointer im_handler) +gboolean IMHandler::signalFocusIn(GtkWidget*, GdkEvent*, gpointer im_handler) #endif - { - IMHandler* pThis = static_cast<IMHandler*>(im_handler); - pThis->signalFocus(true); +{ + IMHandler* pThis = static_cast<IMHandler*>(im_handler); + pThis->signalFocus(true); #if !GTK_CHECK_VERSION(4, 0, 0) - return false; + return false; #endif - } +} #if GTK_CHECK_VERSION(4, 0, 0) - static void signalFocusOut(GtkEventControllerFocus*, gpointer im_handler) +void IMHandler::signalFocusOut(GtkEventControllerFocus*, gpointer im_handler) #else - static gboolean signalFocusOut(GtkWidget*, GdkEvent*, gpointer im_handler) +gboolean IMHandler::signalFocusOut(GtkWidget*, GdkEvent*, gpointer im_handler) #endif - { - IMHandler* pThis = static_cast<IMHandler*>(im_handler); - pThis->signalFocus(false); +{ + IMHandler* pThis = static_cast<IMHandler*>(im_handler); + pThis->signalFocus(false); #if !GTK_CHECK_VERSION(4, 0, 0) - return false; + return false; #endif - } +} - ~IMHandler() - { - EndExtTextInput(); +IMHandler::~IMHandler() +{ + EndExtTextInput(); #if GTK_CHECK_VERSION(4, 0, 0) - g_signal_handler_disconnect(m_pFocusController, m_nFocusOutSignalId); - g_signal_handler_disconnect(m_pFocusController, m_nFocusInSignalId); + g_signal_handler_disconnect(m_pFocusController, m_nFocusOutSignalId); + g_signal_handler_disconnect(m_pFocusController, m_nFocusInSignalId); #else - g_signal_handler_disconnect(m_pArea->getWidget(), m_nFocusOutSignalId); - g_signal_handler_disconnect(m_pArea->getWidget(), m_nFocusInSignalId); + g_signal_handler_disconnect(m_pArea->getWidget(), m_nFocusOutSignalId); + g_signal_handler_disconnect(m_pArea->getWidget(), m_nFocusInSignalId); #endif - if (gtk_widget_has_focus(m_pArea->getWidget())) - gtk_im_context_focus_out(m_pIMContext); - - // first give IC a chance to deinitialize - im_context_set_client_widget(m_pIMContext, nullptr); - // destroy old IC - g_object_unref(m_pIMContext); - } + if (gtk_widget_has_focus(m_pArea->getWidget())) + gtk_im_context_focus_out(m_pIMContext); - void updateIMSpotLocation() - { - CommandEvent aCEvt(Point(), CommandEventId::CursorPos); - // we expect set_cursor_location to get triggered by this - m_pArea->signal_command(aCEvt); - } + // first give IC a chance to deinitialize + im_context_set_client_widget(m_pIMContext, nullptr); + // destroy old IC + g_object_unref(m_pIMContext); +} - void set_cursor_location(const tools::Rectangle& rRect) - { - GdkRectangle aArea{static_cast<int>(rRect.Left()), static_cast<int>(rRect.Top()), - static_cast<int>(rRect.GetWidth()), static_cast<int>(rRect.GetHeight())}; - gtk_im_context_set_cursor_location(m_pIMContext, &aArea); - } +void IMHandler::updateIMSpotLocation() +{ + CommandEvent aCEvt(Point(), CommandEventId::CursorPos); + // we expect set_cursor_location to get triggered by this + m_pArea->signal_command(aCEvt); +} - static void signalIMCommit(GtkIMContext* /*pContext*/, gchar* pText, gpointer im_handler) - { - IMHandler* pThis = static_cast<IMHandler*>(im_handler); +void IMHandler::set_cursor_location(const tools::Rectangle& rRect) +{ + GdkRectangle aArea{static_cast<int>(rRect.Left()), static_cast<int>(rRect.Top()), + static_cast<int>(rRect.GetWidth()), static_cast<int>(rRect.GetHeight())}; + gtk_im_context_set_cursor_location(m_pIMContext, &aArea); +} - SolarMutexGuard aGuard; +void IMHandler::signalIMCommit(GtkIMContext* /*pContext*/, gchar* pText, gpointer im_handler) +{ + IMHandler* pThis = static_cast<IMHandler*>(im_handler); - // at least editeng expects to have seen a start before accepting a commit - pThis->StartExtTextInput(); + SolarMutexGuard aGuard; - OUString sText(pText, strlen(pText), RTL_TEXTENCODING_UTF8); - CommandExtTextInputData aData(sText, nullptr, sText.getLength(), 0, false); - CommandEvent aCEvt(Point(), CommandEventId::ExtTextInput, false, &aData); - pThis->m_pArea->signal_command(aCEvt); + // at least editeng expects to have seen a start before accepting a commit + pThis->StartExtTextInput(); - pThis->updateIMSpotLocation(); + OUString sText(pText, strlen(pText), RTL_TEXTENCODING_UTF8); + CommandExtTextInputData aData(sText, nullptr, sText.getLength(), 0, false); + CommandEvent aCEvt(Point(), CommandEventId::ExtTextInput, false, &aData); + pThis->m_pArea->signal_command(aCEvt); - pThis->EndExtTextInput(); + pThis->updateIMSpotLocation(); - pThis->m_sPreeditText.clear(); - } + pThis->EndExtTextInput(); - static void signalIMPreeditChanged(GtkIMContext* pIMContext, gpointer im_handler) - { - IMHandler* pThis = static_cast<IMHandler*>(im_handler); + pThis->m_sPreeditText.clear(); +} - SolarMutexGuard aGuard; +void IMHandler::signalIMPreeditChanged(GtkIMContext* pIMContext, gpointer im_handler) +{ + IMHandler* pThis = static_cast<IMHandler*>(im_handler); - sal_Int32 nCursorPos(0); - sal_uInt8 nCursorFlags(0); - std::vector<ExtTextInputAttr> aInputFlags; - OUString sText = GtkSalFrame::GetPreeditDetails(pIMContext, aInputFlags, nCursorPos, nCursorFlags); + SolarMutexGuard aGuard; - // change from nothing to nothing -> do not start preedit e.g. this - // will activate input into a calc cell without user input - if (sText.isEmpty() && pThis->m_sPreeditText.isEmpty()) - return; + sal_Int32 nCursorPos(0); + sal_uInt8 nCursorFlags(0); + std::vector<ExtTextInputAttr> aInputFlags; + OUString sText = GtkSalFrame::GetPreeditDetails(pIMContext, aInputFlags, nCursorPos, nCursorFlags); - pThis->m_sPreeditText = sText; + // change from nothing to nothing -> do not start preedit e.g. this + // will activate input into a calc cell without user input + if (sText.isEmpty() && pThis->m_sPreeditText.isEmpty()) + return; - CommandExtTextInputData aData(sText, aInputFlags.data(), nCursorPos, nCursorFlags, false); - CommandEvent aCEvt(Point(), CommandEventId::ExtTextInput, false, &aData); - pThis->m_pArea->signal_command(aCEvt); + pThis->m_sPreeditText = sText; - pThis->updateIMSpotLocation(); - } + CommandExtTextInputData aData(sText, aInputFlags.data(), nCursorPos, nCursorFlags, false); + CommandEvent aCEvt(Point(), CommandEventId::ExtTextInput, false, &aData); + pThis->m_pArea->signal_command(aCEvt); - static gboolean signalIMRetrieveSurrounding(GtkIMContext* pContext, gpointer im_handler) - { - IMHandler* pThis = static_cast<IMHandler*>(im_handler); + pThis->updateIMSpotLocation(); +} - SolarMutexGuard aGuard; +gboolean IMHandler::signalIMRetrieveSurrounding(GtkIMContext* pContext, gpointer im_handler) +{ + IMHandler* pThis = static_cast<IMHandler*>(im_handler); - OUString sSurroundingText; - int nCursorIndex = pThis->m_pArea->im_context_get_surrounding(sSurroundingText); + SolarMutexGuard aGuard; - if (nCursorIndex != -1) - { - OString sUTF = OUStringToOString(sSurroundingText, RTL_TEXTENCODING_UTF8); - std::u16string_view sCursorText(sSurroundingText.subView(0, nCursorIndex)); - gtk_im_context_set_surrounding(pContext, sUTF.getStr(), sUTF.getLength(), - OUStringToOString(sCursorText, RTL_TEXTENCODING_UTF8).getLength()); - } + OUString sSurroundingText; + int nCursorIndex = pThis->m_pArea->im_context_get_surrounding(sSurroundingText); - return true; + if (nCursorIndex != -1) + { + OString sUTF = OUStringToOString(sSurroundingText, RTL_TEXTENCODING_UTF8); + std::u16string_view sCursorText(sSurroundingText.subView(0, nCursorIndex)); + gtk_im_context_set_surrounding(pContext, sUTF.getStr(), sUTF.getLength(), + OUStringToOString(sCursorText, RTL_TEXTENCODING_UTF8).getLength()); } - static gboolean signalIMDeleteSurrounding(GtkIMContext*, gint nOffset, gint nChars, - gpointer im_handler) - { - bool bRet = false; + return true; +} - IMHandler* pThis = static_cast<IMHandler*>(im_handler); +gboolean IMHandler::signalIMDeleteSurrounding(GtkIMContext*, gint nOffset, gint nChars, + gpointer im_handler) +{ + bool bRet = false; - SolarMutexGuard aGuard; + IMHandler* pThis = static_cast<IMHandler*>(im_handler); - OUString sSurroundingText; - sal_Int32 nCursorIndex = pThis->m_pArea->im_context_get_surrounding(sSurroundingText); + SolarMutexGuard aGuard; - Selection aSelection = SalFrame::CalcDeleteSurroundingSelection(sSurroundingText, nCursorIndex, nOffset, nChars); - if (aSelection != Selection(SAL_MAX_UINT32, SAL_MAX_UINT32)) - bRet = pThis->m_pArea->im_context_delete_surrounding(aSelection); - return bRet; - } + OUString sSurroundingText; + sal_Int32 nCursorIndex = pThis->m_pArea->im_context_get_surrounding(sSurroundingText); - void StartExtTextInput() - { - if (m_bExtTextInput) - return; - CommandEvent aCEvt(Point(), CommandEventId::StartExtTextInput); - m_pArea->signal_command(aCEvt); - m_bExtTextInput = true; - } + Selection aSelection = SalFrame::CalcDeleteSurroundingSelection(sSurroundingText, nCursorIndex, nOffset, nChars); + if (aSelection != Selection(SAL_MAX_UINT32, SAL_MAX_UINT32)) + bRet = pThis->m_pArea->im_context_delete_surrounding(aSelection); + return bRet; +} - static void signalIMPreeditStart(GtkIMContext*, gpointer im_handler) - { - IMHandler* pThis = static_cast<IMHandler*>(im_handler); - SolarMutexGuard aGuard; - pThis->StartExtTextInput(); - pThis->updateIMSpotLocation(); - } +void IMHandler::StartExtTextInput() +{ + if (m_bExtTextInput) + return; + CommandEvent aCEvt(Point(), CommandEventId::StartExtTextInput); + m_pArea->signal_command(aCEvt); + m_bExtTextInput = true; +} - void EndExtTextInput() - { - if (!m_bExtTextInput) - return; - CommandEvent aCEvt(Point(), CommandEventId::EndExtTextInput); - m_pArea->signal_command(aCEvt); - m_bExtTextInput = false; - } +void IMHandler::signalIMPreeditStart(GtkIMContext*, gpointer im_handler) +{ + IMHandler* pThis = static_cast<IMHandler*>(im_handler); + SolarMutexGuard aGuard; + pThis->StartExtTextInput(); + pThis->updateIMSpotLocation(); +} - static void signalIMPreeditEnd(GtkIMContext*, gpointer im_handler) - { - IMHandler* pThis = static_cast<IMHandler*>(im_handler); - SolarMutexGuard aGuard; - pThis->updateIMSpotLocation(); - pThis->EndExtTextInput(); - } +void IMHandler::EndExtTextInput() +{ + if (!m_bExtTextInput) + return; + CommandEvent aCEvt(Point(), CommandEventId::EndExtTextInput); + m_pArea->signal_command(aCEvt); + m_bExtTextInput = false; +} + +void IMHandler::signalIMPreeditEnd(GtkIMContext*, gpointer im_handler) +{ + IMHandler* pThis = static_cast<IMHandler*>(im_handler); + SolarMutexGuard aGuard; + pThis->updateIMSpotLocation(); + pThis->EndExtTextInput(); +} #if !GTK_CHECK_VERSION(4, 0, 0) - bool im_context_filter_keypress(const GdkEventKey* pEvent) - { - return gtk_im_context_filter_keypress(m_pIMContext, const_cast<GdkEventKey*>(pEvent)); - } +bool IMHandler::im_context_filter_keypress(const GdkEventKey* pEvent) +{ + return gtk_im_context_filter_keypress(m_pIMContext, const_cast<GdkEventKey*>(pEvent)); +} #endif -}; #if !GTK_CHECK_VERSION(4, 0, 0) bool GtkInstanceDrawingArea::do_signal_key_press(const GdkEventKey* pEvent) |