Bug 1137572 part.3 Use pseudo IME context when TextEventDispatcher has input transaction which is not for native event handler r=smaug

This commit is contained in:
Masayuki Nakano 2016-03-16 13:47:47 +09:00
parent 3a5c26cf72
commit e65433cc66
12 changed files with 87 additions and 16 deletions

View File

@ -155,14 +155,19 @@ TextEventDispatcher::InitEvent(WidgetGUIEvent& aEvent) const
if (aEvent.mClass != eCompositionEventClass) {
return;
}
// Currently, we should set special native IME context when composition
// events are dispatched from PuppetWidget since PuppetWidget may have not
// known actual native IME context yet and it caches native IME context
// when it dispatches every WidgetCompositionEvent.
if (XRE_IsContentProcess()) {
aEvent.AsCompositionEvent()->
mNativeIMEContext.InitWithRawNativeIMEContext(mWidget);
void* pseudoIMEContext = GetPseudoIMEContext();
if (pseudoIMEContext) {
aEvent.AsCompositionEvent()->mNativeIMEContext.
InitWithRawNativeIMEContext(pseudoIMEContext);
}
#ifdef DEBUG
else {
MOZ_ASSERT(!XRE_IsContentProcess(),
"Why did the content process start native event transaction?");
MOZ_ASSERT(aEvent.AsCompositionEvent()->mNativeIMEContext.IsValid(),
"Native IME context shouldn't be invalid");
}
#endif // #ifdef DEBUG
}
nsresult

View File

@ -97,6 +97,20 @@ public:
*/
bool IsDispatchingEvent() const { return mDispatchingEvent > 0; }
/**
* GetPseudoIMEContext() returns pseudo native IME context if there is an
* input transaction whose type is not for native event handler.
* Otherwise, returns nullptr.
*/
void* GetPseudoIMEContext() const
{
if (mInputTransactionType == eNoInputTransaction ||
mInputTransactionType == eNativeInputTransaction) {
return nullptr;
}
return const_cast<TextEventDispatcher*>(this);
}
/**
* StartComposition() starts composition explicitly.
*/

View File

