bug 589879 - All input fields labeled with a go button, which doesn't do anything without special handling r=roc a=blocking-fennec
authorBrad Lassey <blassey@mozilla.com>
Tue, 23 Nov 2010 21:12:53 -0500
changeset 58121 2aceea4f527bfa32a2db95f7b465ef4961b24a95
parent 58120 052a96664eba9433af0f58a515b25f53b770a02b
child 58122 4deec1586536fe0773aab091b4c259b3d0d753a7
push id17166
push userblassey@mozilla.com
push dateWed, 24 Nov 2010 02:17:51 +0000
treeherdermozilla-central@4deec1586536 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, blocking-fennec
bugs589879
milestone2.0b8pre
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 589879 - All input fields labeled with a go button, which doesn't do anything without special handling r=roc a=blocking-fennec
content/base/src/nsGkAtomList.h
content/events/src/nsIMEStateManager.cpp
dom/ipc/PBrowser.ipdl
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
embedding/android/GeckoApp.java
embedding/android/GeckoAppShell.java
embedding/android/GeckoSurfaceView.java
toolkit/content/widgets/autocomplete.xml
toolkit/content/widgets/textbox.xml
widget/public/nsIWidget.h
widget/src/android/AndroidBridge.cpp
widget/src/android/AndroidBridge.h
widget/src/android/nsWindow.cpp
widget/src/xpwidgets/PuppetWidget.cpp
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -583,16 +583,17 @@ GK_ATOM(modifiers, "modifiers")
 GK_ATOM(monochrome, "monochrome")
 GK_ATOM(mousedown, "mousedown")
 GK_ATOM(mousemove, "mousemove")
 GK_ATOM(mouseout, "mouseout")
 GK_ATOM(mouseover, "mouseover")
 GK_ATOM(mousethrough, "mousethrough")
 GK_ATOM(mouseup, "mouseup")
 GK_ATOM(moz_opaque, "moz-opaque")
+GK_ATOM(moz_action_hint, "mozactionhint")
 GK_ATOM(x_moz_errormessage, "x-moz-errormessage")
 GK_ATOM(msthemecompatible, "msthemecompatible")
 GK_ATOM(multicol, "multicol")
 GK_ATOM(multiple, "multiple")
 GK_ATOM(name, "name")
 GK_ATOM(_namespace, "namespace")
 GK_ATOM(namespaceAlias, "namespace-alias")
 GK_ATOM(namespaceUri, "namespace-uri")
--- a/content/events/src/nsIMEStateManager.cpp
+++ b/content/events/src/nsIMEStateManager.cpp
@@ -269,20 +269,24 @@ nsIMEStateManager::SetIMEState(PRUint32 
   if (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
     nsIWidget_MOZILLA_2_0_BRANCH* widget2 = static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(aWidget);
     if (!widget2)
       return;
 
     PRUint32 state = nsContentUtils::GetWidgetStatusFromIMEStatus(aState);
     IMEContext context;
     context.mStatus = state;
-
-    if (aContent && aContent->Tag() == nsGkAtoms::input) {
+    
+    if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
+        (aContent->Tag() == nsGkAtoms::input ||
+         aContent->Tag() == nsGkAtoms::textarea)) {
       aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
                         context.mHTMLInputType);
+      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
+                        context.mActionHint);
     }
 
     widget2->SetInputMode(context);
 
     nsContentUtils::AddScriptRunner(new IMEEnabledStateChangedEvent(state));
   }
   if (aState & nsIContent::IME_STATUS_MASK_OPENED) {
     PRBool open = !!(aState & nsIContent::IME_STATUS_OPEN);
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -164,17 +164,17 @@ parent:
      *    widget should return empty string for composition
      *  if cancel is PR_FALSE,
      *    widget should return the current composition text
      */
     sync EndIMEComposition(PRBool cancel) returns (nsString composition);
 
     sync GetIMEEnabled() returns (PRUint32 value);
 
-    SetInputMode(PRUint32 value, nsString type);
+    SetInputMode(PRUint32 value, nsString type, nsString actionHint);
 
     sync GetIMEOpenState() returns (PRBool value);
 
     SetIMEOpenState(PRBool value);
 
     PContentPermissionRequest(nsCString aType, URI uri);
 
     PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -490,27 +490,28 @@ TabParent::RecvGetIMEEnabled(PRUint32* a
   if (widget2) {
     widget2->GetInputMode(context);
     *aValue = context.mStatus;
   }
   return true;
 }
 
 bool
-TabParent::RecvSetInputMode(const PRUint32& aValue, const nsString& aType)
+TabParent::RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget || !AllowContentIME())
     return true;
 
   nsIWidget_MOZILLA_2_0_BRANCH* widget2 = static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(widget.get());
 
   IMEContext context;
   context.mStatus = aValue;
   context.mHTMLInputType.Assign(aType);
