commit f7909f4d641daacb14be68f041efe25552362584
parent ba2b76fef86befe525ae86dc9d8f48fd4ebeadb2
Author: Makoto Kato <m_kato@ga2.so-net.ne.jp>
Date: Mon, 15 Dec 2025 04:13:07 +0000
Bug 1970097 - Dismiss software keyboard at force when navigating away. r=geckoview-reviewers,tcampbell
Actually, we don't dismiss the software keyboard when navigating to
another page. This behaviour isn't compatible with Chrome now.
As web compatibility, we should dismiss the software keyboard when
navigating away from the current page, like Chrome.
Also, we have to fix `restartInput_disableEnable` that might be rarely
failure after fixing this issue. I mistake to forget setting display
size to take a focus correctly.
Differential Revision: https://phabricator.services.mozilla.com/D276205
Diffstat:
2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TextInputDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TextInputDelegateTest.kt
@@ -421,6 +421,7 @@ class TextInputDelegateTest : BaseSessionTest() {
})
}
+ @WithDisplay(width = 100, height = 100)
@Test fun restartInput_disableEnable() {
assumeThat("input only", id, equalTo("#input"))
@@ -464,6 +465,45 @@ class TextInputDelegateTest : BaseSessionTest() {
assertThat("hideSoftInput isn't called", true, equalTo(true))
}
+ // When navigating away from a page with a focused input field, the keyboard should be dismissed.
+ @WithDisplay(width = 100, height = 100)
+ @Test
+ fun restartInput_dismissAfterNavigation() {
+ assumeThat("input only", id, equalTo("#input"))
+
+ mainSession.textInput.view = View(InstrumentationRegistry.getInstrumentation().targetContext)
+ mainSession.loadTestPath(RESUBMIT_CONFIRM)
+ mainSession.waitForPageStop()
+
+ mainSession.evaluateJS("document.querySelector('#text').focus()")
+
+ mainSession.waitUntilCalled(object : TextInputDelegate {
+ @AssertCalled(count = 1)
+ override fun restartInput(session: GeckoSession, reason: Int) {
+ assertThat(
+ "Reason should be correct",
+ reason,
+ equalTo(GeckoSession.TextInputDelegate.RESTART_REASON_FOCUS),
+ )
+ }
+ })
+
+ val ic = mainSession.textInput.onCreateInputConnection(EditorInfo())!!
+ pressKeyNoWait(ic, KeyEvent.KEYCODE_ENTER)
+
+ mainSession.waitUntilCalled(object : TextInputDelegate, GeckoSession.ProgressDelegate {
+ @AssertCalled(count = 1)
+ override fun hideSoftInput(session: GeckoSession) {
+ }
+
+ @AssertCalled(count = 1)
+ override fun onPageStop(session: GeckoSession, success: Boolean) {
+ }
+ })
+
+ assertThat("hideSoftInput is called once", true, equalTo(true))
+ }
+
private fun getText(ic: InputConnection) =
ic.getExtractedText(ExtractedTextRequest(), 0).text.toString()
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
@@ -1853,7 +1853,7 @@ import org.mozilla.geckoview.SessionTextInput.EditableListener.IMEState;
.append(", toggleSoftInput=")
.append(toggleSoftInput)
.append(")");
- MozLog.d(LOGTAG, sb.toString());
+ MozLog.d(MOZLOGTAG, sb.toString());
}
// Avoid multiple toggleSoftInput call. If this becomes true, onCreateInputConnection is
@@ -1889,7 +1889,12 @@ import org.mozilla.geckoview.SessionTextInput.EditableListener.IMEState;
// Unnecessary to track onCreateInputConnection.
mIsNewICCreated = true;
- toggleSoftInput(/* force */ false, state);
+ // GeckoSession and mFocusedChild would be null due to navigating away or blur.
+ // So we should set force flag to dismiss software keyboard.
+ final boolean force =
+ reason == GeckoSession.TextInputDelegate.RESTART_REASON_BLUR
+ && state == SessionTextInput.EditableListener.IME_STATE_DISABLED;
+ toggleSoftInput(force, state);
}
});
}