Android: Do not hide keyboard when opening

It takes some time to display the keyboard. For this reason, in case the
keyboard was not displayed yet - we could wrongly assume that the
keyboard is hiding. To avoid this situation, there is a new check.
In case the keyboard has just been opened and it is not displayed yet,
the execution of HideKeyboardRunnable is postponed to give time for the
keyboard to be displayed.

Fixes: QTBUG-130000
Change-Id: Iee1310c777ebbb807990bf3cec39e6d07481dfad
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit 4de9b94042dd173c6db31a4641a1513a9b319a79)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Rami Potinkara 2024-10-17 20:50:10 +03:00 committed by Qt Cherry-pick Bot
parent 0a32e20b11
commit 7e4b10677f
2 changed files with 44 additions and 1 deletions

View File

@ -66,12 +66,15 @@ class QtInputConnection extends BaseInputConnection
private static final int ID_COPY_URL = android.R.id.copyUrl;
private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod;
private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary;
private static final int KEYBOARD_CHECK_DELAY_MS = 100;
private static final String QtTAG = "QtInputConnection";
private final QtInputConnectionListener m_qtInputConnectionListener;
class HideKeyboardRunnable implements Runnable {
private int m_numberOfAttempts = 10;
@Override
public void run() {
// Check that the keyboard is really no longer there.
@ -79,6 +82,14 @@ class QtInputConnection extends BaseInputConnection
Log.w(QtTAG, "HideKeyboardRunnable: QtInputConnectionListener is null");
return;
}
if (m_qtInputConnectionListener.keyboardTransitionInProgress()
&& m_numberOfAttempts > 0) {
--m_numberOfAttempts;
m_view.postDelayed(this, KEYBOARD_CHECK_DELAY_MS);
return;
}
if (m_qtInputConnectionListener.isKeyboardHidden())
m_qtInputConnectionListener.onHideKeyboardRunnableDone(false, System.nanoTime());
}
@ -89,6 +100,7 @@ class QtInputConnection extends BaseInputConnection
void onHideKeyboardRunnableDone(boolean visibility, long hideTimeStamp);
void onSendKeyEventDefaultCase();
void onEditTextChanged(QtEditText editText);
boolean keyboardTransitionInProgress();
boolean isKeyboardHidden();
}
@ -98,7 +110,7 @@ class QtInputConnection extends BaseInputConnection
private void setClosing(boolean closing)
{
if (closing)
m_view.postDelayed(new HideKeyboardRunnable(), 100);
m_view.postDelayed(new HideKeyboardRunnable(), KEYBOARD_CHECK_DELAY_MS);
else if (m_qtInputConnectionListener != null)
m_qtInputConnectionListener.onSetClosing(false);
}

View File

@ -20,6 +20,7 @@ import android.view.MotionEvent;
import android.view.WindowInsets;
import android.view.WindowInsets.Type;
import android.view.WindowManager;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener;
@ -52,6 +53,7 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
// That is why we assume that the keyboard should be higher than 0.15 of the screen.
private static final float KEYBOARD_TO_SCREEN_RATIO = 0.15f;
private boolean m_keyboardTransitionInProgress = false;
private boolean m_keyboardIsVisible = false;
private boolean m_isKeyboardHidingAnimationOngoing = false;
private long m_showHideTimeStamp = System.nanoTime();
@ -91,6 +93,28 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
Log.w(TAG, "getSystemService() returned a null InputMethodManager instance");
}
private final ViewTreeObserver.OnGlobalLayoutListener keyboardListener =
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (!isKeyboardHidden())
setKeyboardTransitionInProgress(false);
}
};
private void setKeyboardTransitionInProgress(boolean state)
{
if (m_keyboardTransitionInProgress == state || m_currentEditText == null)
return;
m_keyboardTransitionInProgress= state;
ViewTreeObserver observer = m_currentEditText.getViewTreeObserver();
if (state)
observer.addOnGlobalLayoutListener(keyboardListener);
else
observer.removeOnGlobalLayoutListener(keyboardListener);
}
// QtInputInterface implementation begin
@Override
public void updateSelection(final int selStart, final int selEnd,
@ -234,6 +258,11 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
// QtInputInterface implementation end
// QtInputConnectionListener methods
@Override
public boolean keyboardTransitionInProgress() {
return m_keyboardTransitionInProgress;
}
@Override
public boolean isKeyboardHidden() {
Activity activity = QtNative.activity();
@ -313,6 +342,7 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
return;
m_keyboardIsVisible = visibility;
keyboardVisibilityUpdated(m_keyboardIsVisible);
setKeyboardTransitionInProgress(visibility);
if (!visibility) {
// Hiding the keyboard clears the immersive mode, so we need to set it again.
@ -324,6 +354,7 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
void setFocusedView(QtEditText currentEditText)
{
setKeyboardTransitionInProgress(false);
m_currentEditText = currentEditText;
}