зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
0405f81c59
Коммит
c726abb366
|
@ -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)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче