Bug 814689 - Only use key events for plugins; r=cpeterson
authorJim Chen <nchen@mozilla.com>
Wed, 26 Dec 2012 10:06:53 -0500
changeset 126149 d6c5a0ec5757e489ef9417bdb5c98bf1fb2ab305
parent 126148 7d531752a0fb293d9c40ab40f6d7b2a698c0fb55
child 126150 acb02d013052583761171be66d214d4839a80dd4
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpeterson
bugs814689
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 814689 - Only use key events for plugins; r=cpeterson
mobile/android/base/GeckoEditable.java
mobile/android/base/GeckoInputConnection.java
--- a/mobile/android/base/GeckoEditable.java
+++ b/mobile/android/base/GeckoEditable.java
@@ -527,18 +527,16 @@ final class GeckoEditable
             public void run() {
                 // Make sure there are no other things going on
                 mActionQueue.syncWithGecko();
                 if (type == NOTIFY_IME_FOCUSCHANGE) {
                     if (state == IME_FOCUS_STATE_BLUR) {
                         mFocused = false;
                     } else {
                         mFocused = true;
-                        LayerView v = GeckoApp.mAppContext.getLayerView();
-                        v.setInputConnectionHandler((InputConnectionHandler)mListener);
                         // Unmask events on the Gecko side
                         GeckoAppShell.sendEventToGecko(GeckoEvent.createIMEEvent(
                                 GeckoEvent.IME_ACKNOWLEDGE_FOCUS));
                     }
                 }
                 mListener.notifyIME(type, state);
             }
         });
