diff --git a/dom/events/IMEStateManager.cpp b/dom/events/IMEStateManager.cpp index 9b2944496468..70e1bb78a536 100644 --- a/dom/events/IMEStateManager.cpp +++ b/dom/events/IMEStateManager.cpp @@ -197,9 +197,14 @@ IMEStateManager::Shutdown() void IMEStateManager::OnTabParentDestroying(TabParent* aTabParent) { + if (sFocusedIMETabParent == aTabParent) { + NotifyIMEOfBlurForChildProcess(); + } + if (sActiveTabParent != aTabParent) { return; } + MOZ_LOG(sISMLog, LogLevel::Info, ("OnTabParentDestroying(aTabParent=0x%p), " "The active TabParent is being destroyed", aTabParent)); @@ -207,8 +212,7 @@ IMEStateManager::OnTabParentDestroying(TabParent* aTabParent) // The active remote process might have crashed. sActiveTabParent = nullptr; - // TODO: Need to cancel composition without TextComposition and make - // disable IME. + // XXX: Need to disable IME? } // static @@ -219,6 +223,7 @@ IMEStateManager::WidgetDestroyed(nsIWidget* aWidget) sWidget = nullptr; } if (sFocusedIMEWidget == aWidget) { + NotifyIMEOfBlurForChildProcess(); sFocusedIMEWidget = nullptr; } if (sActiveInputContextWidget == aWidget) { @@ -246,6 +251,27 @@ IMEStateManager::StopIMEStateManagement() DestroyIMEContentObserver(); } +// static +void +IMEStateManager::NotifyIMEOfBlurForChildProcess() +{ + MOZ_LOG(sISMLog, LogLevel::Debug, + ("NotifyIMEOfBlurForChildProcess(), sFocusedIMETabParent=0x%p, " + "sFocusedIMEWidget=0x%p", + sFocusedIMETabParent.get(), sFocusedIMEWidget)); + + if (!sFocusedIMETabParent) { + MOZ_ASSERT(!sFocusedIMEWidget); + return; + } + + MOZ_ASSERT(sFocusedIMEWidget); + NotifyIME(NOTIFY_IME_OF_BLUR, sFocusedIMEWidget, sFocusedIMETabParent); + + MOZ_ASSERT(!sFocusedIMETabParent); + MOZ_ASSERT(!sFocusedIMEWidget); +} + // static void IMEStateManager::MaybeStartOffsetUpdatedInChild(nsIWidget* aWidget, @@ -488,13 +514,19 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext, // process while the process has IME focus too, we need to notify IME of // blur here because it may be too late the blur notification to reach // this process especially when closing active window. - if (sFocusedIMETabParent && + // However, don't send blur if we're being deactivated and IME wants to + // keep composition during deactive because notifying blur will commit + // or cancel composition. + if (sFocusedIMETabParent && sFocusedIMEWidget && + (aPresContext || + !sFocusedIMEWidget->IMENotificationRequestsRef(). + WantDuringDeactive()) && !IsSameProcess(sFocusedIMETabParent, newTabParent)) { MOZ_LOG(sISMLog, LogLevel::Info, (" OnChangeFocusInternal(), notifying IME of blur of previous focused " "remote process because it may be too late actual notification to " "reach this process")); - NotifyIME(NOTIFY_IME_OF_BLUR, sFocusedIMEWidget, sFocusedIMETabParent); + NotifyIMEOfBlurForChildProcess(); } } diff --git a/dom/events/IMEStateManager.h b/dom/events/IMEStateManager.h index a11b8a8ce0a1..89a60c5b7e4d 100644 --- a/dom/events/IMEStateManager.h +++ b/dom/events/IMEStateManager.h @@ -274,6 +274,12 @@ protected: static void CreateIMEContentObserver(EditorBase* aEditorBase); static void DestroyIMEContentObserver(); + /** + * NotifyIMEOfBlurForChildProcess() tries to send blur notification when + * a remote process has IME focus. Otherwise, do nothing. + */ + static void NotifyIMEOfBlurForChildProcess(); + static bool IsEditable(nsINode* node); static bool IsIMEObserverNeeded(const IMEState& aState);