Navigation Menu

Skip to content

Commit

Permalink
[embedlite] Fix input context handling. Fixes JB#37182
Browse files Browse the repository at this point in the history
  • Loading branch information
rainemak committed Dec 11, 2018
1 parent e24992f commit eae05f4
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 24 deletions.
2 changes: 1 addition & 1 deletion embedding/embedlite/EmbedLiteView.h
Expand Up @@ -51,7 +51,7 @@ class EmbedLiteViewListener
const gfxSize& aScrollableSize) { return false; }

virtual void IMENotification(int aEnabled, bool aOpen, int aCause, int aFocusChange, const char16_t* inputType, const char16_t* inputMode) {}
virtual void GetIMEStatus(int32_t* aIMEEnabled, int32_t* aIMEOpen, intptr_t* aNativeIMEContext) {}
virtual void GetIMEStatus(int32_t* aIMEEnabled, int32_t* aIMEOpen) {}

// AZPC Interface, return true in order to prevent default behavior
virtual bool RequestContentRepaint() { return false; }
Expand Down
3 changes: 1 addition & 2 deletions embedding/embedlite/PEmbedLiteView.ipdl
Expand Up @@ -114,8 +114,7 @@ parent:
returns (nsString[] retval);

// IME
sync GetInputContext() returns (int32_t IMEEnabled, int32_t IMEOpen,
intptr_t NativeIMEContext);
sync GetInputContext() returns (int32_t IMEEnabled, int32_t IMEOpen);