+  context.mActionHint.Assign(aAction);
   widget2->SetInputMode(context);
 
   nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
   if (!observerService)
     return true;
 
   nsAutoString state;
   state.AppendInt(aValue);
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -97,17 +97,17 @@ public:
                                          const PRUint32& aNewEnd);
     virtual bool RecvNotifyIMESelection(const PRUint32& aSeqno,
                                         const PRUint32& aAnchor,
                                         const PRUint32& aFocus);
     virtual bool RecvNotifyIMETextHint(const nsString& aText);
     virtual bool RecvEndIMEComposition(const PRBool& aCancel,
                                        nsString* aComposition);
     virtual bool RecvGetIMEEnabled(PRUint32* aValue);
-    virtual bool RecvSetInputMode(const PRUint32& aValue, const nsString& aType);
+    virtual bool RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction);
     virtual bool RecvGetIMEOpenState(PRBool* aValue);
     virtual bool RecvSetIMEOpenState(const PRBool& aValue);
     virtual PContentDialogParent* AllocPContentDialog(const PRUint32& aType,
                                                       const nsCString& aName,
                                                       const nsCString& aFeatures,
                                                       const InfallibleTArray<int>& aIntParams,
                                                       const InfallibleTArray<nsString>& aStringParams);
     virtual bool DeallocPContentDialog(PContentDialogParent* aDialog)
--- a/embedding/android/GeckoApp.java
+++ b/embedding/android/GeckoApp.java
@@ -341,16 +341,21 @@ abstract public class GeckoApp
             case KeyEvent.KEYCODE_DEL:
                 // See comments in GeckoInputConnection.onKeyDel
                 if (surfaceView != null &&
                     surfaceView.inputConnection != null &&
                     surfaceView.inputConnection.onKeyDel()) {
                     return true;
                 }
                 break;
+            case KeyEvent.KEYCODE_ENTER:
+                if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 &&
+                    surfaceView.mIMEActionHint.equalsIgnoreCase("next"))
+                    event = new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB);
+                break;
             default:
                 break;
         }
         // KeyListener returns true if it handled the event for us.
         if (GeckoApp.surfaceView.mIMEState == GeckoSurfaceView.IME_STATE_DISABLED ||
             keyCode == KeyEvent.KEYCODE_ENTER ||
             !GeckoApp.surfaceView.mKeyListener.onKeyDown(GeckoApp.surfaceView, GeckoApp.surfaceView.mEditable, keyCode, event))
             GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -251,24 +251,26 @@ class GeckoAppShell
 
         case NOTIFY_IME_FOCUSCHANGE:
             GeckoApp.surfaceView.mIMEFocus = state != 0;
             IMEStateUpdater.resetIME();
             break;
         }
     }
 
-    public static void notifyIMEEnabled(int state, String hint) {
+    public static void notifyIMEEnabled(int state, String typeHint, 
+                                        String actionHint) {
         if (GeckoApp.surfaceView == null)
             return;
 
         /* When IME is 'disabled', IME processing is disabled.
             In addition, the IME UI is hidden */
         GeckoApp.surfaceView.mIMEState = state;
-        GeckoApp.surfaceView.mIMEHint = hint;
+        GeckoApp.surfaceView.mIMETypeHint = typeHint;
+        GeckoApp.surfaceView.mIMEActionHint = actionHint;
         IMEStateUpdater.enableIME();
     }
 
     public static void notifyIMEChange(String text, int start, int end, int newEnd) {
         if (GeckoApp.surfaceView == null ||
             GeckoApp.surfaceView.inputConnection == null)
             return;
 
--- a/embedding/android/GeckoSurfaceView.java
+++ b/embedding/android/GeckoSurfaceView.java
@@ -82,17 +82,18 @@ class GeckoSurfaceView
         mBufferWidth = 0;
         mBufferHeight = 0;
 
         mSurfaceLock = new ReentrantLock();
 
         mEditableFactory = Editable.Factory.getInstance();
         setupEditable("");
         mIMEState = IME_STATE_DISABLED;
-        mIMEHint = "";
+        mIMETypeHint = "";
+        mIMEActionHint = "";
     }
 
     protected void finalize() throws Throwable {
         super.finalize();
     }
 
     /*
      * Called on main thread
@@ -291,38 +292,50 @@ class GeckoSurfaceView
     @Override
     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
         outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
         outAttrs.imeOptions = EditorInfo.IME_ACTION_GO;
         mKeyListener = TextKeyListener.getInstance();
 
         if (mIMEState == IME_STATE_PASSWORD)
             outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD;
-        else if (mIMEHint.equalsIgnoreCase("url"))
+        else if (mIMETypeHint.equalsIgnoreCase("url"))
             outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_URI;
-        else if (mIMEHint.equalsIgnoreCase("email"))
+        else if (mIMETypeHint.equalsIgnoreCase("email"))
             outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-        else if (mIMEHint.equalsIgnoreCase("search"))
+        else if (mIMETypeHint.equalsIgnoreCase("search"))
             outAttrs.imeOptions = EditorInfo.IME_ACTION_SEARCH;
-        else if (mIMEHint.equalsIgnoreCase("tel"))
+        else if (mIMETypeHint.equalsIgnoreCase("tel"))
             outAttrs.inputType = InputType.TYPE_CLASS_PHONE;
-        else if (mIMEHint.equalsIgnoreCase("number") ||
-                 mIMEHint.equalsIgnoreCase("range"))
+        else if (mIMETypeHint.equalsIgnoreCase("number") ||
+                 mIMETypeHint.equalsIgnoreCase("range"))
             outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;
-        else if (mIMEHint.equalsIgnoreCase("datetime") ||
-                 mIMEHint.equalsIgnoreCase("datetime-local"))
+        else if (mIMETypeHint.equalsIgnoreCase("datetime") ||
+                 mIMETypeHint.equalsIgnoreCase("datetime-local"))
             outAttrs.inputType = InputType.TYPE_CLASS_DATETIME |
                                  InputType.TYPE_DATETIME_VARIATION_NORMAL;
-        else if (mIMEHint.equalsIgnoreCase("date"))
+        else if (mIMETypeHint.equalsIgnoreCase("date"))
             outAttrs.inputType = InputType.TYPE_CLASS_DATETIME |
                                  InputType.TYPE_DATETIME_VARIATION_DATE;
-        else if (mIMEHint.equalsIgnoreCase("time"))
+        else if (mIMETypeHint.equalsIgnoreCase("time"))
             outAttrs.inputType = InputType.TYPE_CLASS_DATETIME |
                                  InputType.TYPE_DATETIME_VARIATION_TIME;
 
+        if (mIMEActionHint.equalsIgnoreCase("go"))
+            outAttrs.imeOptions = EditorInfo.IME_ACTION_GO;
+        else if (mIMEActionHint.equalsIgnoreCase("done"))
+            outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
+        else if (mIMEActionHint.equalsIgnoreCase("next"))
+            outAttrs.imeOptions = EditorInfo.IME_ACTION_NEXT;
+        else if (mIMEActionHint.equalsIgnoreCase("search"))
+            outAttrs.imeOptions = EditorInfo.IME_ACTION_SEARCH;
+        else if (mIMEActionHint.equalsIgnoreCase("send"))
+            outAttrs.imeOptions = EditorInfo.IME_ACTION_SEND;
+        else
+            outAttrs.actionLabel = mIMEActionHint;
         inputConnection.reset();
         return inputConnection;
     }
 
     public void setupEditable(String contents)
     {
         mEditable = mEditableFactory.newEditable(contents);
         mEditable.setSpan(inputConnection, 0, contents.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
@@ -399,17 +412,18 @@ class GeckoSurfaceView
     public static final int IME_STATE_PASSWORD = 2;
 
     GeckoInputConnection inputConnection;
     KeyListener mKeyListener;
     Editable mEditable;
     Editable.Factory mEditableFactory;
     boolean mIMEFocus;
     int mIMEState;
-    String mIMEHint;
+    String mIMETypeHint;
+    String mIMEActionHint;
 
     // Software rendering
     ByteBuffer mSoftwareBuffer;
     Bitmap mSoftwareBitmap;
 
     final SynchronousQueue<ByteBuffer> mSyncBuf = new SynchronousQueue<ByteBuffer>();
 }
 
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -64,17 +64,17 @@
         <children includes="image|deck|stack|box">
           <xul:image class="autocomplete-icon" allowevents="true"/>
         </children>
 
         <xul:hbox anonid="textbox-input-box" class="textbox-input-box" flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
           <children/>
           <html:input anonid="input" class="autocomplete-textbox textbox-input"
                       flex="1" allowevents="true"
-                      xbl:inherits="tooltiptext=inputtooltiptext,onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/>
+                      xbl:inherits="tooltiptext=inputtooltiptext,onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,mozactionhint"/>
         </xul:hbox>
         <children includes="hbox"/>
       </xul:hbox>
 
       <xul:dropmarker anonid="historydropmarker" class="autocomplete-history-dropmarker"
                       allowevents="true"
                       xbl:inherits="open,enablehistory,parentfocused=focused"/>
 
--- a/toolkit/content/widgets/textbox.xml
+++ b/toolkit/content/widgets/textbox.xml
@@ -16,17 +16,17 @@
       <stylesheet src="chrome://global/content/textbox.css"/>
       <stylesheet src="chrome://global/skin/textbox.css"/>
     </resources>
 
     <content>
       <children/>
       <xul:hbox class="textbox-input-box" flex="1" xbl:inherits="context,spellcheck">
         <html:input class="textbox-input" flex="1" anonid="input"
-                    xbl:inherits="onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,noinitialfocus"/>
+                    xbl:inherits="onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,noinitialfocus,mozactionhint"/>
       </xul:hbox>
     </content>
 
     <implementation implements="nsIAccessibleProvider, nsIDOMXULTextBoxElement, nsIDOMXULLabeledControlElement">
       <property name="accessibleType" readonly="true">
         <getter>
           <![CDATA[
             return Components.interfaces.nsIAccessibleProvider.XULTextBox;
@@ -302,18 +302,18 @@
       </handler>
     </handlers>
   </binding>
 
   <binding id="search-textbox" extends="chrome://global/content/bindings/textbox.xml#textbox">
     <content>
       <children/>
       <xul:hbox class="textbox-input-box" flex="1" xbl:inherits="context,spellcheck" align="center">
-        <html:input class="textbox-input" flex="1" anonid="input"
-                    xbl:inherits="onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/>
+        <html:input class="textbox-input" flex="1" anonid="input" mozactionhint="search"
+                    xbl:inherits="onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey,mozactionhint"/>
         <xul:deck class="textbox-search-icons" anonid="search-icons">
           <xul:image class="textbox-search-icon"
                      onclick="document.getBindingParent(this)._iconClick();"
                      xbl:inherits="src=image,searchbutton,disabled"/>
           <xul:image class="textbox-search-clear"
                      onclick="document.getBindingParent(this)._clearSearch();"
                      xbl:inherits="disabled"/>
         </xul:deck>
@@ -430,17 +430,17 @@
       </handler>
     </handlers>
   </binding>
 
   <binding id="textarea" extends="chrome://global/content/bindings/textbox.xml#textbox">
     <content>
       <xul:hbox class="textbox-input-box" flex="1" xbl:inherits="context,spellcheck">
         <html:textarea class="textbox-textarea" flex="1" anonid="input"
-                       xbl:inherits="onfocus,onblur,xbl:text=value,disabled,tabindex,rows,cols,readonly,wrap,placeholder"><children/></html:textarea>
+                       xbl:inherits="onfocus,onblur,xbl:text=value,disabled,tabindex,rows,cols,readonly,wrap,placeholder,mozactionhint"><children/></html:textarea>
       </xul:hbox>
     </content>
   </binding>
 
   <binding id="input-box">
     <content context="_child">
       <children/>
       <xul:menupopup anonid="input-box-contextmenu"
--- a/widget/public/nsIWidget.h
+++ b/widget/public/nsIWidget.h
@@ -238,16 +238,19 @@ struct nsIMEUpdatePreference {
  * Contains IMEStatus plus information about the current 
  * input context that the IME can use as hints if desired.
  */
 struct IMEContext {
   PRUint32 mStatus;
 
   /* The type of the input if the input is a html input field */
   nsString mHTMLInputType;
+
+  /* A hint for the action that is performed when the input is submitted */
+  nsString mActionHint;
 };
 
 
 /**
  * The base class for all the widgets. It provides the interface for
  * all basic and necessary functionality.
  */
 class nsIWidget : public nsISupports {
--- a/widget/src/android/AndroidBridge.cpp
+++ b/widget/src/android/AndroidBridge.cpp
@@ -93,17 +93,17 @@ AndroidBridge::Init(JNIEnv *jEnv,
     jEnv->GetJavaVM(&mJavaVM);
 
     mJNIEnv = nsnull;
     mThread = nsnull;
 
     mGeckoAppShellClass = (jclass) jEnv->NewGlobalRef(jGeckoAppShellClass);
 
     jNotifyIME = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIME", "(II)V");
-    jNotifyIMEEnabled = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEEnabled", "(ILjava/lang/String;)V");
+    jNotifyIMEEnabled = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEEnabled", "(ILjava/lang/String;Ljava/lang/String;)V");
     jNotifyIMEChange = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEChange", "(Ljava/lang/String;III)V");
     jEnableAccelerometer = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableAccelerometer", "(Z)V");
     jEnableLocation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableLocation", "(Z)V");
     jReturnIMEQueryResult = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "returnIMEQueryResult", "(Ljava/lang/String;II)V");
     jScheduleRestart = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scheduleRestart", "()V");
     jNotifyAppShellReady = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onAppShellReady", "()V");
     jNotifyXreExit = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onXreExit", "()V");
     jGetHandlersForMimeType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForMimeType", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
@@ -206,27 +206,30 @@ void
 AndroidBridge::NotifyIME(int aType, int aState)
 {
     if (sBridge)
         JNI()->CallStaticVoidMethod(sBridge->mGeckoAppShellClass, 
                                     sBridge->jNotifyIME,  aType, aState);
 }
 
 void
-AndroidBridge::NotifyIMEEnabled(int aState, const nsAString& aHint)
+AndroidBridge::NotifyIMEEnabled(int aState, const nsAString& aTypeHint,
+                                const nsAString& aActionHint)
 {
     if (!sBridge)
         return;
 
-    nsPromiseFlatString hint(aHint);
+    nsPromiseFlatString typeHint(aTypeHint);
+    nsPromiseFlatString actionHint(aActionHint);
 
-    jvalue args[2];
+    jvalue args[3];
     AutoLocalJNIFrame jniFrame(1);
     args[0].i = aState;
-    args[1].l = JNI()->NewString(hint.get(), hint.Length());
+    args[1].l = JNI()->NewString(typeHint.get(), typeHint.Length());
+    args[2].l = JNI()->NewString(actionHint.get(), actionHint.Length());
     JNI()->CallStaticVoidMethodA(sBridge->mGeckoAppShellClass,
                                  sBridge->jNotifyIMEEnabled, args);
 }
 
 void
 AndroidBridge::NotifyIMEChange(const PRUnichar *aText, PRUint32 aTextLen,
                                int aStart, int aEnd, int aNewEnd)
 {
--- a/widget/src/android/AndroidBridge.h
+++ b/widget/src/android/AndroidBridge.h
@@ -101,17 +101,18 @@ public:
     // SetMainThread.
     PRBool SetMainThread(void *thr);
 
     JNIEnv* AttachThread(PRBool asDaemon = PR_TRUE);
 
     /* These are all implemented in Java */
     static void NotifyIME(int aType, int aState);
 
-    static void NotifyIMEEnabled(int aState, const nsAString& aHint);
+    static void NotifyIMEEnabled(int aState, const nsAString& aTypeHint,
+                                 const nsAString& aActionHint);
 
     static void NotifyIMEChange(const PRUnichar *aText, PRUint32 aTextLen, int aStart, int aEnd, int aNewEnd);
 
     void EnableAccelerometer(bool aEnable);
 
     void EnableLocation(bool aEnable);
 
     void ReturnIMEQueryResult(const PRUnichar *aResult, PRUint32 aLen, int aSelStart, int aSelLen);
--- a/widget/src/android/nsWindow.cpp
+++ b/widget/src/android/nsWindow.cpp
@@ -1646,17 +1646,17 @@ nsWindow::ResetInputState()
 }
 
 NS_IMETHODIMP
 nsWindow::SetInputMode(const IMEContext& aContext)
 {
     ALOGIME("IME: SetInputMode: s=%d", aContext.mStatus);
 
     mIMEContext = aContext;
-    AndroidBridge::NotifyIMEEnabled(int(aContext.mStatus), aContext.mHTMLInputType);
+    AndroidBridge::NotifyIMEEnabled(int(aContext.mStatus), aContext.mHTMLInputType, aContext.mActionHint);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::GetInputMode(IMEContext& aContext)
 {
     aContext = mIMEContext;
     return NS_OK;
--- a/widget/src/xpwidgets/PuppetWidget.cpp
+++ b/widget/src/xpwidgets/PuppetWidget.cpp
@@ -368,17 +368,17 @@ PuppetWidget::SetIMEOpenState(PRBool aSt
     return NS_OK;
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 PuppetWidget::SetInputMode(const IMEContext& aContext)
 {
   if (mTabChild &&
-      mTabChild->SendSetInputMode(aContext.mStatus, aContext.mHTMLInputType))
+      mTabChild->SendSetInputMode(aContext.mStatus, aContext.mHTMLInputType, aContext.mActionHint))
     return NS_OK;
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 PuppetWidget::GetIMEOpenState(PRBool *aState)
 {
   if (mTabChild &&