Bug 1453629 - nsIWidget::GetNativeIMEContext() should return pseudo IME context if TextInputProcessor has a composition on the widget r=m_kato

Key of TextCompositionArrary to search composition on widget is native IME
context.  However, if TextInputProcessor dispatches composition events via
TextEventDispatcher, TextEventDispatcher::InitEvent() sets native IME context
of dispatching composition events to pseudo IME context (that's raw pointer
of TextEventDispatcher and process ID).

IMEStateManager::DispatchCompositionEvent() looks for existing TextComposition
with native IME context stored in WidgetCompositionEvent before dispatching
an event.  However, after dispatching it, it looks for remaining TextComposition
instance with widget stored in WidgetCompositionEvent.  Then,
TextCompositionArrary::IndexOf(nsIWidget*) will look for an instance with
the result of nsIWidget::GetNativeIMEContext() and this never returns actual
native IME context.  Therefore, IMEStateManager::DispatchCompositionEvent()
always fails to remove TextComposition instance from the array even after
a test composition is finished.

This patch moves nsIWidget::GetNativeIMEContext() to nsBaseWidget to refer
nsBaseWidget::mTextEventDispatcher makes it return pseudo IME context if
TextInputProcessor has input transaction.  Therefore, IMEStateManager becomes
always removes TextComposition from the array when every composition ends.

MozReview-Commit-ID: H1PCtPjBYJR

--HG--
extra : rebase_source : cbb3f3aae9954d65135d3840be8974fa30c4f7ff
This commit is contained in:
Masayuki Nakano 2018-07-17 22:31:51 +09:00
parent 382ec3f85e
commit 0ed11cb188
4 changed files with 21 additions and 8 deletions

View File

@ -157,7 +157,9 @@ function runBeginInputTransactionMethodTests()
// Let's confirm that the composing string is NOT committed by above tests.
TIP1.commitComposition();
is(input.value, composingStr,
description + "TIP1.commitString() without specifying commit string should be committed with the last composing string");
description + "TIP1.commitString() without specifying commit string should commit current composition with the last composing string");
ok(!TIP1.hasComposition,
description + "TIP1.commitString() without specifying commit string should've end composition");
ok(TIP1.beginInputTransaction(window, simpleCallback),
description + "TIP1.beginInputTransaction() should succeed because there is no composition #2");

View File

@ -1933,6 +1933,22 @@ nsBaseWidget::EnsureTextEventDispatcher()
mTextEventDispatcher = new TextEventDispatcher(this);
}
nsIWidget::NativeIMEContext
nsBaseWidget::GetNativeIMEContext()
{
if (mTextEventDispatcher && mTextEventDispatcher->GetPseudoIMEContext()) {
// If we already have a TextEventDispatcher and it's working with
// a TextInputProcessor, we need to return pseudo IME context since
// TextCompositionArray::IndexOf(nsIWidget*) should return a composition
// on the pseudo IME context in such case.
NativeIMEContext pseudoIMEContext;
pseudoIMEContext.InitWithRawNativeIMEContext(
mTextEventDispatcher->GetPseudoIMEContext());
return pseudoIMEContext;
}
return NativeIMEContext(this);
}
nsIWidget::TextEventDispatcher*
nsBaseWidget::GetTextEventDispatcher()
{
@ -2441,12 +2457,6 @@ nsBaseWidget::DefaultFillScrollCapture(DrawTarget* aSnapshotDrawTarget)
}
#endif
nsIWidget::NativeIMEContext
nsIWidget::GetNativeIMEContext()
{
return NativeIMEContext(this);
}
const IMENotificationRequests&
nsIWidget::IMENotificationRequestsRef()
{

View File

@ -298,6 +298,7 @@ public:
virtual void SetAttachedWidgetListener(nsIWidgetListener* aListener) override;
virtual nsIWidgetListener* GetPreviouslyAttachedWidgetListener() override;
virtual void SetPreviouslyAttachedWidgetListener(nsIWidgetListener* aListener) override;
virtual NativeIMEContext GetNativeIMEContext() override;
TextEventDispatcher* GetTextEventDispatcher() final;
virtual TextEventDispatcherListener*
GetNativeTextEventDispatcherListener() override;

View File

@ -1851,7 +1851,7 @@ public:
* NS_RAW_NATIVE_IME_CONTEXT, the result is unique even if in a remote
* process.
*/
virtual NativeIMEContext GetNativeIMEContext();
virtual NativeIMEContext GetNativeIMEContext() = 0;
/*
* Given a WidgetKeyboardEvent, this method synthesizes a corresponding