Fix issues where soft keyboard was not shown in some cases when hardware keyboard was attached

For Termux app to be able to show a soft keyboard while a hardware keyboard is attached requires either of 2 cases:

1. User has enabled "Show on-screen keyboard while hardware keyboard is attached" toggle in Android "Language and Input" settings.
2. The toggle is disabled, but the soft keyboard app overrides the default implementation of `InputMethodService.onEvaluateInputViewShown()` and returns `true`. Some keyboard apps have a setting for this, like HackerKeyboard, but its not supported by all keyboard apps.

https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:frameworks/base/core/java/android/inputmethodservice/InputMethodService.java;l=1751

Termux previously didn't forcefully show a keyboard when the drawer "KEYBOARD" toggle button was pressed and only did that for the "KEYBOARD" extra keys toggle button. This prevented the keyboard to be shown for case 2 even when the user attempted to show the keyboard with the drawer "KEYBOARD" toggle. Now both buttons will forcefully show the keyboard.

Moreover, previously at app startup for case 2, the keyboard wasn't being shown. Now it will automatically be shown without requiring a manual press of a "KEYBOARD" toggle button.

This may also solve the issue where the soft keyboard wouldn't show even when the toggle of case 1 was enabled.
This commit is contained in:
agnostic-apollo
2021-05-08 04:16:51 +05:00
parent 596aa56b38
commit 4d1851e6be
2 changed files with 61 additions and 18 deletions

View File

@@ -237,7 +237,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
public void onResume() {
super.onResume();
setSoftKeyboardState();
mTermuxTerminalViewClient.setSoftKeyboardState();
}
/**
@@ -418,8 +418,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
private void setToggleKeyboardView() {
findViewById(R.id.toggle_keyboard_button).setOnClickListener(v -> {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
TermuxTerminalViewClient.toggleSoftKeyboard(this);
getDrawer().closeDrawers();
});
@@ -429,19 +428,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
});
}
private void setSoftKeyboardState() {
// If soft keyboard is to disabled
if (!mPreferences.getSoftKeyboardEnabled()) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
// If soft keyboard is to be hidden on startup
if (mProperties.shouldSoftKeyboardBeHiddenOnStartup()) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
}
@@ -780,7 +767,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
setTerminalToolbarHeight();
setSoftKeyboardState();
mTermuxTerminalViewClient.setSoftKeyboardState();
// To change the activity and drawer theme, activity needs to be recreated.
// But this will destroy the activity, and will call the onCreate() again.

View File

@@ -7,6 +7,7 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.Uri;
import android.text.TextUtils;
@@ -14,6 +15,7 @@ import android.view.Gravity;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.ListView;
import android.widget.Toast;
@@ -36,6 +38,7 @@ import com.termux.shared.termux.TermuxUtils;
import com.termux.terminal.KeyHandler;
import com.termux.terminal.TerminalEmulator;
import com.termux.terminal.TerminalSession;
import com.termux.view.TerminalView;
import java.util.Arrays;
import java.util.Collections;
@@ -122,8 +125,7 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mActivity.getDrawer().closeDrawers();
} else if (unicodeChar == 'k'/* keyboard */) {
InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
toggleSoftKeyboard(mActivity);
} else if (unicodeChar == 'm'/* menu */) {
mActivity.getTerminalView().showContextMenu();
} else if (unicodeChar == 'r'/* rename */) {
@@ -151,6 +153,8 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent e) {
return handleVirtualKeys(keyCode, e, false);
@@ -337,6 +341,58 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
}
/**
* Toggle the soft keyboard. The {@link InputMethodManager#SHOW_FORCED} is passed as
* {@code showFlags} so that keyboard is forcefully shown if it needs to be enabled.
*
* This is also important for soft keyboard to be shown when a hardware keyboard is attached, and
* user has disabled the {@code Show on-screen keyboard while hardware keyboard is attached} toggle
* in Android "Language and Input" settings but the current soft keyboard app overrides the
* default implementation of {@link InputMethodService#onEvaluateInputViewShown()} and returns
* {@code true}.
*/
public static void toggleSoftKeyboard(Context context) {
InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
/**
* Show the soft keyboard. The {@code 0} value is passed as {@code flags} so that keyboard is
* forcefully shown.
*
* This is also important for soft keyboard to be shown on app startup when a hardware keyboard
* is attached, and user has disabled the {@code Show on-screen keyboard while hardware keyboard
* is attached} toggle in Android "Language and Input" settings but the current soft keyboard app
* overrides the default implementation of {@link InputMethodService#onEvaluateInputViewShown()}
* and returns {@code true}.
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:frameworks/base/core/java/android/inputmethodservice/InputMethodService.java;l=1751
*
* Also check {@link InputMethodService#onShowInputRequested(int, boolean)} which must return
* {@code true}, which can be done by failing its {@code ((flags&InputMethod.SHOW_EXPLICIT) == 0)}
* check by passing {@code 0} as {@code flags}.
* https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:frameworks/base/core/java/android/inputmethodservice/InputMethodService.java;l=2022
*/
public static void showSoftKeyboard(Context context, TerminalView terminalView) {
InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(terminalView, 0);
}
public void setSoftKeyboardState() {
// If soft keyboard is to disabled
if (!mActivity.getPreferences().getSoftKeyboardEnabled()) {
mActivity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
} else {
mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
showSoftKeyboard(mActivity, mActivity.getTerminalView());
}
// If soft keyboard is to be hidden on startup
if (mActivity.getProperties().shouldSoftKeyboardBeHiddenOnStartup()) {
mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
}
public void shareSessionTranscript() {
TerminalSession session = mActivity.getCurrentSession();