зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1629347 - Make `TSFTextStore::SetInputContext()` emulate focus when the menu keyboard event listener is uninstalled r=m_kato
Currently, `IMEStateManager` sets `InputContext` to disable IME when the menu keyboard event listener is installed, but does not destroy `IMEContentObserver` which may be in a remote process. And similarly, it setns `InputContext` to enable IME when the menu keyboard event listener is uninstalled, but does not make `IMEContentObserver` which may be in a remote process send `NOTIFY_IME_OF_FOCUS` again. Therefore, from point of view of native IME handlers in widget, `NOTIFY_IME_OF_FOCUS` won't be sent in this case, but `TSFTextStore::SetInputContext()` expects that it'll be followed by `NOTIFY_IME_OF_FOCUS` unless it's called for `FOCUS_NOT_CHANGED`. Therefore, `sEnabledTextStore` is `nullptr` when this bug occurs. For fixing this bug **quickly**, this patch makes `TSFTextStore::SetInputContext()` treat `MENU_LOST_PSEUDO_FOCUS` as `FOCUS_NOT_CHANGED` to create `TSFTextStore` instance if new state is "enabled". Ideally, we should redesign `IMEStateManager` because while menu keyboard event listener has pseudo focus, web apps may change focus or create something complicated cases. Unfortunately, we still cannot write automated tests for `TSFTextStore` due to bug 1322744. Differential Revision: https://phabricator.services.mozilla.com/D93469
This commit is contained in:
Родитель
40b561b9ac
Коммит
edfe4e01f5
|
@ -6589,28 +6589,41 @@ void TSFTextStore::SetInputContext(nsWindowBase* aWidget,
|
|||
sEnabledTextStore ? sEnabledTextStore->mWidget.get() : nullptr,
|
||||
GetBoolName(ThinksHavingFocus())));
|
||||
|
||||
// When this is called when the widget is created, there is nothing to do.
|
||||
if (aAction.mFocusChange == InputContextAction::WIDGET_CREATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE_VOID(IsInTSFMode());
|
||||
|
||||
if (aAction.mFocusChange != InputContextAction::FOCUS_NOT_CHANGED) {
|
||||
if (sEnabledTextStore) {
|
||||
RefPtr<TSFTextStore> textStore(sEnabledTextStore);
|
||||
textStore->SetInputScope(aContext.mHTMLInputType,
|
||||
aContext.mHTMLInputInputmode,
|
||||
aContext.mInPrivateBrowsing);
|
||||
}
|
||||
return;
|
||||
switch (aAction.mFocusChange) {
|
||||
case InputContextAction::WIDGET_CREATED:
|
||||
// If this is called when the widget is created, there is nothing to do.
|
||||
return;
|
||||
case InputContextAction::FOCUS_NOT_CHANGED:
|
||||
case InputContextAction::MENU_LOST_PSEUDO_FOCUS:
|
||||
if (NS_WARN_IF(!IsInTSFMode())) {
|
||||
return;
|
||||
}
|
||||
// In these cases, `NOTIFY_IME_OF_FOCUS` won't be sent. Therefore,
|
||||
// we need to reset text store for new state right now.
|
||||
break;
|
||||
default:
|
||||
NS_WARNING_ASSERTION(IsInTSFMode(),
|
||||
"Why is this called when TSF is disabled?");
|
||||
if (sEnabledTextStore) {
|
||||
RefPtr<TSFTextStore> textStore(sEnabledTextStore);
|
||||
textStore->SetInputScope(aContext.mHTMLInputType,
|
||||
aContext.mHTMLInputInputmode,
|
||||
aContext.mInPrivateBrowsing);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If focus isn't actually changed but the enabled state is changed,
|
||||
// emulate the focus move.
|
||||
if (!ThinksHavingFocus() && aContext.mIMEState.IsEditable()) {
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
|
||||
(" TSFTextStore::SetInputContent() emulates focus for IME "
|
||||
"state change"));
|
||||
OnFocusChange(true, aWidget, aContext);
|
||||
} else if (ThinksHavingFocus() && !aContext.mIMEState.IsEditable()) {
|
||||
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
|
||||
(" TSFTextStore::SetInputContent() emulates blur for IME "
|
||||
"state change"));
|
||||
OnFocusChange(false, aWidget, aContext);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче