зеркало из https://github.com/mozilla/gecko-dev.git
Bug 805357 part.1 nsIMEStateManager should always call nsIWidget::OnIMEFocusChange(false) when our editor loses focus r=smaug
This commit is contained in:
Родитель
1aabf932f3
Коммит
adc6bfb320
|
@ -116,6 +116,9 @@ nsIMEStateManager::OnDestroyPresContext(nsPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
nsCOMPtr<nsIWidget> widget = sPresContext->GetNearestWidget();
|
||||
if (widget) {
|
||||
if (IsEditableIMEState(widget)) {
|
||||
widget->OnIMEFocusChange(false);
|
||||
}
|
||||
IMEState newState = GetNewIMEState(sPresContext, nullptr);
|
||||
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
|
||||
InputContextAction::LOST_FOCUS);
|
||||
|
@ -175,6 +178,9 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
|
|||
// Current IME transaction should commit
|
||||
nsCOMPtr<nsIWidget> widget = sPresContext->GetNearestWidget();
|
||||
if (widget) {
|
||||
if (IsEditableIMEState(widget)) {
|
||||
widget->OnIMEFocusChange(false);
|
||||
}
|
||||
IMEState newState = GetNewIMEState(sPresContext, nullptr);
|
||||
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
|
||||
InputContextAction::LOST_FOCUS);
|
||||
|
@ -202,6 +208,23 @@ nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
|
|||
nsIContent* aContent,
|
||||
InputContextAction aAction)
|
||||
{
|
||||
bool focusActuallyChanging =
|
||||
(sContent != aContent || sPresContext != aPresContext);
|
||||
|
||||
nsCOMPtr<nsIWidget> oldWidget =
|
||||
sPresContext ? sPresContext->GetNearestWidget() : nullptr;
|
||||
if (oldWidget && focusActuallyChanging) {
|
||||
// If we're deactivating, we shouldn't commit composition forcibly because
|
||||
// the user may want to continue the composition.
|
||||
if (aPresContext) {
|
||||
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget);
|
||||
}
|
||||
// Notify IME of losing focus even if we're deactivating.
|
||||
if (IsEditableIMEState(oldWidget)) {
|
||||
oldWidget->OnIMEFocusChange(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (sTextStateObserver &&
|
||||
!sTextStateObserver->IsManaging(aPresContext, aContent)) {
|
||||
DestroyTextStateManager();
|
||||
|
@ -211,7 +234,9 @@ nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = aPresContext->GetNearestWidget();
|
||||
nsCOMPtr<nsIWidget> widget =
|
||||
(sPresContext == aPresContext) ? oldWidget.get() :
|
||||
aPresContext->GetNearestWidget();
|
||||
if (!widget) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -240,7 +265,7 @@ nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
IMEState newState = GetNewIMEState(aPresContext, aContent);
|
||||
if (aPresContext == sPresContext && aContent == sContent) {
|
||||
if (!focusActuallyChanging) {
|
||||
// actual focus isn't changing, but if IME enabled state is changing,
|
||||
// we should do it.
|
||||
InputContext context = widget->GetInputContext();
|
||||
|
@ -249,6 +274,12 @@ nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
aAction.mFocusChange = InputContextAction::FOCUS_NOT_CHANGED;
|
||||
|
||||
// Even if focus isn't changing actually, we should commit current
|
||||
// composition here since the IME state is changing.
|
||||
if (sPresContext && oldWidget && !focusActuallyChanging) {
|
||||
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget);
|
||||
}
|
||||
} else if (aAction.mFocusChange == InputContextAction::FOCUS_NOT_CHANGED) {
|
||||
// If aContent isn't null or aContent is null but editable, somebody gets
|
||||
// focus.
|
||||
|
@ -257,18 +288,6 @@ nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
|
|||
gotFocus ? InputContextAction::GOT_FOCUS : InputContextAction::LOST_FOCUS;
|
||||
}
|
||||
|
||||
// Current IME transaction should commit
|
||||
if (sPresContext) {
|
||||
nsCOMPtr<nsIWidget> oldWidget;
|
||||
if (sPresContext == aPresContext)
|
||||
oldWidget = widget;
|
||||
else
|
||||
oldWidget = sPresContext->GetNearestWidget();
|
||||
if (oldWidget) {
|
||||
NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, oldWidget);
|
||||
}
|
||||
}
|
||||
|
||||
// Update IME state for new focus widget
|
||||
SetIMEState(newState, aContent, widget, aAction);
|
||||
|
||||
|
@ -936,6 +955,22 @@ nsIMEStateManager::GetRootEditableNode(nsPresContext* aPresContext,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsIMEStateManager::IsEditableIMEState(nsIWidget* aWidget)
|
||||
{
|
||||
switch (aWidget->GetInputContext().mIMEState.mEnabled) {
|
||||
case widget::IMEState::ENABLED:
|
||||
case widget::IMEState::PASSWORD:
|
||||
return true;
|
||||
case widget::IMEState::PLUGIN:
|
||||
case widget::IMEState::DISABLED:
|
||||
return false;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unknown IME enable state");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsIMEStateManager::DestroyTextStateManager()
|
||||
{
|
||||
|
@ -944,7 +979,6 @@ nsIMEStateManager::DestroyTextStateManager()
|
|||
}
|
||||
|
||||
sTextStateObserver->mDestroying = true;
|
||||
sTextStateObserver->mWidget->OnIMEFocusChange(false);
|
||||
sTextStateObserver->Destroy();
|
||||
NS_RELEASE(sTextStateObserver);
|
||||
}
|
||||
|
@ -964,12 +998,8 @@ nsIMEStateManager::CreateTextStateManager()
|
|||
}
|
||||
|
||||
// If it's not text ediable, we don't need to create nsTextStateManager.
|
||||
switch (widget->GetInputContext().mIMEState.mEnabled) {
|
||||
case widget::IMEState::ENABLED:
|
||||
case widget::IMEState::PASSWORD:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
if (!IsEditableIMEState(widget)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsINode *editableNode = GetRootEditableNode(sPresContext, sContent);
|
||||
|
|
|
@ -123,6 +123,8 @@ protected:
|
|||
static nsINode* GetRootEditableNode(nsPresContext* aPresContext,
|
||||
nsIContent* aContent);
|
||||
|
||||
static bool IsEditableIMEState(nsIWidget* aWidget);
|
||||
|
||||
static nsIContent* sContent;
|
||||
static nsPresContext* sPresContext;
|
||||
static bool sInstalledMenuKeyboardListener;
|
||||
|
|
|
@ -2971,8 +2971,6 @@ IMEInputHandler::OnFocusChangeInGecko(bool aFocus)
|
|||
|
||||
// This is called when the native focus is changed and when the native focus
|
||||
// isn't changed but the focus is changed in Gecko.
|
||||
// XXX currently, we're not called this method with false, we need to
|
||||
// improve the nsIMEStateManager implementation.
|
||||
if (!aFocus) {
|
||||
if (sFocusedIMEHandler == this)
|
||||
sFocusedIMEHandler = nullptr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче