vcl/inc/unx/gtk/gtkframe.hxx | 1 vcl/unx/gtk3/gtkframe.cxx | 79 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 70 insertions(+), 10 deletions(-)
New commits: commit d19397ea3fe742d81251382c61608ea93a42ce74 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Tue May 11 11:36:35 2021 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Tue May 11 14:39:25 2021 +0200 gtk4: add basic Input Engine support old hack to emulate single key press events not supported (yet?) Change-Id: I0de44fab76d0fa82f7586a6712b1f4a469550c45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115395 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index f80e6f068edf..4d440119a6b3 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -180,6 +180,7 @@ class GtkSalFrame final : public SalFrame GtkFixed* m_pFixedContainer; #else GtkDrawingArea* m_pFixedContainer; + GtkEventControllerKey* m_pKeyController; #endif #if !GTK_CHECK_VERSION(4, 0, 0) GdkWindow* m_pForeignParent; diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx index 718140d0ac86..1838652ebd3d 100644 --- a/vcl/unx/gtk3/gtkframe.cxx +++ b/vcl/unx/gtk3/gtkframe.cxx @@ -1031,10 +1031,10 @@ void GtkSalFrame::InitCommon() g_signal_connect( G_OBJECT(m_pWindow), "key-press-event", G_CALLBACK(signalKey), this ); g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this ); #else - GtkEventController* pKeyController = gtk_event_controller_key_new(); - g_signal_connect(pKeyController, "key-pressed", G_CALLBACK(signalKeyPressed), this); - g_signal_connect(pKeyController, "key-released", G_CALLBACK(signalKeyReleased), this); - gtk_widget_add_controller(pEventWidget, pKeyController); + m_pKeyController = GTK_EVENT_CONTROLLER_KEY(gtk_event_controller_key_new()); + g_signal_connect(m_pKeyController, "key-pressed", G_CALLBACK(signalKeyPressed), this); + g_signal_connect(m_pKeyController, "key-released", G_CALLBACK(signalKeyReleased), this); + gtk_widget_add_controller(pEventWidget, GTK_EVENT_CONTROLLER(m_pKeyController)); #endif g_signal_connect( G_OBJECT(m_pWindow), "destroy", G_CALLBACK(signalDestroy), this ); @@ -3910,11 +3910,6 @@ bool GtkSalFrame::DrawingAreaKey(SalEvent nEventType, guint keyval, guint keycod { UpdateLastInputEventTime(nTime); -#if 0 - if (m_pIMHandler && m_pIMHandler->handleKeyEvent(pEvent)) - return true; -#endif - vcl::DeletionListener aDel(this); bool bStopProcessingKey = false; @@ -4573,6 +4568,7 @@ void GtkSalFrame::IMHandler::createIMContext() GetGenericUnixSalData()->ErrorTrapPush(); #if GTK_CHECK_VERSION(4, 0, 0) gtk_im_context_set_client_widget(m_pIMContext, m_pFrame->getMouseEventWidget()); + gtk_event_controller_key_set_im_context(m_pFrame->m_pKeyController, m_pIMContext); #else gtk_im_context_set_client_window(m_pIMContext, gtk_widget_get_window(m_pFrame->getMouseEventWidget())); #endif @@ -4590,6 +4586,7 @@ void GtkSalFrame::IMHandler::deleteIMContext() GetGenericUnixSalData()->ErrorTrapPush(); #if GTK_CHECK_VERSION(4, 0, 0) gtk_im_context_set_client_widget(m_pIMContext, nullptr); + gtk_event_controller_key_set_im_context(m_pFrame->m_pKeyController, nullptr); #else gtk_im_context_set_client_window(m_pIMContext, nullptr); #endif @@ -4856,8 +4853,70 @@ void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* /*pContext*/, gchar* } } #else -void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* /*pContext*/, gchar* /*pText*/, gpointer /*im_handler*/ ) +void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* /*pContext*/, gchar* pText, gpointer im_handler ) { + GtkSalFrame::IMHandler* pThis = static_cast<GtkSalFrame::IMHandler*>(im_handler); + + SolarMutexGuard aGuard; + vcl::DeletionListener aDel( pThis->m_pFrame ); + { +#if 0 + const bool bWasPreedit = + (pThis->m_aInputEvent.mpTextAttr != nullptr) || + pThis->m_bPreeditJustChanged; +#endif + + pThis->m_aInputEvent.mpTextAttr = nullptr; + pThis->m_aInputEvent.maText = OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ); + pThis->m_aInputEvent.mnCursorPos = pThis->m_aInputEvent.maText.getLength(); + pThis->m_aInputEvent.mnCursorFlags = 0; + + pThis->m_aInputFlags.clear(); + + /* necessary HACK: all keyboard input comes in here as soon as an IMContext is set + * which is logical and consequent. But since even simple input like + * <space> comes through the commit signal instead of signalKey + * and all kinds of windows only implement KeyInput (e.g. PushButtons, + * RadioButtons and a lot of other Controls), will send a single + * KeyInput/KeyUp sequence instead of an ExtText event if there + * never was a preedit and the text is only one character. + * + * In this case there the last ExtText event must have been + * SalEvent::EndExtTextInput, either because of a regular commit + * or because there never was a preedit. + */ + bool bSingleCommit = false; +#if 0 + // TODO this needs a rethink to work again if necessary + if( ! bWasPreedit + && pThis->m_aInputEvent.maText.getLength() == 1 + && ! pThis->m_aPrevKeyPresses.empty() + ) + { + const PreviousKeyPress& rKP = pThis->m_aPrevKeyPresses.back(); + sal_Unicode aOrigCode = pThis->m_aInputEvent.maText[0]; + + if( checkSingleKeyCommitHack( rKP.keyval, aOrigCode ) ) + { + pThis->m_pFrame->doKeyCallback( rKP.state, rKP.keyval, rKP.hardware_keycode, rKP.group, aOrigCode, true, true ); + bSingleCommit = true; + } + } +#endif + if( ! bSingleCommit ) + { + pThis->m_pFrame->CallCallbackExc( SalEvent::ExtTextInput, static_cast<void*>(&pThis->m_aInputEvent)); + if( ! aDel.isDeleted() ) + pThis->doCallEndExtTextInput(); + } + if( ! aDel.isDeleted() ) + { + // reset input event + pThis->m_aInputEvent.maText.clear(); + pThis->m_aInputEvent.mnCursorPos = 0; + pThis->updateIMSpotLocation(); + } + } } #endif _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits