mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1167022 part.2 IMEStateManager::UpdateIMEState() should try to restart to observe focused editor when it's reframed r=smaug+nchen
This commit is contained in:
parent
2af6616c71
commit
f9ae17caea
@ -105,8 +105,7 @@ IMEContentObserver::Init(nsIWidget* aWidget,
|
||||
{
|
||||
MOZ_ASSERT(aEditor, "aEditor must not be null");
|
||||
|
||||
bool firstInitialization =
|
||||
!(mRootContent && !mRootContent->IsInComposedDoc());
|
||||
bool firstInitialization = GetState() != eState_StoppedObserving;
|
||||
if (!firstInitialization) {
|
||||
// If this is now trying to initialize with new contents, all observers
|
||||
// should be registered again for simpler implementation.
|
||||
@ -307,16 +306,47 @@ IMEContentObserver::DisconnectFromEventStateManager()
|
||||
mESM = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
IMEContentObserver::MaybeReinitialize(nsIWidget* aWidget,
|
||||
nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIEditor* aEditor)
|
||||
{
|
||||
if (!IsObservingContent(aPresContext, aContent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetState() == eState_StoppedObserving) {
|
||||
Init(aWidget, aPresContext, aContent, aEditor);
|
||||
}
|
||||
return IsManaging(aPresContext, aContent);
|
||||
}
|
||||
|
||||
bool
|
||||
IMEContentObserver::IsManaging(nsPresContext* aPresContext,
|
||||
nsIContent* aContent)
|
||||
{
|
||||
return GetState() == eState_Observing &&
|
||||
IsObservingContent(aPresContext, aContent);
|
||||
}
|
||||
|
||||
IMEContentObserver::State
|
||||
IMEContentObserver::GetState() const
|
||||
{
|
||||
if (!mSelection || !mRootContent || !mEditableNode) {
|
||||
return false; // failed to initialize.
|
||||
return eState_NotObserving; // failed to initialize or finalized.
|
||||
}
|
||||
if (!mRootContent->IsInComposedDoc()) {
|
||||
return false; // the focused editor has already been reframed.
|
||||
// the focused editor has already been reframed.
|
||||
return eState_StoppedObserving;
|
||||
}
|
||||
return eState_Observing;
|
||||
}
|
||||
|
||||
bool
|
||||
IMEContentObserver::IsObservingContent(nsPresContext* aPresContext,
|
||||
nsIContent* aContent) const
|
||||
{
|
||||
return mEditableNode == IMEStateManager::GetRootEditableNode(aPresContext,
|
||||
aContent);
|
||||
}
|
||||
|
@ -72,6 +72,17 @@ public:
|
||||
* storing the instance.
|
||||
*/
|
||||
void DisconnectFromEventStateManager();
|
||||
/**
|
||||
* MaybeReinitialize() tries to restart to observe the editor's root node.
|
||||
* This is useful when the editor is reframed and all children are replaced
|
||||
* with new node instances.
|
||||
* @return Returns true if the instance is managing the content.
|
||||
* Otherwise, false.
|
||||
*/
|
||||
bool MaybeReinitialize(nsIWidget* aWidget,
|
||||
nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIEditor* aEditor);
|
||||
bool IsManaging(nsPresContext* aPresContext, nsIContent* aContent);
|
||||
bool IsEditorHandlingEventForComposition() const;
|
||||
bool KeepAliveDuringDeactive() const
|
||||
@ -133,6 +144,14 @@ public:
|
||||
private:
|
||||
~IMEContentObserver() {}
|
||||
|
||||
enum State {
|
||||
eState_NotObserving,
|
||||
eState_StoppedObserving,
|
||||
eState_Observing
|
||||
};
|
||||
State GetState() const;
|
||||
bool IsObservingContent(nsPresContext* aPresContext,
|
||||
nsIContent* aContent) const;
|
||||
void MaybeNotifyIMEOfTextChange(const TextChangeData& aTextChangeData);
|
||||
void MaybeNotifyIMEOfSelectionChange(bool aCausedByComposition);
|
||||
void MaybeNotifyIMEOfPositionChange();
|
||||
|
@ -649,9 +649,23 @@ IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState,
|
||||
return;
|
||||
}
|
||||
|
||||
// If the IMEContentObserver instance isn't managing the editor's current
|
||||
// editable root content, the editor frame might be reframed. We should
|
||||
// recreate the instance at that time.
|
||||
// Even if there is active IMEContentObserver, it may not be observing the
|
||||
// editor with current editable root content due to reframed. In such case,
|
||||
// We should try to reinitialize the IMEContentObserver.
|
||||
if (sActiveIMEContentObserver && IsIMEObserverNeeded(aNewIMEState)) {
|
||||
PR_LOG(sISMLog, PR_LOG_DEBUG,
|
||||
("ISM: IMEStateManager::UpdateIMEState(), try to reinitialize the "
|
||||
"active IMEContentObserver"));
|
||||
if (!sActiveIMEContentObserver->MaybeReinitialize(widget, sPresContext,
|
||||
aContent, aEditor)) {
|
||||
PR_LOG(sISMLog, PR_LOG_ERROR,
|
||||
("ISM: IMEStateManager::UpdateIMEState(), failed to reinitialize the "
|
||||
"active IMEContentObserver"));
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no active IMEContentObserver or it isn't observing the
|
||||
// editor correctly, we should recreate it.
|
||||
bool createTextStateManager =
|
||||
(!sActiveIMEContentObserver ||
|
||||
!sActiveIMEContentObserver->IsManaging(sPresContext, aContent));
|
||||
@ -1128,18 +1142,9 @@ IMEStateManager::GetRootEditableNode(nsPresContext* aPresContext,
|
||||
|
||||
// static
|
||||
bool
|
||||
IMEStateManager::IsEditableIMEState(nsIWidget* aWidget)
|
||||
IMEStateManager::IsIMEObserverNeeded(const IMEState& aState)
|
||||
{
|
||||
switch (aWidget->GetInputContext().mIMEState.mEnabled) {
|
||||
case IMEState::ENABLED:
|
||||
case IMEState::PASSWORD:
|
||||
return true;
|
||||
case IMEState::PLUGIN:
|
||||
case IMEState::DISABLED:
|
||||
return false;
|
||||
default:
|
||||
MOZ_CRASH("Unknown IME enable state");
|
||||
}
|
||||
return aState.IsEditable();
|
||||
}
|
||||
|
||||
// static
|
||||
@ -1193,8 +1198,8 @@ IMEStateManager::CreateIMEContentObserver(nsIEditor* aEditor)
|
||||
return; // Sometimes, there are no widgets.
|
||||
}
|
||||
|
||||
// If it's not text ediable, we don't need to create IMEContentObserver.
|
||||
if (!IsEditableIMEState(widget)) {
|
||||
// If it's not text editable, we don't need to create IMEContentObserver.
|
||||
if (!IsIMEObserverNeeded(widget->GetInputContext().mIMEState)) {
|
||||
MOZ_LOG(sISMLog, PR_LOG_DEBUG,
|
||||
("ISM: IMEStateManager::CreateIMEContentObserver() doesn't create "
|
||||
"IMEContentObserver because of non-editable IME state"));
|
||||
|
@ -157,7 +157,7 @@ protected:
|
||||
|
||||
static bool IsEditable(nsINode* node);
|
||||
|
||||
static bool IsEditableIMEState(nsIWidget* aWidget);
|
||||
static bool IsIMEObserverNeeded(const IMEState& aState);
|
||||
|
||||
static nsIContent* sContent;
|
||||
static nsPresContext* sPresContext;
|
||||
|
Loading…
Reference in New Issue
Block a user