diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cef9943d..ee6eae63 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -57,8 +57,7 @@ android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" android:label="@string/application_name" android:launchMode="singleTask" - android:resizeableActivity="true" - android:windowSoftInputMode="adjustResize|stateAlwaysVisible"> + android:resizeableActivity="true"> diff --git a/app/src/main/java/com/termux/app/TermuxActivity.java b/app/src/main/java/com/termux/app/TermuxActivity.java index 003dec95..1381998e 100644 --- a/app/src/main/java/com/termux/app/TermuxActivity.java +++ b/app/src/main/java/com/termux/app/TermuxActivity.java @@ -25,7 +25,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.autofill.AutofillManager; -import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; @@ -237,7 +236,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection public void onResume() { super.onResume(); - mTermuxTerminalViewClient.setSoftKeyboardState(); + mTermuxTerminalViewClient.setSoftKeyboardState(true); } /** @@ -418,7 +417,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection private void setToggleKeyboardView() { findViewById(R.id.toggle_keyboard_button).setOnClickListener(v -> { - TermuxTerminalViewClient.toggleSoftKeyboard(this); + mTermuxTerminalViewClient.onToggleSoftKeyboardRequest(); getDrawer().closeDrawers(); }); @@ -447,8 +446,6 @@ public final class TermuxActivity extends Activity implements ServiceConnection // Set {@link TerminalView#TERMINAL_VIEW_KEY_LOGGING_ENABLED} value mTerminalView.setIsTerminalViewKeyLoggingEnabled(mPreferences.getTerminalViewKeyLoggingEnabled()); - mTerminalView.requestFocus(); - mTermuxTerminalSessionClient.checkForFontAndColors(); } @@ -677,6 +674,10 @@ public final class TermuxActivity extends Activity implements ServiceConnection return mTerminalView; } + public TermuxTerminalViewClient getTermuxTerminalViewClient() { + return mTermuxTerminalViewClient; + } + public TermuxTerminalSessionClient getTermuxTerminalSessionClient() { return mTermuxTerminalSessionClient; } @@ -767,7 +768,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection setTerminalToolbarHeight(); - mTermuxTerminalViewClient.setSoftKeyboardState(); + mTermuxTerminalViewClient.setSoftKeyboardState(true); // To change the activity and drawer theme, activity needs to be recreated. // But this will destroy the activity, and will call the onCreate() again. diff --git a/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java b/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java index 400db111..57cb5732 100644 --- a/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java +++ b/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java @@ -1,6 +1,7 @@ package com.termux.app.terminal; import android.annotation.SuppressLint; +import android.app.Activity; import android.app.AlertDialog; import android.content.ActivityNotFoundException; import android.content.ClipData; @@ -15,6 +16,7 @@ import android.view.Gravity; import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.View; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.ListView; @@ -38,7 +40,6 @@ 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; @@ -75,8 +76,7 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase { @Override public void onSingleTapUp(MotionEvent e) { - InputMethodManager mgr = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE); - mgr.showSoftInput(mActivity.getTerminalView(), InputMethodManager.SHOW_IMPLICIT); + showSoftKeyboard(mActivity, mActivity.getTerminalView()); } @Override @@ -125,7 +125,7 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase { } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { mActivity.getDrawer().closeDrawers(); } else if (unicodeChar == 'k'/* keyboard */) { - toggleSoftKeyboard(mActivity); + onToggleSoftKeyboardRequest(); } else if (unicodeChar == 'm'/* menu */) { mActivity.getTerminalView().showContextMenu(); } else if (unicodeChar == 'r'/* rename */) { @@ -372,23 +372,83 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase { * 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) { + public static void showSoftKeyboard(Context context, View view) { InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); - inputMethodManager.showSoftInput(terminalView, 0); + inputMethodManager.showSoftInput(view, 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()); - } + public static void hideSoftKeyboard(Context context, View view) { + InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); + } - // If soft keyboard is to be hidden on startup - if (mActivity.getProperties().shouldSoftKeyboardBeHiddenOnStartup()) { - mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + public static void disableSoftKeyboard(Activity activity, View view) { + hideSoftKeyboard(activity, view); + setDisableSoftKeyboardFlags(activity); + } + + public static void setDisableSoftKeyboardFlags(Activity activity) { + activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + } + + public static void clearDisableSoftKeyboardFlags(Activity activity) { + activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + } + + public void setResizeTerminalViewForSoftKeyboardFlags() { + // TODO: The flag is deprecated for API 30 and WindowInset API should be used + // https://developer.android.com/reference/android/view/WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE + // https://medium.com/androiddevelopers/animating-your-keyboard-fb776a8fb66d + // https://stackoverflow.com/a/65194077/14686958 + mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + } + + /** + * Called when user requests the soft keyboard to be toggled via "KEYBOARD" toggle button in + * drawer or extra keys, or with ctrl+alt+k hardware keyboard shortcut. + */ + public void onToggleSoftKeyboardRequest() { + // If soft keyboard is disabled by user for Termux + if (!mActivity.getPreferences().getSoftKeyboardEnabled()) { + disableSoftKeyboard(mActivity, mActivity.getTerminalView()); + } else { + clearDisableSoftKeyboardFlags(mActivity); + toggleSoftKeyboard(mActivity); + } + } + + public void setSoftKeyboardState(boolean isStartup) { + // If soft keyboard is disabled by user for Termux + if (!mActivity.getPreferences().getSoftKeyboardEnabled()) { + disableSoftKeyboard(mActivity, mActivity.getTerminalView()); + } else { + // Set flag to automatically push up TerminalView when keyboard is opened instead of showing over it + setResizeTerminalViewForSoftKeyboardFlags(); + + // Clear any previous flags to disable soft keyboard in case setting updated + clearDisableSoftKeyboardFlags(mActivity); + + // If soft keyboard is to be hidden on startup + if (isStartup && mActivity.getProperties().shouldSoftKeyboardBeHiddenOnStartup()) { + hideSoftKeyboard(mActivity, mActivity.getTerminalView()); + } else { + // Force show soft keyboard + showSoftKeyboard(mActivity, mActivity.getTerminalView()); + + mActivity.getTerminalView().setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View view, boolean hasFocus) { + if (hasFocus) { + showSoftKeyboard(mActivity, mActivity.getTerminalView()); + } else { + hideSoftKeyboard(mActivity, mActivity.getTerminalView()); + } + } + }); + + // Request focus for TerminalView + mActivity.getTerminalView().requestFocus(); + } } } diff --git a/app/src/main/java/com/termux/app/terminal/io/TerminalToolbarViewPager.java b/app/src/main/java/com/termux/app/terminal/io/TerminalToolbarViewPager.java index 06bdfe19..5e7adfb8 100644 --- a/app/src/main/java/com/termux/app/terminal/io/TerminalToolbarViewPager.java +++ b/app/src/main/java/com/termux/app/terminal/io/TerminalToolbarViewPager.java @@ -44,6 +44,7 @@ public class TerminalToolbarViewPager { if (position == 0) { layout = inflater.inflate(R.layout.view_terminal_toolbar_extra_keys, collection, false); ExtraKeysView extraKeysView = (ExtraKeysView) layout; + extraKeysView.setTermuxTerminalViewClient(mActivity.getTermuxTerminalViewClient()); mActivity.setExtraKeysView(extraKeysView); extraKeysView.reload(mActivity.getProperties().getExtraKeysInfo()); diff --git a/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysView.java b/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysView.java index da4cbeaf..31afa07f 100644 --- a/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysView.java +++ b/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysView.java @@ -23,12 +23,12 @@ import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; -import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.GridLayout; import android.widget.PopupWindow; import com.termux.R; +import com.termux.app.terminal.TermuxTerminalViewClient; import com.termux.view.TerminalView; import androidx.drawerlayout.widget.DrawerLayout; @@ -44,6 +44,8 @@ public final class ExtraKeysView extends GridLayout { private static final int INTERESTING_COLOR = 0xFF80DEEA; private static final int BUTTON_PRESSED_COLOR = 0xFF7F7F7F; + TermuxTerminalViewClient mTermuxTerminalViewClient; + public ExtraKeysView(Context context, AttributeSet attrs) { super(context, attrs); } @@ -82,8 +84,8 @@ public final class ExtraKeysView extends GridLayout { private void sendKey(View view, String keyName, boolean forceCtrlDown, boolean forceLeftAltDown) { TerminalView terminalView = view.findViewById(R.id.terminal_view); if ("KEYBOARD".equals(keyName)) { - InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.toggleSoftInput(0, 0); + if(mTermuxTerminalViewClient != null) + mTermuxTerminalViewClient.onToggleSoftKeyboardRequest(); } else if ("DRAWER".equals(keyName)) { DrawerLayout drawer = view.findViewById(R.id.drawer_layout); drawer.openDrawer(Gravity.LEFT); @@ -379,4 +381,8 @@ public final class ExtraKeysView extends GridLayout { } } + public void setTermuxTerminalViewClient(TermuxTerminalViewClient termuxTerminalViewClient) { + this.mTermuxTerminalViewClient = termuxTerminalViewClient; + } + }