Bug 843048 - Delay setting IME context on Gecko thread instead of Java thread; r=cpeterson
authorJim Chen <nchen@mozilla.com>
Tue, 05 Mar 2013 15:24:35 +0000
changeset 123838 ec8fb77b41af19effc00f1a16777621aad73a781
parent 123837 39abe4f679552ba98389700b2eff9773280424df
child 123839 9c92da2ea3d7bdc5cf625e62f5fd1cf5c91c919d
push id1401
push userpastithas@mozilla.com
push dateThu, 07 Mar 2013 07:26:45 +0000
treeherderfx-team@ee4879719f78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpeterson
bugs843048
milestone22.0a1
Bug 843048 - Delay setting IME context on Gecko thread instead of Java thread; r=cpeterson
mobile/android/base/GeckoInputConnection.java
widget/android/AndroidJavaWrappers.h
widget/android/nsWindow.cpp
widget/android/nsWindow.h
--- a/mobile/android/base/GeckoInputConnection.java
+++ b/mobile/android/base/GeckoInputConnection.java
@@ -849,26 +849,21 @@ class GeckoInputConnection
         if (v == null || !v.hasFocus()) {
             // When using Find In Page, we can still receive notifyIMEEnabled calls due to the
             // selection changing when highlighting. However in this case we don't want to reset/
             // show/hide the keyboard because the find box has the focus and is taking input from
             // the keyboard.
             return;
         }
         restartInput();
-        GeckoApp.mAppContext.mMainHandler.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                if (mIMEState == IME_STATE_DISABLED) {
-                    hideSoftInput();
-                } else {
-                    showSoftInput();
-                }
-            }
-        }, 200); // Delay 200ms to prevent repeated IME showing/hiding
+        if (mIMEState == IME_STATE_DISABLED) {
+            hideSoftInput();
+        } else {
+            showSoftInput();
+        }
     }
 }
 
 final class DebugGeckoInputConnection
         extends GeckoInputConnection
         implements InvocationHandler {
 
     private InputConnection mProxy;
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -777,17 +777,18 @@ public:
     enum {
         IME_SYNCHRONIZE = 0,
         IME_REPLACE_TEXT = 1,
         IME_SET_SELECTION = 2,
         IME_ADD_COMPOSITION_RANGE = 3,
         IME_UPDATE_COMPOSITION = 4,
         IME_REMOVE_COMPOSITION = 5,
         IME_ACKNOWLEDGE_FOCUS = 6,
-        IME_FLUSH_CHANGES = 7
+        IME_FLUSH_CHANGES = 7,
+        IME_UPDATE_CONTEXT = 8
     };
 };
 
 class nsJNIString : public nsString
 {
 public:
     nsJNIString(jstring jstr, JNIEnv *jenv);
 };
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -157,16 +157,17 @@ nsWindow::DumpWindows(const nsTArray<nsW
 nsWindow::nsWindow() :
     mIsVisible(false),
     mParent(nullptr),
     mFocus(nullptr),
     mIMEComposing(false),
     mIMEMaskSelectionUpdate(false),
     mIMEMaskTextUpdate(false),
     mIMEMaskEventsCount(1), // Mask IME events since there's no focus yet
+    mIMEUpdatingContext(false),
     mIMESelectionChanged(false)
 {
 }
 
 nsWindow::~nsWindow()
 {
     gTopLevelWindows.RemoveElement(this);
     nsWindow *top = FindTopLevel();
@@ -1721,16 +1722,23 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             // Use 'INT32_MAX / 2' here because subsequent text changes might
             // combine with this text change, and overflow might occur if
             // we just use INT32_MAX
             OnIMETextChange(0, INT32_MAX / 2, INT32_MAX / 2);
             FlushIMEChanges();
         }
         AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT, 0);
         return;
+    } else if (ae->Action() == AndroidGeckoEvent::IME_UPDATE_CONTEXT) {
+        AndroidBridge::NotifyIMEEnabled(mInputContext.mIMEState.mEnabled,
+                                        mInputContext.mHTMLInputType,
+                                        mInputContext.mHTMLInputInputmode,
+                                        mInputContext.mActionHint);
+        mIMEUpdatingContext = false;
+        return;
     }
     if (mIMEMaskEventsCount > 0) {
         // Still reply to events, but don't do anything else
         if (ae->Action() == AndroidGeckoEvent::IME_SYNCHRONIZE ||
             ae->Action() == AndroidGeckoEvent::IME_REPLACE_TEXT) {
             AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT, 0);
         }
         return;
@@ -1981,29 +1989,35 @@ nsWindow::SetInputContext(const InputCon
     if (aContext.mIMEState.mEnabled != IMEState::DISABLED && 
         aContext.mIMEState.mEnabled != IMEState::PLUGIN &&
         Preferences::GetBool("content.ime.strict_policy", false) &&
         !aAction.ContentGotFocusByTrustedCause() &&
         !aAction.UserMightRequestOpenVKB()) {
         return;
     }
 
-    int enabled = int(aContext.mIMEState.mEnabled);
+    IMEState::Enabled enabled = aContext.mIMEState.mEnabled;
 
     // Only show the virtual keyboard for plugins if mOpen is set appropriately.
     // This avoids showing it whenever a plugin is focused. Bug 747492
     if (aContext.mIMEState.mEnabled == IMEState::PLUGIN &&
         aContext.mIMEState.mOpen != IMEState::OPEN) {
-        enabled = int(IMEState::DISABLED);
+        enabled = IMEState::DISABLED;
     }
 
-    AndroidBridge::NotifyIMEEnabled(enabled,
-                                    aContext.mHTMLInputType,
-                                    aContext.mHTMLInputInputmode,
-                                    aContext.mActionHint);
+    mInputContext.mIMEState.mEnabled = enabled;
+
+    if (mIMEUpdatingContext) {
+        return;
+    }
+    AndroidGeckoEvent *event = new AndroidGeckoEvent(
+            AndroidGeckoEvent::IME_EVENT,
+            AndroidGeckoEvent::IME_UPDATE_CONTEXT);
+    nsAppShell::gAppShell->PostEvent(event);
+    mIMEUpdatingContext = true;
 }
 
 NS_IMETHODIMP_(InputContext)
 nsWindow::GetInputContext()
 {
     mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
     // We assume that there is only one context per process on Android
     mInputContext.mNativeIMEContext = nullptr;
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -181,16 +181,17 @@ protected:
 
     nsCOMPtr<nsIIdleServiceInternal> mIdleService;
 
     bool mIMEComposing;
     bool mIMEMaskSelectionUpdate, mIMEMaskTextUpdate;
     int32_t mIMEMaskEventsCount; // Mask events when > 0
     nsString mIMEComposingText;
     nsAutoTArray<nsTextRange, 4> mIMERanges;
+    bool mIMEUpdatingContext;
 
     struct IMEChange {
         int32_t mStart, mOldEnd, mNewEnd;
 
         IMEChange() :
             mStart(-1), mOldEnd(-1), mNewEnd(-1)
         {
         }