mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 10:45:23 +08:00
Allow users to disable soft keyboard automatically if hardware keyboard is connected
Users can enable this behaviour by enabling the `Termux Settings` -> `Keyboard I/O` -> `Soft Keyboard Only If No Hardware` toggle. Currently, for this case, soft keyboard will be disabled on Termux app startup and when switching back from another app. Soft keyboard can be temporarily enabled in show/hide soft keyboard toggle behaviour with keyboard toggle buttons and will continue to work when tapping on terminal view for opening and back button for closing, until Termux app is switched to another app. After returning back, keyboard will be disabled until toggle is pressed again. This also may help for the Lineage OS bug where blank space is shown where soft keyboard should be if "Show soft keyboard" toggle in "Language and Input" is disabled. Check KeyboardUtils.shouldSoftKeyboardBeDisabled() and https://github.com/termux/termux-app/issues/1995#issuecomment-837080079 for details. The `TermuxPreferenceConstants` class has been updated to `v0.10.0`. Check its Changelog sections for info on changes.
This commit is contained in:
@@ -62,6 +62,14 @@ public class TermuxAppSharedPreferences {
|
||||
SharedPreferenceUtils.setBoolean(mSharedPreferences, TERMUX_APP.KEY_SOFT_KEYBOARD_ENABLED, value, false);
|
||||
}
|
||||
|
||||
public boolean getSoftKeyboardEnabledOnlyIfNoHardware() {
|
||||
return SharedPreferenceUtils.getBoolean(mSharedPreferences, TERMUX_APP.KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE, TERMUX_APP.DEFAULT_VALUE_KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE);
|
||||
}
|
||||
|
||||
public void setSoftKeyboardEnabledOnlyIfNoHardware(boolean value) {
|
||||
SharedPreferenceUtils.setBoolean(mSharedPreferences, TERMUX_APP.KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE, value, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean getKeepScreenOn() {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package com.termux.shared.settings.preferences;
|
||||
|
||||
/*
|
||||
* Version: v0.9.0
|
||||
* Version: v0.10.0
|
||||
*
|
||||
* Changelog
|
||||
*
|
||||
@@ -40,6 +40,10 @@ package com.termux.shared.settings.preferences;
|
||||
*
|
||||
* - 0.9.0 (2021-04-07)
|
||||
* - Updated javadocs.
|
||||
*
|
||||
* - 0.10.0 (2021-05-12)
|
||||
* - Added following to `TERMUX_APP`:
|
||||
* `KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE` and `DEFAULT_VALUE_KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE`.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -70,6 +74,13 @@ public final class TermuxPreferenceConstants {
|
||||
public static final String KEY_SOFT_KEYBOARD_ENABLED = "soft_keyboard_enabled";
|
||||
public static final boolean DEFAULT_VALUE_KEY_SOFT_KEYBOARD_ENABLED = true;
|
||||
|
||||
/**
|
||||
* Defines the key for whether the soft keyboard will be enabled only if no hardware keyboard
|
||||
* attached, for cases where users want to use a hardware keyboard instead.
|
||||
*/
|
||||
public static final String KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE = "soft_keyboard_enabled_only_if_no_hardware";
|
||||
public static final boolean DEFAULT_VALUE_KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE = false;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the key for whether to always keep screen on.
|
||||
|
@@ -2,6 +2,7 @@ package com.termux.shared.view;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.inputmethodservice.InputMethodService;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
@@ -32,8 +33,8 @@ public class KeyboardUtils {
|
||||
* 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
|
||||
* This is also important for soft keyboard to be shown when a hardware keyboard is connected, and
|
||||
* user has disabled the {@code Show on-screen keyboard while hardware keyboard is connected} 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}.
|
||||
@@ -50,8 +51,8 @@ public class KeyboardUtils {
|
||||
* 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
|
||||
* is connected, and user has disabled the {@code Show on-screen keyboard while hardware keyboard
|
||||
* is connected} 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
|
||||
@@ -110,21 +111,85 @@ public class KeyboardUtils {
|
||||
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||
}
|
||||
|
||||
/** Check if keyboard visible. Does not work on android 7 but does on android 11 avd. */
|
||||
/**
|
||||
* Check if soft keyboard is visible.
|
||||
* Does not work on android 7 but does on android 11 avd.
|
||||
*
|
||||
* @param activity The Activity of the root view for which the visibility should be checked.
|
||||
* @return Returns {@code true} if soft keyboard is visible, otherwise {@code false}.
|
||||
*/
|
||||
public static boolean isSoftKeyboardVisible(final Activity activity) {
|
||||
if (activity != null && activity.getWindow() != null) {
|
||||
WindowInsets insets = activity.getWindow().getDecorView().getRootWindowInsets();
|
||||
if (insets != null) {
|
||||
WindowInsetsCompat insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(insets);
|
||||
if (insetsCompat != null && insetsCompat.isVisible(WindowInsetsCompat.Type.ime())) {
|
||||
Logger.logVerbose(LOG_TAG, "Keyboard visible");
|
||||
if (insetsCompat.isVisible(WindowInsetsCompat.Type.ime())) {
|
||||
Logger.logVerbose(LOG_TAG, "Soft keyboard visible");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logger.logVerbose(LOG_TAG, "Keyboard not visible");
|
||||
Logger.logVerbose(LOG_TAG, "Soft keyboard not visible");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if hardware keyboard is connected.
|
||||
* Based on default implementation of {@link InputMethodService#onEvaluateInputViewShown()}.
|
||||
*
|
||||
* https://developer.android.com/guide/topics/resources/providing-resources#ImeQualifier
|
||||
*
|
||||
* @param context The Context for operations.
|
||||
* @return Returns {@code true} if device has hardware keys for text input or an external hardware
|
||||
* keyboard is connected, otherwise {@code false}.
|
||||
*/
|
||||
public static boolean isHardKeyboardConnected(final Context context) {
|
||||
if (context == null) return false;
|
||||
|
||||
Configuration config = context.getResources().getConfiguration();
|
||||
return config.keyboard != Configuration.KEYBOARD_NOKEYS
|
||||
|| config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if soft keyboard should be disabled based on user configuration.
|
||||
*
|
||||
* @param context The Context for operations.
|
||||
* @return Returns {@code true} if device has soft keyboard should be disabled, otherwise {@code false}.
|
||||
*/
|
||||
public static boolean shouldSoftKeyboardBeDisabled(final Context context, final boolean isSoftKeyboardEnabled, final boolean isSoftKeyboardEnabledOnlyIfNoHardware) {
|
||||
// If soft keyboard is disabled by user regardless of hardware keyboard
|
||||
if (!isSoftKeyboardEnabled) {
|
||||
return true;
|
||||
} else {
|
||||
/*
|
||||
* Currently, for this case, soft keyboard will be disabled on Termux app startup and
|
||||
* when switching back from another app. Soft keyboard can be temporarily enabled in
|
||||
* show/hide soft keyboard toggle behaviour with keyboard toggle buttons and will continue
|
||||
* to work when tapping on terminal view for opening and back button for closing, until
|
||||
* Termux app is switched to another app. After returning back, keyboard will be disabled
|
||||
* until toggle is pressed again.
|
||||
* This may also be helpful for the Lineage OS bug where if "Show soft keyboard" toggle
|
||||
* in "Language and Input" is disabled and Termux is started without a hardware keyboard
|
||||
* in landscape mode, and then the keyboard is connected and phone is rotated to portrait
|
||||
* mode and then keyboard is toggled with Termux keyboard toggle buttons, then a blank
|
||||
* space is shown in-place of the soft keyboard. Its likely related to
|
||||
* WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE which pushes up the view when
|
||||
* keyboard is opened instead of the keyboard opening on top of the view (hiding stuff).
|
||||
* If the "Show soft keyboard" toggle was disabled, then this resizing shouldn't happen.
|
||||
* But it seems resizing does happen, but keyboard is never opened since its not supposed to.
|
||||
* https://github.com/termux/termux-app/issues/1995#issuecomment-837080079
|
||||
*/
|
||||
// If soft keyboard is disabled by user only if hardware keyboard is connected
|
||||
if(isSoftKeyboardEnabledOnlyIfNoHardware) {
|
||||
boolean isHardKeyboardConnected = KeyboardUtils.isHardKeyboardConnected(context);
|
||||
Logger.logVerbose(LOG_TAG, "Hardware keyboard connected=" + isHardKeyboardConnected);
|
||||
return isHardKeyboardConnected;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user