diff --git a/app/src/main/java/com/termux/app/TermuxActivity.java b/app/src/main/java/com/termux/app/TermuxActivity.java index a6e1d985..292cdf9e 100644 --- a/app/src/main/java/com/termux/app/TermuxActivity.java +++ b/app/src/main/java/com/termux/app/TermuxActivity.java @@ -48,6 +48,9 @@ import android.widget.Toast; import com.termux.R; import com.termux.app.TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY; +import com.termux.app.input.BellHandler; +import com.termux.app.input.extrakeys.ExtraKeysView; +import com.termux.app.input.FullScreenWorkAround; import com.termux.terminal.EmulatorDebug; import com.termux.terminal.TerminalColors; import com.termux.terminal.TerminalSession; @@ -455,7 +458,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection mBellSoundPool.play(mBellSoundId, 1.f, 1.f, 1, 0, 1.f); break; case TermuxPreferences.BELL_VIBRATE: - BellUtil.getInstance(TermuxActivity.this).doBell(); + BellHandler.getInstance(TermuxActivity.this).doBell(); break; case TermuxPreferences.BELL_IGNORE: // Ignore the bell character. diff --git a/app/src/main/java/com/termux/app/TermuxViewClient.java b/app/src/main/java/com/termux/app/TermuxViewClient.java index ec962a88..3e92c933 100644 --- a/app/src/main/java/com/termux/app/TermuxViewClient.java +++ b/app/src/main/java/com/termux/app/TermuxViewClient.java @@ -8,6 +8,7 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.inputmethod.InputMethodManager; +import com.termux.app.input.extrakeys.ExtraKeysView; import com.termux.terminal.KeyHandler; import com.termux.terminal.TerminalEmulator; import com.termux.terminal.TerminalSession; diff --git a/app/src/main/java/com/termux/app/BellUtil.java b/app/src/main/java/com/termux/app/input/BellHandler.java similarity index 81% rename from app/src/main/java/com/termux/app/BellUtil.java rename to app/src/main/java/com/termux/app/input/BellHandler.java index 666124ce..0610971e 100644 --- a/app/src/main/java/com/termux/app/BellUtil.java +++ b/app/src/main/java/com/termux/app/input/BellHandler.java @@ -1,4 +1,4 @@ -package com.termux.app; +package com.termux.app.input; import android.content.Context; import android.os.Handler; @@ -6,15 +6,15 @@ import android.os.Looper; import android.os.SystemClock; import android.os.Vibrator; -public class BellUtil { - private static BellUtil instance = null; +public class BellHandler { + private static BellHandler instance = null; private static final Object lock = new Object(); - public static BellUtil getInstance(Context context) { + public static BellHandler getInstance(Context context) { if (instance == null) { synchronized (lock) { if (instance == null) { - instance = new BellUtil((Vibrator) context.getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE)); + instance = new BellHandler((Vibrator) context.getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE)); } } } @@ -29,7 +29,7 @@ public class BellUtil { private long lastBell = 0; private final Runnable bellRunnable; - private BellUtil(final Vibrator vibrator) { + private BellHandler(final Vibrator vibrator) { bellRunnable = new Runnable() { @Override public void run() { diff --git a/app/src/main/java/com/termux/app/FullScreenWorkAround.java b/app/src/main/java/com/termux/app/input/FullScreenWorkAround.java similarity index 91% rename from app/src/main/java/com/termux/app/FullScreenWorkAround.java rename to app/src/main/java/com/termux/app/input/FullScreenWorkAround.java index 006918ee..6002f8c8 100644 --- a/app/src/main/java/com/termux/app/FullScreenWorkAround.java +++ b/app/src/main/java/com/termux/app/input/FullScreenWorkAround.java @@ -1,9 +1,11 @@ -package com.termux.app; +package com.termux.app.input; import android.graphics.Rect; import android.view.View; import android.view.ViewGroup; +import com.termux.app.TermuxActivity; + /** * Work around for fullscreen mode in Termux to fix ExtraKeysView not being visible. * This class is derived from: @@ -13,11 +15,11 @@ import android.view.ViewGroup; * For more information, see https://issuetracker.google.com/issues/36911528 */ public class FullScreenWorkAround { - private View mChildOfContent; + private final View mChildOfContent; private int mUsableHeightPrevious; - private ViewGroup.LayoutParams mViewGroupLayoutParams; + private final ViewGroup.LayoutParams mViewGroupLayoutParams; - private int mNavBarHeight; + private final int mNavBarHeight; public static void apply(TermuxActivity activity) { diff --git a/app/src/main/java/com/termux/app/input/KeyboardShortcut.java b/app/src/main/java/com/termux/app/input/KeyboardShortcut.java new file mode 100644 index 00000000..7308c94c --- /dev/null +++ b/app/src/main/java/com/termux/app/input/KeyboardShortcut.java @@ -0,0 +1,13 @@ +package com.termux.app.input; + +public class KeyboardShortcut { + + public final int codePoint; + public final int shortcutAction; + + public KeyboardShortcut(int codePoint, int shortcutAction) { + this.codePoint = codePoint; + this.shortcutAction = shortcutAction; + } + +} diff --git a/app/src/main/java/com/termux/app/input/extrakeys/ExtraKeyButton.java b/app/src/main/java/com/termux/app/input/extrakeys/ExtraKeyButton.java new file mode 100644 index 00000000..1218ef78 --- /dev/null +++ b/app/src/main/java/com/termux/app/input/extrakeys/ExtraKeyButton.java @@ -0,0 +1,92 @@ +package com.termux.app.input.extrakeys; + +import android.text.TextUtils; + +import androidx.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public class ExtraKeyButton { + + /** + * The key that will be sent to the terminal, either a control character + * defined in ExtraKeysView.keyCodesForString (LEFT, RIGHT, PGUP...) or + * some text. + */ + private final String key; + + /** + * If the key is a macro, i.e. a sequence of keys separated by space. + */ + private final boolean macro; + + /** + * The text that will be shown on the button. + */ + private final String display; + + /** + * The information of the popup (triggered by swipe up). + */ + @Nullable + private ExtraKeyButton popup = null; + + public ExtraKeyButton(ExtraKeysInfo.CharDisplayMap charDisplayMap, JSONObject config) throws JSONException { + this(charDisplayMap, config, null); + } + + public ExtraKeyButton(ExtraKeysInfo.CharDisplayMap charDisplayMap, JSONObject config, @Nullable ExtraKeyButton popup) throws JSONException { + String keyFromConfig = config.optString("key", null); + String macroFromConfig = config.optString("macro", null); + String[] keys; + if (keyFromConfig != null && macroFromConfig != null) { + throw new JSONException("Both key and macro can't be set for the same key"); + } else if (keyFromConfig != null) { + keys = new String[]{keyFromConfig}; + this.macro = false; + } else if (macroFromConfig != null) { + keys = macroFromConfig.split(" "); + this.macro = true; + } else { + throw new JSONException("All keys have to specify either key or macro"); + } + + for (int i = 0; i < keys.length; i++) { + keys[i] = ExtraKeysInfo.replaceAlias(keys[i]); + } + + this.key = TextUtils.join(" ", keys); + + String displayFromConfig = config.optString("display", null); + if (displayFromConfig != null) { + this.display = displayFromConfig; + } else { + this.display = Arrays.stream(keys) + .map(key -> charDisplayMap.get(key, key)) + .collect(Collectors.joining(" ")); + } + + this.popup = popup; + } + + public String getKey() { + return key; + } + + public boolean isMacro() { + return macro; + } + + public String getDisplay() { + return display; + } + + @Nullable + public ExtraKeyButton getPopup() { + return popup; + } +} diff --git a/app/src/main/java/com/termux/app/ExtraKeysInfos.java b/app/src/main/java/com/termux/app/input/extrakeys/ExtraKeysInfo.java similarity index 77% rename from app/src/main/java/com/termux/app/ExtraKeysInfos.java rename to app/src/main/java/com/termux/app/input/extrakeys/ExtraKeysInfo.java index 1274c224..c71f3b1f 100644 --- a/app/src/main/java/com/termux/app/ExtraKeysInfos.java +++ b/app/src/main/java/com/termux/app/input/extrakeys/ExtraKeysInfo.java @@ -1,31 +1,24 @@ -package com.termux.app; - -import android.text.TextUtils; - -import androidx.annotation.Nullable; +package com.termux.app.input.extrakeys; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.util.Arrays; import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; -public class ExtraKeysInfos { +public class ExtraKeysInfo { /** * Matrix of buttons displayed */ - private ExtraKeyButton[][] buttons; + private final ExtraKeyButton[][] buttons; /** * This corresponds to one of the CharMapDisplay below */ private String style = "default"; - public ExtraKeysInfos(String propertiesInfo, String style) throws JSONException { + public ExtraKeysInfo(String propertiesInfo, String style) throws JSONException { this.style = style; // Convert String propertiesInfo to Array of Arrays @@ -151,7 +144,7 @@ public class ExtraKeysInfos { put("-", "―"); // U+2015 ― HORIZONTAL BAR }}; - /** + /* * Multiple maps are available to quickly change * the style of the keys. */ @@ -258,83 +251,3 @@ public class ExtraKeysInfos { } } -class ExtraKeyButton { - - /** - * The key that will be sent to the terminal, either a control character - * defined in ExtraKeysView.keyCodesForString (LEFT, RIGHT, PGUP...) or - * some text. - */ - private String key; - - /** - * If the key is a macro, i.e. a sequence of keys separated by space. - */ - private boolean macro; - - /** - * The text that will be shown on the button. - */ - private String display; - - /** - * The information of the popup (triggered by swipe up). - */ - @Nullable - private ExtraKeyButton popup = null; - - public ExtraKeyButton(ExtraKeysInfos.CharDisplayMap charDisplayMap, JSONObject config) throws JSONException { - this(charDisplayMap, config, null); - } - - public ExtraKeyButton(ExtraKeysInfos.CharDisplayMap charDisplayMap, JSONObject config, ExtraKeyButton popup) throws JSONException { - String keyFromConfig = config.optString("key", null); - String macroFromConfig = config.optString("macro", null); - String[] keys; - if (keyFromConfig != null && macroFromConfig != null) { - throw new JSONException("Both key and macro can't be set for the same key"); - } else if (keyFromConfig != null) { - keys = new String[]{keyFromConfig}; - this.macro = false; - } else if (macroFromConfig != null) { - keys = macroFromConfig.split(" "); - this.macro = true; - } else { - throw new JSONException("All keys have to specify either key or macro"); - } - - for (int i = 0; i < keys.length; i++) { - keys[i] = ExtraKeysInfos.replaceAlias(keys[i]); - } - - this.key = TextUtils.join(" ", keys); - - String displayFromConfig = config.optString("display", null); - if (displayFromConfig != null) { - this.display = displayFromConfig; - } else { - this.display = Arrays.stream(keys) - .map(key -> charDisplayMap.get(key, key)) - .collect(Collectors.joining(" ")); - } - - this.popup = popup; - } - - public String getKey() { - return key; - } - - public boolean isMacro() { - return macro; - } - - public String getDisplay() { - return display; - } - - @Nullable - public ExtraKeyButton getPopup() { - return popup; - } -} diff --git a/app/src/main/java/com/termux/app/ExtraKeysView.java b/app/src/main/java/com/termux/app/input/extrakeys/ExtraKeysView.java similarity index 96% rename from app/src/main/java/com/termux/app/ExtraKeysView.java rename to app/src/main/java/com/termux/app/input/extrakeys/ExtraKeysView.java index e475e32a..92e1c370 100644 --- a/app/src/main/java/com/termux/app/ExtraKeysView.java +++ b/app/src/main/java/com/termux/app/input/extrakeys/ExtraKeysView.java @@ -1,4 +1,4 @@ -package com.termux.app; +package com.termux.app.input.extrakeys; import android.annotation.SuppressLint; import android.content.Context; @@ -78,6 +78,7 @@ public final class ExtraKeysView extends GridLayout { put("F12", KeyEvent.KEYCODE_F12); }}; + @SuppressLint("RtlHardcoded") private void sendKey(View view, String keyName, boolean forceCtrlDown, boolean forceLeftAltDown) { TerminalView terminalView = view.findViewById(R.id.terminal_view); if ("KEYBOARD".equals(keyName)) { @@ -87,7 +88,8 @@ public final class ExtraKeysView extends GridLayout { DrawerLayout drawer = view.findViewById(R.id.drawer_layout); drawer.openDrawer(Gravity.LEFT); } else if (keyCodesForString.containsKey(keyName)) { - int keyCode = keyCodesForString.get(keyName); + Integer keyCode = keyCodesForString.get(keyName); + if (keyCode == null) return; int metaState = 0; if (forceCtrlDown) { metaState |= KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON; @@ -172,6 +174,7 @@ public final class ExtraKeysView extends GridLayout { private Button createSpecialButton(String buttonKey, boolean needUpdate) { SpecialButtonState state = specialButtons.get(SpecialButton.valueOf(buttonKey)); + if (state == null) return null; state.isOn = true; Button button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); button.setTextColor(state.isActive ? INTERESTING_COLOR : TEXT_COLOR); @@ -187,6 +190,7 @@ public final class ExtraKeysView extends GridLayout { Button button; if(isSpecialButton(extraButton)) { button = createSpecialButton(extraButton.getKey(), false); + if (button == null) return; } else { button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); button.setTextColor(TEXT_COLOR); @@ -235,7 +239,7 @@ public final class ExtraKeysView extends GridLayout { * "-_-" will input the string "-_-" */ @SuppressLint("ClickableViewAccessibility") - void reload(ExtraKeysInfos infos) { + public void reload(ExtraKeysInfo infos) { if(infos == null) return; @@ -256,6 +260,7 @@ public final class ExtraKeysView extends GridLayout { Button button; if(isSpecialButton(buttonInfo)) { button = createSpecialButton(buttonInfo.getKey(), true); + if (button == null) return; } else { button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); } @@ -282,6 +287,7 @@ public final class ExtraKeysView extends GridLayout { View root = getRootView(); if (isSpecialButton(buttonInfo)) { SpecialButtonState state = specialButtons.get(SpecialButton.valueOf(buttonInfo.getKey())); + if (state == null) return; state.setIsActive(!state.isActive); } else { sendKey(root, buttonInfo); @@ -343,6 +349,7 @@ public final class ExtraKeysView extends GridLayout { if (buttonInfo.getPopup() != null) { if (isSpecialButton(buttonInfo.getPopup())) { SpecialButtonState state = specialButtons.get(SpecialButton.valueOf(buttonInfo.getPopup().getKey())); + if (state == null) return true; state.setIsActive(!state.isActive); } else { sendKey(root, buttonInfo.getPopup()); diff --git a/app/src/main/res/layout/extra_keys_main.xml b/app/src/main/res/layout/extra_keys_main.xml index 45dfab6c..90584317 100644 --- a/app/src/main/res/layout/extra_keys_main.xml +++ b/app/src/main/res/layout/extra_keys_main.xml @@ -1,5 +1,5 @@ -