Bug 1037346 IMEStateManager should ignore a call of UpdateIMEState() which is caused by a call of nsIContent::GetDesiredIMEState() r=smaug

This commit is contained in:
Masayuki Nakano 2014-07-17 14:08:44 +09:00
parent eed56f67d8
commit b775a56968
2 changed files with 36 additions and 2 deletions

View File

@ -191,6 +191,7 @@ nsIContent* IMEStateManager::sContent = nullptr;
nsPresContext* IMEStateManager::sPresContext = nullptr;
bool IMEStateManager::sInstalledMenuKeyboardListener = false;
bool IMEStateManager::sIsTestingIME = false;
bool IMEStateManager::sIsGettingNewIMEState = false;
// sActiveIMEContentObserver points to the currently active IMEContentObserver.
// sActiveIMEContentObserver is null if there is no focused editor.
@ -568,10 +569,19 @@ IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState,
PR_LOG(sISMLog, PR_LOG_ALWAYS,
("ISM: IMEStateManager::UpdateIMEState(aNewIMEState={ mEnabled=%s, "
"mOpen=%s }, aContent=0x%p), "
"sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p",
"sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p, "
"sIsGettingNewIMEState=%s",
GetIMEStateEnabledName(aNewIMEState.mEnabled),
GetIMEStateSetOpenName(aNewIMEState.mOpen), aContent,
sPresContext, sContent, sActiveIMEContentObserver));
sPresContext, sContent, sActiveIMEContentObserver,
GetBoolName(sIsGettingNewIMEState)));
if (sIsGettingNewIMEState) {
PR_LOG(sISMLog, PR_LOG_DEBUG,
("ISM: IMEStateManager::UpdateIMEState(), "
"does nothing because of called while getting new IME state"));
return;
}
if (NS_WARN_IF(!sPresContext)) {
PR_LOG(sISMLog, PR_LOG_ERROR,
@ -659,6 +669,13 @@ IMEStateManager::GetNewIMEState(nsPresContext* aPresContext,
return IMEState(IMEState::DISABLED);
}
// nsIContent::GetDesiredIMEState() may cause a call of UpdateIMEState()
// from nsEditor::PostCreate() because GetDesiredIMEState() needs to retrieve
// an editor instance for the element if it's editable element.
// For avoiding such nested IME state updates, we should set
// sIsGettingNewIMEState here and UpdateIMEState() should check it.
GettingNewIMEStateBlocker blocker;
IMEState newIMEState = aContent->GetDesiredIMEState();
PR_LOG(sISMLog, PR_LOG_DEBUG,
("ISM: IMEStateManager::GetNewIMEState() returns { mEnabled=%s, "

View File

@ -146,6 +146,23 @@ protected:
static nsPresContext* sPresContext;
static bool sInstalledMenuKeyboardListener;
static bool sIsTestingIME;
static bool sIsGettingNewIMEState;
class MOZ_STACK_CLASS GettingNewIMEStateBlocker MOZ_FINAL
{
public:
GettingNewIMEStateBlocker()
: mOldValue(IMEStateManager::sIsGettingNewIMEState)
{
IMEStateManager::sIsGettingNewIMEState = true;
}
~GettingNewIMEStateBlocker()
{
IMEStateManager::sIsGettingNewIMEState = mOldValue;
}
private:
bool mOldValue;
};
static IMEContentObserver* sActiveIMEContentObserver;