Skip to content

Commit

Permalink
Fix issues where soft keyboard was not shown in some cases when hardw…
Browse files Browse the repository at this point in the history
…are 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.
  • Loading branch information
agnostic-apollo committed May 7, 2021
1 parent 596aa56 commit 4d1851e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 18 deletions.
19 changes: 3 additions & 16 deletions app/src/main/java/com/termux/app/TermuxActivity.java
Expand Up @@ -237,7 +237,7 @@ public void onStart() {
public void onResume() {
super.onResume();

setSoftKeyboardState();
mTermuxTerminalViewClient.setSoftKeyboardState();
}

/**
Expand Down Expand Up @@ -418,8 +418,7 @@ private void setNewSessionButtonView() {

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();
});

Expand All @@ -429,19 +428,7 @@ private void setToggleKeyboardView() {
});
}

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);
}
}



Expand Down Expand Up @@ -780,7 +767,7 @@ private void reloadTermuxActivityStyling() {

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.
Expand Down
Expand Up @@ -7,13 +7,15 @@
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;
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;
Expand All @@ -36,6 +38,7 @@
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;
Expand Down Expand Up @@ -122,8 +125,7 @@ public boolean onKeyDown(int keyCode, KeyEvent e, TerminalSession currentSession
} 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 */) {
Expand Down Expand Up @@ -151,6 +153,8 @@ public boolean onKeyDown(int keyCode, KeyEvent e, TerminalSession currentSession

}



@Override
public boolean onKeyUp(int keyCode, KeyEvent e) {
return handleVirtualKeys(keyCode, e, false);
Expand Down Expand Up @@ -337,6 +341,58 @@ public void changeFontSize(boolean increase) {
}


/**
* 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();
Expand Down

0 comments on commit 4d1851e

Please sign in to comment.