diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoEditable.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoEditable.java index 591f6a3bf80d..ff86bb1092a2 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoEditable.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoEditable.java @@ -1608,8 +1608,36 @@ import android.view.inputmethod.EditorInfo; mListener.notifyIMEContext(state, typeHint, modeHint, actionHint, flags); } - if (state == SessionTextInput.EditableListener.IME_STATE_DISABLED || - mFocusedChild == null) { + if (mFocusedChild == null) { + // We have no focus. + return; + } + + if ((flags & SessionTextInput.EditableListener.IME_FOCUS_NOT_CHANGED) != 0) { + if (DEBUG) { + final StringBuilder sb = new StringBuilder("icNotifyIMEContext: "); + sb.append("focus isn't changed. oldState=").append(oldState) + .append(", newState=").append(state); + Log.d(LOGTAG, sb.toString()); + } + if (((oldState == SessionTextInput.EditableListener.IME_STATE_ENABLED || + oldState == SessionTextInput.EditableListener.IME_STATE_PASSWORD) && + state == SessionTextInput.EditableListener.IME_STATE_DISABLED) || + (oldState == SessionTextInput.EditableListener.IME_STATE_DISABLED && + (state == SessionTextInput.EditableListener.IME_STATE_ENABLED || + state == SessionTextInput.EditableListener.IME_STATE_PASSWORD))) { + // Even if focus isn't changed, software keyboard state is changed. + // We have to show or dismiss it. + icRestartInput(GeckoSession.TextInputDelegate.RESTART_REASON_CONTENT_CHANGE, + /* toggleSoftInput */ true); + return; + } + } + + if (state == SessionTextInput.EditableListener.IME_STATE_DISABLED) { + // When focus is being lost, icNotifyIME with NOTIFY_IME_OF_BLUR + // will dismiss it. + // So ignore to control software keyboard at this time. return; } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java index 961d7133f410..6c8f4994d89d 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java @@ -93,6 +93,7 @@ public final class SessionTextInput { // Flags for notifyIMEContext(). @WrapForJNI final int IME_FLAG_PRIVATE_BROWSING = 1; @WrapForJNI final int IME_FLAG_USER_ACTION = 2; + @WrapForJNI final int IME_FOCUS_NOT_CHANGED = 4; void notifyIME(int type); void notifyIMEContext(int state, String typeHint, String modeHint, diff --git a/widget/android/GeckoEditableSupport.cpp b/widget/android/GeckoEditableSupport.cpp index 42a93bd5bb08..35bc41bc6e6e 100644 --- a/widget/android/GeckoEditableSupport.cpp +++ b/widget/android/GeckoEditableSupport.cpp @@ -1471,7 +1471,10 @@ void GeckoEditableSupport::NotifyIMEContext(const InputContext& aContext, (aAction.IsHandlingUserInput() || aContext.mHasHandledUserInput); const int32_t flags = (inPrivateBrowsing ? EditableListener::IME_FLAG_PRIVATE_BROWSING : 0) | - (isUserAction ? EditableListener::IME_FLAG_USER_ACTION : 0); + (isUserAction ? EditableListener::IME_FLAG_USER_ACTION : 0) | + (aAction.mFocusChange == InputContextAction::FOCUS_NOT_CHANGED + ? EditableListener::IME_FOCUS_NOT_CHANGED + : 0); mEditable->NotifyIMEContext( static_cast(aContext.mIMEState.mEnabled),