@ -1988,9 +1988,14 @@ nsWindow::GetNativeData(uint32_t aDataType)
case NS_NATIVE_WIDGET:
return (void *) this;
case NS_RAW_NATIVE_IME_CONTEXT:
case NS_RAW_NATIVE_IME_CONTEXT: {
void* pseudoIMEContext = GetPseudoIMEContext();
if (pseudoIMEContext) {
return pseudoIMEContext;
}
// We assume that there is only one context per process on Android
return NS_ONLY_ONE_NATIVE_IME_CONTEXT;
}
case NS_NATIVE_NEW_EGL_SURFACE:
if (!mGLControllerSupport) {

View File

@ -689,6 +689,10 @@ void* nsChildView::GetNativeData(uint32_t aDataType)
break;
case NS_RAW_NATIVE_IME_CONTEXT:
retVal = GetPseudoIMEContext();
if (retVal) {
break;
}
retVal = [mView inputContext];
// If input context isn't available on this widget, we should set |this|
// instead of nullptr since if this returns nullptr, IMEStateManager

View File

@ -596,6 +596,10 @@ void* nsCocoaWindow::GetNativeData(uint32_t aDataType)
NS_ERROR("Requesting NS_NATIVE_GRAPHIC on a top-level window!");
break;
case NS_RAW_NATIVE_IME_CONTEXT: {
retVal = GetPseudoIMEContext();
if (retVal) {
break;
}
NSView* view = mWindow ? [mWindow contentView] : nil;
if (view) {
retVal = [view inputContext];

View File

@ -536,10 +536,15 @@ nsWindow::GetNativeData(uint32_t aDataType)
return mScreen->GetNativeWindow();
case NS_NATIVE_OPENGL_CONTEXT:
return mScreen->GetGLContext().take();
case NS_RAW_NATIVE_IME_CONTEXT:
case NS_RAW_NATIVE_IME_CONTEXT: {
void* pseudoIMEContext = GetPseudoIMEContext();
if (pseudoIMEContext) {
return pseudoIMEContext;
}
// There is only one IME context on Gonk.
return NS_ONLY_ONE_NATIVE_IME_CONTEXT;
}
}
return nullptr;
}

View File

@ -1740,15 +1740,18 @@ nsWindow::GetNativeData(uint32_t aDataType)
return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow));
case NS_NATIVE_PLUGIN_OBJECT_PTR:
return (void *) mPluginNativeWindow;
case NS_RAW_NATIVE_IME_CONTEXT:
case NS_RAW_NATIVE_IME_CONTEXT: {
void* pseudoIMEContext = GetPseudoIMEContext();
if (pseudoIMEContext) {
return pseudoIMEContext;
}
// If IME context isn't available on this widget, we should set |this|
// instead of nullptr since if we return nullptr, IMEStateManager
// cannot manage composition with TextComposition instance. Although,
// this case shouldn't occur.
if (NS_WARN_IF(!mIMContext)) {
// instead of nullptr.
if (!mIMContext) {
return this;
}
return mIMContext.get();
}
default:
NS_WARNING("nsWindow::GetNativeData called with bad value");
return nullptr;

View File

@ -1787,6 +1787,16 @@ nsBaseWidget::GetTextEventDispatcher()
return mTextEventDispatcher;
}
void*
nsBaseWidget::GetPseudoIMEContext()
{
TextEventDispatcher* dispatcher = GetTextEventDispatcher();
if (!dispatcher) {
return nullptr;
}
return dispatcher->GetPseudoIMEContext();
}
NS_IMETHODIMP_(TextEventDispatcherListener*)
nsBaseWidget::GetNativeTextEventDispatcherListener()
{

View File

@ -431,6 +431,12 @@ protected:
virtual nsresult NotifyIMEInternal(const IMENotification& aIMENotification)
{ return NS_ERROR_NOT_IMPLEMENTED; }
/**
* GetPseudoIMEContext() returns pseudo IME context when TextEventDispatcher
* has non-native input transaction. Otherwise, returns nullptr.
*/
void* GetPseudoIMEContext();
protected:
// Utility to check if an array of clip rects is equal to our
// internally stored clip rect array mClipRects.

View File

@ -660,10 +660,15 @@ nsWindow::GetNativeData(uint32_t aDataType)
case NS_NATIVE_SHELLWIDGET: {
break;
}
case NS_RAW_NATIVE_IME_CONTEXT:
case NS_RAW_NATIVE_IME_CONTEXT: {
void* pseudoIMEContext = GetPseudoIMEContext();
if (pseudoIMEContext) {
return pseudoIMEContext;
}
// Our qt widget looks like using only one context per process.
// However, it's better to set the context's pointer.
return qApp->inputMethod();
}
default:
NS_WARNING("nsWindow::GetNativeData called with bad value");
return nullptr;

View File

@ -875,6 +875,10 @@ void* nsWindow::GetNativeData(uint32_t aDataType)
break;
case NS_RAW_NATIVE_IME_CONTEXT:
retVal = GetPseudoIMEContext();
if (retVal) {
break;
}
retVal = NS_ONLY_ONE_NATIVE_IME_CONTEXT;
break;
}

View File

@ -3244,7 +3244,13 @@ void* nsWindow::GetNativeData(uint32_t aDataType)
return (void*)::GetDC(mWnd);
#endif
case NS_RAW_NATIVE_IME_CONTEXT:
case NS_RAW_NATIVE_IME_CONTEXT: {
void* pseudoIMEContext = GetPseudoIMEContext();
if (pseudoIMEContext) {
return pseudoIMEContext;
}
MOZ_FALLTHROUGH;
}
case NS_NATIVE_TSF_THREAD_MGR:
case NS_NATIVE_TSF_CATEGORY_MGR:
case NS_NATIVE_TSF_DISPLAY_ATTR_MGR: