OSDN Git Service

Hide the soft keyboard when a blur happens.
authorLeon Scroggins <scroggo@google.com>
Fri, 24 Sep 2010 19:30:24 +0000 (15:30 -0400)
committerLeon Scroggins <scroggo@google.com>
Tue, 28 Sep 2010 14:04:36 +0000 (10:04 -0400)
Bug: 2953257

Requires a change in frameworks/base.

Change-Id: Ib0e7976cd5eb585be991b265087bff9ee7c4f4fd

WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
WebKit/android/WebCoreSupport/ChromeClientAndroid.h
WebKit/android/jni/WebViewCore.cpp
WebKit/android/jni/WebViewCore.h

index d5cadad..2688d69 100644 (file)
@@ -198,6 +198,11 @@ void ChromeClientAndroid::addMessageToConsole(MessageSource, MessageType, Messag
     android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->addMessageToConsole(message, lineNumber, sourceID, msgLevel);
 }
 
+void ChromeClientAndroid::formDidBlur(const WebCore::Node* node)
+{
+    android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->formDidBlur(node);
+}
+
 bool ChromeClientAndroid::canRunBeforeUnloadConfirmPanel() { return true; }
 bool ChromeClientAndroid::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) {
     String url = frame->document()->documentURI();
index d25747f..b7d423d 100644 (file)
@@ -65,7 +65,7 @@ namespace android {
         
         virtual void focus();
         virtual void unfocus();
-        
+        virtual void formDidBlur(const WebCore::Node*);
         virtual bool canTakeFocus(FocusDirection);
         virtual void takeFocus(FocusDirection);
 
index 8353b98..619ac10 100644 (file)
@@ -252,6 +252,7 @@ struct WebViewCore::JavaGlue {
     jmethodID   m_geolocationPermissionsHidePrompt;
     jmethodID   m_getDeviceOrientationService;
     jmethodID   m_addMessageToConsole;
+    jmethodID   m_formDidBlur;
     jmethodID   m_getPluginClass;
     jmethodID   m_showFullScreenPlugin;
     jmethodID   m_hideFullScreenPlugin;
@@ -343,6 +344,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
     m_javaGlue->m_geolocationPermissionsHidePrompt = GetJMethod(env, clazz, "geolocationPermissionsHidePrompt", "()V");
     m_javaGlue->m_getDeviceOrientationService = GetJMethod(env, clazz, "getDeviceOrientationService", "()Landroid/webkit/DeviceOrientationService;");
     m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;I)V");
+    m_javaGlue->m_formDidBlur = GetJMethod(env, clazz, "formDidBlur", "(I)V");
     m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
     m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;I)V");
     m_javaGlue->m_hideFullScreenPlugin = GetJMethod(env, clazz, "hideFullScreenPlugin", "()V");
@@ -2765,6 +2767,7 @@ static void scrollLayer(WebCore::RenderObject* renderer, WebCore::IntPoint* pos)
 // Common code for both clicking with the trackball and touchUp
 bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr)
 {
+    m_lastClickWasOnTextInput = false;
     bool valid = framePtr == NULL
             || CacheBuilder::validNode(m_mainFrame, framePtr, nodePtr);
     WebFrame* webFrame = WebFrame::getWebFrame(m_mainFrame);
@@ -2821,8 +2824,15 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
     }
     if (!valid || !framePtr)
         framePtr = m_mainFrame;
-    if (nodePtr && valid)
+    if (nodePtr && valid) {
         scrollLayer(nodePtr->renderer(), &m_mousePos);
+        if (nodePtr->isContentEditable() || (nodePtr->renderer()
+                && (nodePtr->renderer()-> isTextArea() || nodePtr->renderer()->isTextField()))) {
+            // The user clicked on a text input field.  If this causes a blur event
+            // on a different text input, do not hide the keyboard in formDidBlur
+            m_lastClickWasOnTextInput = true;
+        }
+    }
     webFrame->setUserInitiatedAction(true);
     WebCore::PlatformMouseEvent mouseDown(m_mousePos, m_mousePos, WebCore::LeftButton,
             WebCore::MouseEventPressed, 1, false, false, false, false,
@@ -2835,6 +2845,8 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
     bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp);
     webFrame->setUserInitiatedAction(false);
 
+    m_lastClickWasOnTextInput = false;
+
     // If the user clicked on a textfield, make the focusController active
     // so we show the blinking cursor.
     WebCore::Node* focusNode = currentFocus();
@@ -2890,6 +2902,18 @@ void WebViewCore::popupReply(const int* array, int count)
     }
 }
 
+void WebViewCore::formDidBlur(const WebCore::Node* node)
+{
+    // This blur is the result of clicking on a different input.  Do not hide
+    // the keyboard, since it will just be opened again.
+    if (m_lastClickWasOnTextInput) return;
+
+    JNIEnv* env = JSC::Bindings::getJNIEnv();
+    env->CallVoidMethod(m_javaGlue->object(env).get(),
+            m_javaGlue->m_formDidBlur, reinterpret_cast<int>(node));
+    checkException(env);
+}
+
 void WebViewCore::addMessageToConsole(const WTF::String& message, unsigned int lineNumber, const WTF::String& sourceID, int msgLevel) {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
     jstring jMessageStr = env->NewString((unsigned short *)message.characters(), message.length());
index 0078fd9..f898406 100644 (file)
@@ -126,6 +126,13 @@ namespace android {
         // Followings are called from native WebCore to Java
 
         /**
+         * Notification that a form was blurred.  Pass a message to hide the
+         * keyboard if it was showing for that Node.
+         * @param Node The Node that blurred.
+         */
+        void formDidBlur(const WebCore::Node*);
+
+        /**
          * Scroll to an absolute position.
          * @param x The x coordinate.
          * @param y The y coordinate.
@@ -540,6 +547,7 @@ namespace android {
         WebCoreReply*          m_popupReply;
         WebCore::Node* m_lastFocused;
         WebCore::IntRect m_lastFocusedBounds;
+        bool m_lastClickWasOnTextInput;
         int m_lastFocusedSelStart;
         int m_lastFocusedSelEnd;
         PictureSet m_content; // the set of pictures to draw