@@ -550,16 +548,23 @@ final class GeckoEditable
         if (DEBUG) {
             // GeckoEditableListener methods should all be called from the Gecko thread
             GeckoApp.assertOnGeckoThread();
         }
         geckoPostToUI(new Runnable() {
             public void run() {
                 // Make sure there are no other things going on
                 mActionQueue.syncWithGecko();
+                // Set InputConnectionHandler in notifyIMEEnabled because
+                // GeckoInputConnection.notifyIMEEnabled calls restartInput() which will invoke
+                // InputConnectionHandler.onCreateInputConnection
+                LayerView v = GeckoApp.mAppContext.getLayerView();
+                if (v != null) {
+                    v.setInputConnectionHandler((InputConnectionHandler)mListener);
+                }
                 mListener.notifyIMEEnabled(state, typeHint,
                                            modeHint, actionHint);
             }
         });
     }
 
     @Override
     public void onSelectionChange(final int start, final int end) {
--- a/mobile/android/base/GeckoInputConnection.java
+++ b/mobile/android/base/GeckoInputConnection.java
@@ -48,30 +48,33 @@ class GeckoInputConnection
 
     private final GeckoEditableClient mEditableClient;
     protected int mBatchEditCount;
     private ExtractedTextRequest mUpdateRequest;
     private final ExtractedText mUpdateExtract = new ExtractedText();
     private boolean mBatchSelectionChanged;
     private boolean mBatchTextChanged;
     private Runnable mRestartInputRunnable;
+    private final InputConnection mPluginInputConnection;
 
     public static GeckoEditableListener create(View targetView,
                                                GeckoEditableClient editable) {
         if (DEBUG)
             return DebugGeckoInputConnection.create(targetView, editable);
         else
             return new GeckoInputConnection(targetView, editable);
     }
 
     protected GeckoInputConnection(View targetView,
                                    GeckoEditableClient editable) {
         super(targetView, true);
         mEditableClient = editable;
         mIMEState = IME_STATE_DISABLED;
+        // InputConnection for plugins, which don't have full editors
+        mPluginInputConnection = new BaseInputConnection(targetView, false);
     }
 
     @Override
     public synchronized boolean beginBatchEdit() {
         mBatchEditCount++;
         mEditableClient.setUpdateGecko(false);
         return true;
     }
@@ -282,32 +285,34 @@ class GeckoInputConnection
 
     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
         outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
         outAttrs.imeOptions = EditorInfo.IME_ACTION_NONE;
         outAttrs.actionLabel = null;
 
         if (mIMEState == IME_STATE_PASSWORD)
             outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD;
+        else if (mIMEState == IME_STATE_PLUGIN)
+            outAttrs.inputType = InputType.TYPE_NULL; // "send key events" mode
         else if (mIMETypeHint.equalsIgnoreCase("url"))
             outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_URI;
         else if (mIMETypeHint.equalsIgnoreCase("email"))
             outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
         else if (mIMETypeHint.equalsIgnoreCase("search"))
             outAttrs.imeOptions = EditorInfo.IME_ACTION_SEARCH;
         else if (mIMETypeHint.equalsIgnoreCase("tel"))
             outAttrs.inputType = InputType.TYPE_CLASS_PHONE;
         else if (mIMETypeHint.equalsIgnoreCase("number") ||
                  mIMETypeHint.equalsIgnoreCase("range"))
             outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
                                  | InputType.TYPE_NUMBER_FLAG_SIGNED
                                  | InputType.TYPE_NUMBER_FLAG_DECIMAL;
         else if (mIMETypeHint.equalsIgnoreCase("week") ||
                  mIMETypeHint.equalsIgnoreCase("month"))
-             outAttrs.inputType = InputType.TYPE_CLASS_DATETIME
+            outAttrs.inputType = InputType.TYPE_CLASS_DATETIME
                                   | InputType.TYPE_DATETIME_VARIATION_DATE;
         else if (mIMEModeHint.equalsIgnoreCase("numeric"))
             outAttrs.inputType = InputType.TYPE_CLASS_NUMBER |
                                  InputType.TYPE_NUMBER_FLAG_SIGNED |
                                  InputType.TYPE_NUMBER_FLAG_DECIMAL;
         else if (mIMEModeHint.equalsIgnoreCase("digit"))
             outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;
         else {
@@ -355,16 +360,22 @@ class GeckoInputConnection
         // If the user has changed IMEs, then notify input method observers.
         if (mCurrentInputMethod != prevInputMethod) {
             FormAssistPopup popup = app.mFormAssistPopup;
             if (popup != null) {
                 popup.onInputMethodChanged(mCurrentInputMethod);
             }
         }
 
+        if (mIMEState == IME_STATE_PLUGIN) {
+            // Since we are using a temporary string as the editable, the selection is at 0
+            outAttrs.initialSelStart = 0;
+            outAttrs.initialSelEnd = 0;
+            return mPluginInputConnection;
+        }
         Editable editable = getEditable();
         outAttrs.initialSelStart = Selection.getSelectionStart(editable);
         outAttrs.initialSelEnd = Selection.getSelectionEnd(editable);
         return this;
     }
 
     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
         return false;
@@ -394,16 +405,17 @@ class GeckoInputConnection
                 break;
         }
 
         View view = getView();
         KeyListener keyListener = TextKeyListener.getInstance();
 
         // KeyListener returns true if it handled the event for us.
         if (mIMEState == IME_STATE_DISABLED ||
+                mIMEState == IME_STATE_PLUGIN ||
                 keyCode == KeyEvent.KEYCODE_ENTER ||
                 keyCode == KeyEvent.KEYCODE_DEL ||
                 keyCode == KeyEvent.KEYCODE_TAB ||
                 (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
                 !keyListener.onKeyDown(view, getEditable(), keyCode, event)) {
             mEditableClient.sendEvent(GeckoEvent.createKeyEvent(event));
         }
         return true;
@@ -425,16 +437,17 @@ class GeckoInputConnection
             default:
                 break;
         }
 
         View view = getView();
         KeyListener keyListener = TextKeyListener.getInstance();
 
         if (mIMEState == IME_STATE_DISABLED ||
+            mIMEState == IME_STATE_PLUGIN ||
             keyCode == KeyEvent.KEYCODE_ENTER ||
             keyCode == KeyEvent.KEYCODE_DEL ||
             (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
             !keyListener.onKeyUp(view, getEditable(), keyCode, event)) {
             mEditableClient.sendEvent(GeckoEvent.createKeyEvent(event));
         }
 
         return true;