Bug 1466910 - 4. Don't notify of blur unnecessarily; r?esawin draft
authorJim Chen <nchen@mozilla.com>
Mon, 18 Jun 2018 12:48:46 -0400
changeset 808186 4bbf88cdd42b4049b547e29f2e6280a712becf40
parent 808185 ec9ec3f3ac6cf00a068eb1d91f54911575c90553
child 808187 b0bfb28398ea70c07d1d439fe9e74c6243fd4e2d
push id113305
push userbmo:nchen@mozilla.com
push dateMon, 18 Jun 2018 16:49:25 +0000
reviewersesawin
bugs1466910
milestone62.0a1
Bug 1466910 - 4. Don't notify of blur unnecessarily; r?esawin Right now we always notify Java of input blur. However, when input is rapidly blurred and then focused again, we don't want to generate the unnecessary blur notification, in order to avoid unwanted effects such as the keyboard flashing. MozReview-Commit-ID: HybPuDzjXc1
widget/android/GeckoEditableSupport.cpp
widget/android/GeckoEditableSupport.h
--- a/widget/android/GeckoEditableSupport.cpp
+++ b/widget/android/GeckoEditableSupport.cpp
@@ -1249,27 +1249,29 @@ GeckoEditableSupport::NotifyIME(TextEven
             AsyncNotifyIME(EditableListener::
                            NOTIFY_IME_TO_CANCEL_COMPOSITION);
             break;
         }
 
         case NOTIFY_IME_OF_FOCUS: {
             ALOGIME("IME: NOTIFY_IME_OF_FOCUS");
 
+            mIMEFocusCount++;
+
             RefPtr<GeckoEditableSupport> self(this);
             RefPtr<TextEventDispatcher> dispatcher = aTextEventDispatcher;
 
             // Post an event because we have to flush the text before sending a
             // focus event, and we may not be able to flush text during the
             // NotifyIME call.
             nsAppShell::PostEvent([this, self, dispatcher] {
                 nsCOMPtr<nsIWidget> widget = dispatcher->GetWidget();
 
                 --mIMEMaskEventsCount;
-                if (mIMEMaskEventsCount || !widget || widget->Destroyed()) {
+                if (!mIMEFocusCount || !widget || widget->Destroyed()) {
                     return;
                 }
 
                 mEditable->NotifyIME(
                         EditableListener::NOTIFY_IME_OF_TOKEN);
 
                 if (mIsRemote) {
                     if (!mEditableAttached) {
@@ -1295,20 +1297,25 @@ GeckoEditableSupport::NotifyIME(TextEven
                         EditableListener::NOTIFY_IME_OF_FOCUS);
             });
             break;
         }
 
         case NOTIFY_IME_OF_BLUR: {
             ALOGIME("IME: NOTIFY_IME_OF_BLUR");
 
-            if (!mIMEMaskEventsCount) {
-                mEditable->NotifyIME(EditableListener::NOTIFY_IME_OF_BLUR);
-                OnRemovedFrom(mDispatcher);
-            }
+            mIMEFocusCount--;
+
+            RefPtr<GeckoEditableSupport> self(this);
+            nsAppShell::PostEvent([this, self] {
+                if (!mIMEFocusCount) {
+                    mEditable->NotifyIME(EditableListener::NOTIFY_IME_OF_BLUR);
+                    OnRemovedFrom(mDispatcher);
+                }
+            });
 
             // Mask events because we lost focus. Unmask on the next focus.
             mIMEMaskEventsCount++;
             break;
         }
 
         case NOTIFY_IME_OF_SELECTION_CHANGE: {
             ALOGIME("IME: NOTIFY_IME_OF_SELECTION_CHANGE");
--- a/widget/android/GeckoEditableSupport.h
+++ b/widget/android/GeckoEditableSupport.h
@@ -96,16 +96,17 @@ class GeckoEditableSupport final
     RefPtr<TextEventDispatcher> mDispatcher;
     java::GeckoEditableChild::GlobalRef mEditable;
     bool mEditableAttached;
     InputContext mInputContext;
     AutoTArray<UniquePtr<mozilla::WidgetEvent>, 4> mIMEKeyEvents;
     AutoTArray<IMETextChange, 4> mIMETextChanges;
     RefPtr<TextRangeArray> mIMERanges;
     int32_t mIMEMaskEventsCount; // Mask events when > 0.
+    int32_t mIMEFocusCount; // We are focused when > 0.
     bool mIMEUpdatingContext;
     bool mIMESelectionChanged;
     bool mIMETextChangedDuringFlush;
     bool mIMEMonitorCursor;
 
     static bool sDispatchKeyEventsInCompositionForAnyApps;
 
     void ObservePrefs();
@@ -175,16 +176,17 @@ public:
                          nsWindow* aWindow,
                          java::GeckoEditableChild::Param aEditableChild)
         : mIsRemote(!aWindow)
         , mWindow(aPtr, aWindow)
         , mEditable(aEditableChild)
         , mEditableAttached(!mIsRemote)
         , mIMERanges(new TextRangeArray())
         , mIMEMaskEventsCount(1) // Mask IME events since there's no focus yet
+        , mIMEFocusCount(0)
         , mIMEUpdatingContext(false)
         , mIMESelectionChanged(false)
         , mIMETextChangedDuringFlush(false)
         , mIMEMonitorCursor(false)
     {
         ObservePrefs();
     }