Bug 1377672 - part2: IMEStateManager::SetIMEState() should set input context with proper origin information r=m_kato

Currently, IMEStateManager always sets input context as set by current process even when it needs to adjust IME state when a tab parent for current focused IME process is removed.  Then, input context for the widget is marked as for main process but the widget still have IME focus of a remote process.

For fixing this mismatch, IMEStateManager should set ORIGIN_CONTENT even when the tab parent is being destroyed.

MozReview-Commit-ID: C10YOAtkET4

--HG--
extra : source : 9430d123b19e0ac551c6048bb044fcfa22d13e45
This commit is contained in:
Masayuki Nakano 2017-07-03 12:28:10 +09:00
Родитель 0405f81c59
Коммит c726abb366
4 изменённых файлов: 51 добавлений и 16 удалений

Просмотреть файл

@ -144,6 +144,7 @@ nsIWidget* IMEStateManager::sActiveInputContextWidget = nullptr;
StaticRefPtr<TabParent> IMEStateManager::sActiveTabParent;
StaticRefPtr<IMEContentObserver> IMEStateManager::sActiveIMEContentObserver;
TextCompositionArray* IMEStateManager::sTextCompositions = nullptr;
InputContext::Origin IMEStateManager::sOrigin = InputContext::ORIGIN_MAIN;
bool IMEStateManager::sInstalledMenuKeyboardListener = false;
bool IMEStateManager::sIsGettingNewIMEState = false;
bool IMEStateManager::sCheckForIMEUnawareWebApps = false;
@ -163,6 +164,9 @@ IMEStateManager::Init()
&sInputModeSupported,
"dom.forms.inputmode",
false);
sOrigin = XRE_IsParentProcess() ? InputContext::ORIGIN_MAIN :
InputContext::ORIGIN_CONTENT;
}
// static
@ -304,7 +308,9 @@ IMEStateManager::OnDestroyPresContext(nsPresContext* aPresContext)
IMEState newState = GetNewIMEState(sPresContext, nullptr);
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
InputContextAction::LOST_FOCUS);
SetIMEState(newState, nullptr, sWidget, action);
InputContext::Origin origin =
sActiveTabParent ? InputContext::ORIGIN_CONTENT : sOrigin;
SetIMEState(newState, nullptr, sWidget, action, origin);
}
sWidget = nullptr;
sContent = nullptr;
@ -359,7 +365,9 @@ IMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
IMEState newState = GetNewIMEState(sPresContext, nullptr);
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
InputContextAction::LOST_FOCUS);
SetIMEState(newState, nullptr, sWidget, action);
InputContext::Origin origin =
sActiveTabParent ? InputContext::ORIGIN_CONTENT : sOrigin;
SetIMEState(newState, nullptr, sWidget, action, origin);
}
sWidget = nullptr;
@ -513,23 +521,26 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
setIMEState = sInstalledMenuKeyboardListener;
} else if (focusActuallyChanging) {
InputContext context = newWidget->GetInputContext();
if (context.mIMEState.mEnabled == IMEState::DISABLED) {
if (context.mIMEState.mEnabled == IMEState::DISABLED &&
context.mOrigin == InputContext::ORIGIN_CONTENT) {
setIMEState = false;
MOZ_LOG(sISMLog, LogLevel::Debug,
(" OnChangeFocusInternal(), doesn't set IME "
"state because focused element (or document) is in a child process "
"and the IME state is already disabled"));
"and the IME state is already disabled by a remote process"));
} else {
MOZ_LOG(sISMLog, LogLevel::Debug,
(" OnChangeFocusInternal(), will disable IME "
"until new focused element (or document) in the child process "
"will get focus actually"));
}
} else {
// When focus is NOT changed actually, we shouldn't set IME state since
// that means that the window is being activated and the child process
// may have composition. Then, we shouldn't commit the composition with
// making IME state disabled.
} else if (newWidget->GetInputContext().mOrigin !=
InputContext::ORIGIN_CONTENT) {
// When focus is NOT changed actually, we shouldn't set IME state if
// current input context was set by a remote process since that means
// that the window is being activated and the child process may have
// composition. Then, we shouldn't commit the composition with making
// IME state disabled.
setIMEState = false;
MOZ_LOG(sISMLog, LogLevel::Debug,
(" OnChangeFocusInternal(), doesn't set IME "
@ -566,7 +577,8 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
}
// Update IME state for new focus widget
SetIMEState(newState, aContent, newWidget, aAction);
SetIMEState(newState, aContent, newWidget, aAction,
newTabParent ? InputContext::ORIGIN_CONTENT : sOrigin);
}
sActiveTabParent = newTabParent;
@ -717,7 +729,7 @@ IMEStateManager::OnClickInEditor(nsPresContext* aPresContext,
InputContextAction action(cause, InputContextAction::FOCUS_NOT_CHANGED);
IMEState newState = GetNewIMEState(aPresContext, aContent);
SetIMEState(newState, aContent, widget, action);
SetIMEState(newState, aContent, widget, action, sOrigin);
}
// static
@ -926,7 +938,7 @@ IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState,
if (updateIMEState) {
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
InputContextAction::FOCUS_NOT_CHANGED);
SetIMEState(aNewIMEState, aContent, widget, action);
SetIMEState(aNewIMEState, aContent, widget, action, sOrigin);
if (NS_WARN_IF(widget->Destroyed())) {
MOZ_LOG(sISMLog, LogLevel::Error,
(" UpdateIMEState(), widget has gone during setting input context"));
@ -1086,22 +1098,25 @@ void
IMEStateManager::SetIMEState(const IMEState& aState,
nsIContent* aContent,
nsIWidget* aWidget,
InputContextAction aAction)
InputContextAction aAction,
InputContext::Origin aOrigin)
{
MOZ_LOG(sISMLog, LogLevel::Info,
("SetIMEState(aState={ mEnabled=%s, mOpen=%s }, "
"aContent=0x%p (TabParent=0x%p), aWidget=0x%p, aAction={ mCause=%s, "
"mFocusChange=%s })",
"mFocusChange=%s }, aOrigin=%s)",
GetIMEStateEnabledName(aState.mEnabled),
GetIMEStateSetOpenName(aState.mOpen), aContent,
TabParent::GetFrom(aContent), aWidget,
GetActionCauseName(aAction.mCause),
GetActionFocusChangeName(aAction.mFocusChange)));
GetActionFocusChangeName(aAction.mFocusChange),
ToChar(aOrigin)));
NS_ENSURE_TRUE_VOID(aWidget);
InputContext context;
context.mIMEState = aState;
context.mOrigin = aOrigin;
context.mMayBeIMEUnaware = context.mIMEState.IsEditable() &&
sCheckForIMEUnawareWebApps && MayBeIMEUnawareWebApp(aContent);

