Bug 1148590 - Ignore IME notifications outside of the focused editor. r=esawin, a=lmandel
authorJim Chen <nchen@mozilla.com>
Fri, 24 Apr 2015 08:32:00 -0400
changeset 265737 e429aa5f271c6df540d38651f324b5a40eb1037b
parent 265736 58ab5d4e0e0a07f855a8bfbfcdbde5387a1ee0b4
child 265738 e4a72e7cc9c1bd64b77e1ed82b60382862e4b55b
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersesawin, lmandel
bugs1148590
milestone39.0a2
Bug 1148590 - Ignore IME notifications outside of the focused editor. r=esawin, a=lmandel Bug 1148590 - Clear existing focus when closing selection; r=capella
mobile/android/chrome/content/SelectionHandler.js
widget/android/nsWindow.cpp
--- a/mobile/android/chrome/content/SelectionHandler.js
+++ b/mobile/android/chrome/content/SelectionHandler.js
@@ -380,16 +380,22 @@ var SelectionHandler = {
   startSelection: function sh_startSelection(aElement, aOptions = { mode: SelectionHandler.SELECT_ALL }) {
     // Clear out any existing active selection
     this._closeSelection();
 
     if (this._isNonTextInputElement(aElement)) {
       return this.START_ERROR_NONTEXT_INPUT;
     }
 
+    const focus = Services.focus.focusedWindow;
+    if (focus) {
+      // Make sure any previous focus is cleared.
+      Services.focus.clearFocus(focus);
+    }
+
     this._initTargetInfo(aElement, this.TYPE_SELECTION);
 
     // Perform the appropriate selection method, if we can't determine method, or it fails, return
     let selectionResult = this._performSelection(aOptions);
     if (selectionResult !== this.ERROR_NONE) {
       this._deactivate();
       return selectionResult;
     }
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -2,16 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <android/log.h>
 #include <math.h>
 #include <unistd.h>
 
+#include "mozilla/IMEStateManager.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/unused.h"
@@ -25,16 +26,17 @@ using mozilla::unused;
 
 #include "nsAppShell.h"
 #include "nsIdleService.h"
 #include "nsWindow.h"
 #include "nsIObserverService.h"
 #include "nsFocusManager.h"
 #include "nsIWidgetListener.h"
 #include "nsViewManager.h"
+#include "nsISelection.h"
 
 #include "nsIDOMSimpleGestureEvent.h"
 
 #include "nsGkAtoms.h"
 #include "nsWidgetsCID.h"
 #include "nsGfxCIID.h"
 
 #include "gfxContext.h"
@@ -2188,48 +2190,60 @@ nsWindow::PostFlushIMEChanges()
     AndroidGeckoEvent *event = AndroidGeckoEvent::MakeIMEEvent(
             AndroidGeckoEvent::IME_FLUSH_CHANGES);
     nsAppShell::gAppShell->PostEvent(event);
 }
 
 void
 nsWindow::FlushIMEChanges()
 {
+    // Only send change notifications if we are *not* masking events,
+    // i.e. if we have a focused editor,
+    NS_ENSURE_TRUE_VOID(!mIMEMaskEventsCount);
+
+    nsCOMPtr<nsISelection> imeSelection;
+    nsCOMPtr<nsIContent> imeRoot;
+
+    // If we are receiving notifications, we must have selection/root content.
+    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(IMEStateManager::GetFocusSelectionAndRoot(
+            getter_AddRefs(imeSelection), getter_AddRefs(imeRoot))));
+
     nsRefPtr<nsWindow> kungFuDeathGrip(this);
+
     for (uint32_t i = 0; i < mIMETextChanges.Length(); i++) {
         IMEChange &change = mIMETextChanges[i];
 
         if (change.mStart == change.mOldEnd &&
                 change.mStart == change.mNewEnd) {
             continue;
         }
 
         WidgetQueryContentEvent event(true, NS_QUERY_TEXT_CONTENT, this);
 
         if (change.mNewEnd != change.mStart) {
             InitEvent(event, nullptr);
             event.InitForQueryTextContent(change.mStart,
                                           change.mNewEnd - change.mStart);
             DispatchEvent(&event);
-            if (!event.mSucceeded)
-                return;
+            NS_ENSURE_TRUE_VOID(event.mSucceeded);
+            NS_ENSURE_TRUE_VOID(event.mReply.mContentsRoot == imeRoot.get());
         }
 
         GeckoAppShell::NotifyIMEChange(event.mReply.mString, change.mStart,
                                        change.mOldEnd, change.mNewEnd);
     }
     mIMETextChanges.Clear();
 
     if (mIMESelectionChanged) {
         WidgetQueryContentEvent event(true, NS_QUERY_SELECTED_TEXT, this);
         InitEvent(event, nullptr);
 
         DispatchEvent(&event);
-        if (!event.mSucceeded)
-            return;
+        NS_ENSURE_TRUE_VOID(event.mSucceeded);
+        NS_ENSURE_TRUE_VOID(event.mReply.mContentsRoot == imeRoot.get());
 
         GeckoAppShell::NotifyIMEChange(EmptyString(),
                                        int32_t(event.GetSelectionStart()),
                                        int32_t(event.GetSelectionEnd()), -1);
         mIMESelectionChanged = false;
     }
 }