Bug 1137565 part.2 IMContextWrapper should use TextEventDispatcher r=m_kato

This commit is contained in:
Masayuki Nakano 2016-03-16 13:47:49 +09:00
parent a9f207530a
commit ad8535477c
2 changed files with 88 additions and 39 deletions

View File

@ -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<TextEventDispatcher> 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<nsIWidget> kungFuDeathGrip = mLastFocusedWindow;
nsEventStatus status;
mLastFocusedWindow->DispatchEvent(&compEvent, status);
if (static_cast<nsWindow*>(kungFuDeathGrip.get())->IsDestroyed() ||
kungFuDeathGrip != mLastFocusedWindow) {
RefPtr<nsWindow> 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<nsWindow> lastFocusedWindow = mLastFocusedWindow;
RefPtr<TextEventDispatcher> 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<TextRangeArray> 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<nsWindow> 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<TextEventDispatcher> 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<nsWindow> 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();

View File

@ -84,6 +84,8 @@ public:
void OnUpdateComposition();
void OnLayoutChange();
TextEventDispatcher* GetTextEventDispatcher();
protected:
~IMContextWrapper();