Просмотреть файл

@ -248,7 +248,8 @@ protected:
static void SetIMEState(const IMEState &aState,
nsIContent* aContent,
nsIWidget* aWidget,
InputContextAction aAction);
InputContextAction aAction,
InputContext::Origin aOrigin);
static void SetInputContext(nsIWidget* aWidget,
const InputContext& aInputContext,
const InputContextAction& aAction);
@ -300,6 +301,9 @@ protected:
// something to cause committing or canceling the composition.
static TextCompositionArray* sTextCompositions;
// Origin type of current process.
static InputContext::Origin sOrigin;
static bool sInstalledMenuKeyboardListener;
static bool sIsGettingNewIMEState;
static bool sCheckForIMEUnawareWebApps;

Просмотреть файл

@ -327,6 +327,9 @@ struct InputContext final
}
};
// FYI: Implemented in nsBaseWidget.cpp
const char* ToChar(InputContext::Origin aOrigin);
struct InputContextAction final
{
/**

Просмотреть файл

@ -2327,6 +2327,19 @@ nsIWidget::GetEditCommands(nsIWidget::NativeKeyBindingsType aType,
namespace mozilla {
namespace widget {
const char*
ToChar(InputContext::Origin aOrigin)
{
switch (aOrigin) {
case InputContext::ORIGIN_MAIN:
return "ORIGIN_MAIN";
case InputContext::ORIGIN_CONTENT:
return "ORIGIN_CONTENT";
default:
return "Unexpected value";
}
}
const char*
ToChar(IMEMessage aIMEMessage)
{