SetInputContext(int32_t IMEEnabled,
int32_t IMEOpen,
Expand Down
87 changes: 81 additions & 6 deletions embedding/embedlite/embedshared/EmbedLitePuppetWidget.cpp
Expand Up @@ -27,6 +27,12 @@
#include "GLContext.h"
#include "EmbedLiteCompositorParent.h"
#include "mozilla/Preferences.h"

#ifdef DEBUG
#include "mozilla/TextComposition.h"
#include "mozilla/IMEStateManager.h"
#endif

#include "EmbedLiteApp.h"
#include "LayerScope.h"
#include "mozilla/unused.h"
Expand Down Expand Up @@ -419,6 +425,8 @@ EmbedLitePuppetWidget::GetNativeData(uint32_t aDataType)
case NS_NATIVE_WIDGET:
LOGW("nsWindow::GetNativeData not implemented for this type");
break;
case NS_RAW_NATIVE_IME_CONTEXT:
return NS_ONLY_ONE_NATIVE_IME_CONTEXT;
default:
NS_WARNING("nsWindow::GetNativeData called with bad value");
break;
Expand All @@ -431,7 +439,6 @@ NS_IMETHODIMP
EmbedLitePuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus)
{
LOGT();

aStatus = nsEventStatus_eIgnore;

nsIWidgetListener* listener =
Expand All @@ -441,6 +448,22 @@ EmbedLitePuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStat

if (event->mClass == eKeyboardEventClass) {
RemoveIMEComposition();
} else if (event->mClass == eCompositionEventClass) {
// Store the latest native IME context of parent process's widget or
// TextEventDispatcher if it's in this process.
WidgetCompositionEvent* compositionEvent = event->AsCompositionEvent();
#ifdef DEBUG
if (mNativeIMEContext.IsValid() &&
mNativeIMEContext != compositionEvent->mNativeIMEContext) {
RefPtr<TextComposition> composition =
IMEStateManager::GetTextCompositionFor(this);
MOZ_ASSERT(!composition,
"When there is composition caused by old native IME context, "
"composition events caused by different native IME context are not "
"allowed");
}
#endif // #ifdef DEBUG
mNativeIMEContext = compositionEvent->mNativeIMEContext;
}

aStatus = listener->HandleEvent(event, mUseAttachedEvents);
Expand Down Expand Up @@ -475,7 +498,10 @@ EmbedLitePuppetWidget::SetInputContext(const InputContext& aContext,
aContext.mIMEState.mEnabled, aContext.mIMEState.mOpen,
aAction.mCause, aAction.mFocusChange);

mInputContext = aContext;
if (Destroyed()) {
LOGT("Trying to focus after puppet widget got destroyed.");
return;
}

// Ensure that opening the virtual keyboard is allowed for this specific
// InputContext depending on the content.ime.strict.policy pref
Expand All @@ -487,6 +513,18 @@ EmbedLitePuppetWidget::SetInputContext(const InputContext& aContext,
return;
}

IMEState::Enabled enabled = aContext.mIMEState.mEnabled;

// Only show the virtual keyboard for plugins if mOpen is set appropriately.
// This avoids showing it whenever a plugin is focused. Bug 747492
if (aContext.mIMEState.mEnabled == IMEState::PLUGIN &&
aContext.mIMEState.mOpen != IMEState::OPEN) {
enabled = IMEState::DISABLED;
}

mInputContext = aContext;
mInputContext.mIMEState.mEnabled = enabled;

EmbedLiteViewChildIface* view = GetEmbedLiteChildView();
if (view) {
view->SetInputContext(
Expand All @@ -503,21 +541,58 @@ EmbedLitePuppetWidget::SetInputContext(const InputContext& aContext,
NS_IMETHODIMP_(InputContext)
EmbedLitePuppetWidget::GetInputContext()
{
mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
LOGT();
EmbedLiteViewChildIface* view = GetEmbedLiteChildView();

if (view) {
int32_t enabled, open;
intptr_t nativeIMEContext;
view->GetInputContext(&enabled, &open, &nativeIMEContext);
int32_t enabled = IMEState::DISABLED;
int32_t open = IMEState::OPEN_STATE_NOT_SUPPORTED;

view->GetInputContext(&enabled, &open);
mInputContext.mIMEState.mEnabled = static_cast<IMEState::Enabled>(enabled);
mInputContext.mIMEState.mOpen = static_cast<IMEState::Open>(open);
}

return mInputContext;
}

NS_IMETHODIMP_(NativeIMEContext)
EmbedLitePuppetWidget::GetNativeIMEContext()
{
LOGT();
return mNativeIMEContext;
}

nsIMEUpdatePreference
EmbedLitePuppetWidget::GetIMEUpdatePreference()
{
LOGT();
#ifdef MOZ_CROSS_PROCESS_IME
// e10s requires IME content cache in in the TabParent for handling query
// content event only with the parent process. Therefore, this process
// needs to receive a lot of information from the focused editor to sent
// the latest content to the parent process.
if (mInputContext.mIMEState.mEnabled == IMEState::PLUGIN) {
// But if a plugin has focus, we cannot receive text nor selection change
// in the plugin. Therefore, PuppetWidget needs to receive only position
// change event for updating the editor rect cache.
return nsIMEUpdatePreference(mIMEPreferenceOfParent.mWantUpdates |
nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE);
}
return nsIMEUpdatePreference(mIMEPreferenceOfParent.mWantUpdates |
nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE |
nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE );
#else
// B2G doesn't handle IME as widget-level.
return nsIMEUpdatePreference();
#endif
}

void
EmbedLitePuppetWidget::RemoveIMEComposition()
{
LOGT();
// Remove composition on Gecko side
if (!mIMEComposing) {
return;
Expand Down
4 changes: 4 additions & 0 deletions embedding/embedlite/embedshared/EmbedLitePuppetWidget.h
Expand Up @@ -133,6 +133,8 @@ class EmbedLitePuppetWidget : public nsBaseWidget
NS_IMETHOD_(void) SetInputContext(const InputContext& aContext,
const InputContextAction& aAction) override;
NS_IMETHOD_(InputContext) GetInputContext() override;
NS_IMETHOD_(NativeIMEContext) GetNativeIMEContext() override;
virtual nsIMEUpdatePreference GetIMEUpdatePreference() override;

NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) override {
LOGNI();
Expand Down Expand Up @@ -219,6 +221,8 @@ class EmbedLitePuppetWidget : public nsBaseWidget
bool mActive;
bool mHasCompositor;
InputContext mInputContext;
NativeIMEContext mNativeIMEContext;

bool mIMEComposing;
nsString mIMEComposingText;
ChildrenArray mChildren;
Expand Down
5 changes: 2 additions & 3 deletions embedding/embedlite/embedshared/EmbedLiteViewBaseChild.cpp
Expand Up @@ -340,10 +340,9 @@ EmbedLiteViewBaseChild::SetInputContext(const int32_t& IMEEnabled,

bool
EmbedLiteViewBaseChild::GetInputContext(int32_t* IMEEnabled,
int32_t* IMEOpen,
intptr_t* NativeIMEContext)
int32_t* IMEOpen)
{
return SendGetInputContext(IMEEnabled, IMEOpen, NativeIMEContext);
return SendGetInputContext(IMEEnabled, IMEOpen);
}

void EmbedLiteViewBaseChild::ResetInputState()
Expand Down
3 changes: 1 addition & 2 deletions embedding/embedlite/embedshared/EmbedLiteViewBaseChild.h
Expand Up @@ -102,8 +102,7 @@ class EmbedLiteViewBaseChild : public PEmbedLiteViewChild,

virtual bool
GetInputContext(int32_t* IMEEnabled,
int32_t* IMEOpen,
intptr_t* NativeIMEContext) override;
int32_t* IMEOpen) override;

/*---------WidgetIface---------------*/

Expand Down
14 changes: 8 additions & 6 deletions embedding/embedlite/embedshared/EmbedLiteViewBaseParent.cpp
Expand Up @@ -496,15 +496,17 @@ EmbedLiteViewBaseParent::MouseMove(int x, int y, int mstime, unsigned int button

bool
EmbedLiteViewBaseParent::RecvGetInputContext(int32_t* aIMEEnabled,
int32_t* aIMEOpen,
intptr_t* aNativeIMEContext)
int32_t* aIMEOpen)
{
LOGT("mLastIMEState:%i", mLastIMEState);
LOGT("mLastIMEState:%i view: %p listener: %p", mLastIMEState, mView, (mView ? mView->GetListener() : 0));
NS_ASSERTION(aIMEEnabled, "Passing nullptr for aIMEEnabled. A bug in EmbedLitePuppetWidget.");
NS_ASSERTION(aIMEOpen, "Passing nullptr for aIMEOpen. A bug in EmbedLitePuppetWidget.");

*aIMEEnabled = mLastIMEState;
*aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
*aNativeIMEContext = 0;
if (mView) {
mView->GetListener()->GetIMEStatus(aIMEEnabled, aIMEOpen, aNativeIMEContext);

if (mView && mView->GetListener()) {
mView->GetListener()->GetIMEStatus(aIMEEnabled, aIMEOpen);
}
return true;
}
Expand Down
3 changes: 1 addition & 2 deletions embedding/embedlite/embedshared/EmbedLiteViewBaseParent.h
Expand Up @@ -104,8 +104,7 @@ class EmbedLiteViewBaseParent : public PEmbedLiteViewParent,

// IME
virtual bool RecvGetInputContext(int32_t* aIMEEnabled,
int32_t* aIMEOpen,
intptr_t* aNativeIMEContext) override;
int32_t* aIMEOpen) override;
virtual bool RecvSetInputContext(const int32_t& aIMEEnabled,
const int32_t& aIMEOpen,
const nsString& aType,
Expand Down
3 changes: 1 addition & 2 deletions embedding/embedlite/embedshared/EmbedLiteViewChildIface.h
Expand Up @@ -26,8 +26,7 @@ class EmbedLiteViewChildIface

virtual bool
GetInputContext(int32_t* IMEEnabled,
int32_t* IMEOpen,
intptr_t* NativeIMEContext) = 0;
int32_t* IMEOpen) = 0;
virtual void ResetInputState() = 0;

/*-------------TabChild-------------------*/
Expand Down

0 comments on commit eae05f4

Please sign in to comment.