From ad8535477cee8865bd3fc98248a04ca5ea3866d1 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 16 Mar 2016 13:47:49 +0900 Subject: [PATCH] Bug 1137565 part.2 IMContextWrapper should use TextEventDispatcher r=m_kato --- widget/gtk/IMContextWrapper.cpp | 125 ++++++++++++++++++++++---------- widget/gtk/IMContextWrapper.h | 2 + 2 files changed, 88 insertions(+), 39 deletions(-) diff --git a/widget/gtk/IMContextWrapper.cpp b/widget/gtk/IMContextWrapper.cpp index b01d9ceee5d2..a15a3754fe8f 100644 --- a/widget/gtk/IMContextWrapper.cpp +++ b/widget/gtk/IMContextWrapper.cpp @@ -330,6 +330,19 @@ IMContextWrapper::WillDispatchKeyboardEvent( // TODO: Implement this in the following patch. } +TextEventDispatcher* +IMContextWrapper::GetTextEventDispatcher() +{ + if (NS_WARN_IF(!mLastFocusedWindow)) { + return nullptr; + } + TextEventDispatcher* dispatcher = + mLastFocusedWindow->GetTextEventDispatcher(); + // nsIWidget::GetTextEventDispatcher() shouldn't return nullptr. + MOZ_RELEASE_ASSERT(dispatcher); + return dispatcher; +} + nsIMEUpdatePreference IMContextWrapper::GetIMEUpdatePreference() const { @@ -1375,18 +1388,26 @@ IMContextWrapper::DispatchCompositionStart(GtkIMContext* aContext) } } + RefPtr dispatcher = GetTextEventDispatcher(); + nsresult rv = dispatcher->BeginNativeInputTransaction(); + if (NS_WARN_IF(NS_FAILED(rv))) { + MOZ_LOG(gGtkIMLog, LogLevel::Error, + ("GTKIM: %p DispatchCompositionStart(), FAILED, " + "due to BeginNativeInputTransaction() failure", + this)); + return false; + } + MOZ_LOG(gGtkIMLog, LogLevel::Debug, - ("GTKIM: %p DispatchCompositionStart(), FAILED, mCompositionStart=%u", + ("GTKIM: %p DispatchCompositionStart(), dispatching " + "compositionstart... (mCompositionStart=%u)", this, mCompositionStart)); mCompositionState = eCompositionState_CompositionStartDispatched; - WidgetCompositionEvent compEvent(true, eCompositionStart, - mLastFocusedWindow); - InitEvent(compEvent); - nsCOMPtr kungFuDeathGrip = mLastFocusedWindow; nsEventStatus status; - mLastFocusedWindow->DispatchEvent(&compEvent, status); - if (static_cast(kungFuDeathGrip.get())->IsDestroyed() || - kungFuDeathGrip != mLastFocusedWindow) { + RefPtr lastFocusedWindow = mLastFocusedWindow; + dispatcher->StartComposition(status); + if (lastFocusedWindow->IsDestroyed() || + lastFocusedWindow != mLastFocusedWindow) { MOZ_LOG(gGtkIMLog, LogLevel::Error, ("GTKIM: %p DispatchCompositionStart(), FAILED, the focused " "widget was destroyed/changed by compositionstart event", @@ -1425,8 +1446,15 @@ IMContextWrapper::DispatchCompositionChangeEvent( } } - nsEventStatus status; - RefPtr lastFocusedWindow = mLastFocusedWindow; + RefPtr dispatcher = GetTextEventDispatcher(); + nsresult rv = dispatcher->BeginNativeInputTransaction(); + if (NS_WARN_IF(NS_FAILED(rv))) { + MOZ_LOG(gGtkIMLog, LogLevel::Error, + ("GTKIM: %p DispatchCompositionChangeEvent(), FAILED, " + "due to BeginNativeInputTransaction() failure", + this)); + return false; + } // Store the selected string which will be removed by following // compositionchange event. @@ -1440,30 +1468,39 @@ IMContextWrapper::DispatchCompositionChangeEvent( } } - WidgetCompositionEvent compositionChangeEvent(true, eCompositionChange, - mLastFocusedWindow); - InitEvent(compositionChangeEvent); + RefPtr rangeArray = + CreateTextRangeArray(aContext, aCompositionString); - uint32_t targetOffset = mCompositionStart; - - compositionChangeEvent.mData = - mDispatchedCompositionString = aCompositionString; - - compositionChangeEvent.mRanges = - CreateTextRangeArray(aContext, mDispatchedCompositionString); - targetOffset += compositionChangeEvent.TargetClauseOffset(); + rv = dispatcher->SetPendingComposition(aCompositionString, rangeArray); + if (NS_WARN_IF(NS_FAILED(rv))) { + MOZ_LOG(gGtkIMLog, LogLevel::Error, + ("GTKIM: %p DispatchCompositionChangeEvent(), FAILED, " + "due to SetPendingComposition() failure", + this)); + return false; + } mCompositionState = eCompositionState_CompositionChangeEventDispatched; // We cannot call SetCursorPosition for e10s-aware. // DispatchEvent is async on e10s, so composition rect isn't updated now // on tab parent. + mDispatchedCompositionString = aCompositionString; mLayoutChanged = false; - mCompositionTargetRange.mOffset = targetOffset; - mCompositionTargetRange.mLength = - compositionChangeEvent.TargetClauseLength(); + mCompositionTargetRange.mOffset = rangeArray->TargetClauseOffset(); + mCompositionTargetRange.mLength = rangeArray->TargetClauseLength(); + + RefPtr lastFocusedWindow(mLastFocusedWindow); + nsEventStatus status; + rv = dispatcher->FlushPendingComposition(status); + if (NS_WARN_IF(NS_FAILED(rv))) { + MOZ_LOG(gGtkIMLog, LogLevel::Error, + ("GTKIM: %p DispatchCompositionChangeEvent(), FAILED, " + "due to FlushPendingComposition() failure", + this)); + return false; + } - mLastFocusedWindow->DispatchEvent(&compositionChangeEvent, status); if (lastFocusedWindow->IsDestroyed() || lastFocusedWindow != mLastFocusedWindow) { MOZ_LOG(gGtkIMLog, LogLevel::Error, @@ -1513,25 +1550,33 @@ IMContextWrapper::DispatchCompositionCommitEvent( } } + RefPtr dispatcher = GetTextEventDispatcher(); + nsresult rv = dispatcher->BeginNativeInputTransaction(); + if (NS_WARN_IF(NS_FAILED(rv))) { + MOZ_LOG(gGtkIMLog, LogLevel::Error, + ("GTKIM: %p DispatchCompositionCommitEvent(), FAILED, " + "due to BeginNativeInputTransaction() failure", + this)); + return false; + } + RefPtr lastFocusedWindow(mLastFocusedWindow); - EventMessage message = aCommitString ? eCompositionCommit : - eCompositionCommitAsIs; mCompositionState = eCompositionState_NotComposing; mCompositionStart = UINT32_MAX; mCompositionTargetRange.Clear(); mDispatchedCompositionString.Truncate(); - WidgetCompositionEvent compositionCommitEvent(true, message, - mLastFocusedWindow); - InitEvent(compositionCommitEvent); - if (message == eCompositionCommit) { - compositionCommitEvent.mData = *aCommitString; + nsEventStatus status; + rv = dispatcher->CommitComposition(status, aCommitString); + if (NS_WARN_IF(NS_FAILED(rv))) { + MOZ_LOG(gGtkIMLog, LogLevel::Error, + ("GTKIM: %p DispatchCompositionChangeEvent(), FAILED, " + "due to CommitComposition() failure", + this)); + return false; } - nsEventStatus status = nsEventStatus_eIgnore; - mLastFocusedWindow->DispatchEvent(&compositionCommitEvent, status); - if (lastFocusedWindow->IsDestroyed() || lastFocusedWindow != mLastFocusedWindow) { MOZ_LOG(gGtkIMLog, LogLevel::Error, @@ -1563,10 +1608,12 @@ IMContextWrapper::CreateTextRangeArray(GtkIMContext* aContext, gtk_im_context_get_preedit_string(aContext, &preedit_string, &feedback_list, &cursor_pos_in_chars); if (!preedit_string || !*preedit_string) { - MOZ_LOG(gGtkIMLog, LogLevel::Error, - ("GTKIM: %p CreateTextRangeArray(), FAILED, due to " - "preedit_string is null", - this)); + if (!aCompositionString.IsEmpty()) { + MOZ_LOG(gGtkIMLog, LogLevel::Error, + ("GTKIM: %p CreateTextRangeArray(), FAILED, due to " + "preedit_string is null", + this)); + } pango_attr_list_unref(feedback_list); g_free(preedit_string); return textRangeArray.forget(); diff --git a/widget/gtk/IMContextWrapper.h b/widget/gtk/IMContextWrapper.h index f7a4d4e7d277..662cd24af056 100644 --- a/widget/gtk/IMContextWrapper.h +++ b/widget/gtk/IMContextWrapper.h @@ -84,6 +84,8 @@ public: void OnUpdateComposition(); void OnLayoutChange(); + TextEventDispatcher* GetTextEventDispatcher(); + protected: ~IMContextWrapper();