From 08b581228883f3b34734cb1b74657dbb8ea6d18f Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Mon, 23 Aug 2021 08:22:14 +0500 Subject: [PATCH] Added!: Convert extra-keys to agnosticism The termux `extra-keys` have been moved to `termux-shared` library so that they can be imported and used by other apps for their own needs as long as they comply with GPLv3 license. Almost everything is customizable and has no dependency on termux specific logic. Check the javadocs of files of `com.termux.shared.terminal.io.extrakeys` package for more info, specially, `ExtraKeysView`, `ExtraKeysInfo`, `ExtraKeyButton`, `TerminalExtraKeys` and `TermuxTerminalExtraKeys`. Moreover, you can now long hold on `CTRL`, `ALT`, `SHIFT` and `FN` to lock those control keys. They will not be released when you press another key and will only be released by pressing the respective control key again. Closes #2049, Closes #1861 --- .../java/com/termux/app/TermuxActivity.java | 2 +- .../properties/TermuxAppSharedProperties.java | 15 +- .../terminal/TermuxTerminalViewClient.java | 16 +- .../terminal/io/TerminalToolbarViewPager.java | 6 +- .../terminal/io/TermuxTerminalExtraKeys.java | 47 ++ .../terminal/io/extrakeys/ExtraKeyButton.java | 92 --- .../terminal/io/extrakeys/ExtraKeysInfo.java | 260 ------- .../terminal/io/extrakeys/ExtraKeysView.java | 401 ----------- .../view_terminal_toolbar_extra_keys.xml | 2 +- .../shared/terminal/io/TerminalExtraKeys.java | 77 +++ .../terminal/io/extrakeys/ExtraKeyButton.java | 151 ++++ .../io/extrakeys/ExtraKeysConstants.java | 207 ++++++ .../terminal/io/extrakeys/ExtraKeysInfo.java | 211 ++++++ .../terminal/io/extrakeys/ExtraKeysView.java | 646 ++++++++++++++++++ .../terminal/io/extrakeys/SpecialButton.java | 52 ++ .../io/extrakeys/SpecialButtonState.java | 49 ++ 16 files changed, 1470 insertions(+), 764 deletions(-) create mode 100644 app/src/main/java/com/termux/app/terminal/io/TermuxTerminalExtraKeys.java delete mode 100644 app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeyButton.java delete mode 100644 app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysInfo.java delete mode 100644 app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysView.java create mode 100644 termux-shared/src/main/java/com/termux/shared/terminal/io/TerminalExtraKeys.java create mode 100644 termux-shared/src/main/java/com/termux/shared/terminal/io/extrakeys/ExtraKeyButton.java create mode 100644 termux-shared/src/main/java/com/termux/shared/terminal/io/extrakeys/ExtraKeysConstants.java create mode 100644 termux-shared/src/main/java/com/termux/shared/terminal/io/extrakeys/ExtraKeysInfo.java create mode 100644 termux-shared/src/main/java/com/termux/shared/terminal/io/extrakeys/ExtraKeysView.java create mode 100644 termux-shared/src/main/java/com/termux/shared/terminal/io/extrakeys/SpecialButton.java create mode 100644 termux-shared/src/main/java/com/termux/shared/terminal/io/extrakeys/SpecialButtonState.java diff --git a/app/src/main/java/com/termux/app/TermuxActivity.java b/app/src/main/java/com/termux/app/TermuxActivity.java index 257ec38993..254b3bc50f 100644 --- a/app/src/main/java/com/termux/app/TermuxActivity.java +++ b/app/src/main/java/com/termux/app/TermuxActivity.java @@ -44,7 +44,7 @@ import com.termux.app.terminal.io.TerminalToolbarViewPager; import com.termux.app.terminal.TermuxTerminalSessionClient; import com.termux.app.terminal.TermuxTerminalViewClient; -import com.termux.app.terminal.io.extrakeys.ExtraKeysView; +import com.termux.shared.terminal.io.extrakeys.ExtraKeysView; import com.termux.app.settings.properties.TermuxAppSharedProperties; import com.termux.shared.interact.TextInputDialogUtils; import com.termux.shared.logger.Logger; diff --git a/app/src/main/java/com/termux/app/settings/properties/TermuxAppSharedProperties.java b/app/src/main/java/com/termux/app/settings/properties/TermuxAppSharedProperties.java index 6c2e03713a..fabe683a3c 100644 --- a/app/src/main/java/com/termux/app/settings/properties/TermuxAppSharedProperties.java +++ b/app/src/main/java/com/termux/app/settings/properties/TermuxAppSharedProperties.java @@ -3,7 +3,9 @@ import android.content.Context; import com.termux.app.terminal.io.KeyboardShortcut; -import com.termux.app.terminal.io.extrakeys.ExtraKeysInfo; +import com.termux.shared.terminal.io.extrakeys.ExtraKeysConstants; +import com.termux.shared.terminal.io.extrakeys.ExtraKeysConstants.EXTRA_KEY_DISPLAY_MAPS; +import com.termux.shared.terminal.io.extrakeys.ExtraKeysInfo; import com.termux.shared.logger.Logger; import com.termux.shared.settings.properties.TermuxPropertyConstants; import com.termux.shared.settings.properties.TermuxSharedProperties; @@ -50,13 +52,20 @@ private void setExtraKeys() { // {@link #getExtraKeysStyleInternalPropertyValueFromValue(String)} String extrakeys = (String) getInternalPropertyValue(TermuxPropertyConstants.KEY_EXTRA_KEYS, true); String extraKeysStyle = (String) getInternalPropertyValue(TermuxPropertyConstants.KEY_EXTRA_KEYS_STYLE, true); - mExtraKeysInfo = new ExtraKeysInfo(extrakeys, extraKeysStyle); + + ExtraKeysConstants.ExtraKeyDisplayMap extraKeyDisplayMap = ExtraKeysInfo.getCharDisplayMapForStyle(extraKeysStyle); + if (EXTRA_KEY_DISPLAY_MAPS.DEFAULT_CHAR_DISPLAY.equals(extraKeyDisplayMap) && !TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS_STYLE.equals(extraKeysStyle)) { + Logger.logError(TermuxSharedProperties.LOG_TAG, "The style \"" + extraKeysStyle + "\" for the key \"" + TermuxPropertyConstants.KEY_EXTRA_KEYS_STYLE + "\" is invalid. Using default style instead."); + extraKeysStyle = TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS_STYLE; + } + + mExtraKeysInfo = new ExtraKeysInfo(extrakeys, extraKeysStyle, ExtraKeysConstants.CONTROL_CHARS_ALIASES); } catch (JSONException e) { Logger.showToast(mContext, "Could not load and set the \"" + TermuxPropertyConstants.KEY_EXTRA_KEYS + "\" property from the properties file: " + e.toString(), true); Logger.logStackTraceWithMessage(LOG_TAG, "Could not load and set the \"" + TermuxPropertyConstants.KEY_EXTRA_KEYS + "\" property from the properties file: ", e); try { - mExtraKeysInfo = new ExtraKeysInfo(TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS, TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS_STYLE); + mExtraKeysInfo = new ExtraKeysInfo(TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS, TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS_STYLE, ExtraKeysConstants.CONTROL_CHARS_ALIASES); } catch (JSONException e2) { Logger.showToast(mContext, "Can't create default extra keys",true); Logger.logStackTraceWithMessage(LOG_TAG, "Could create default extra keys: ", e); 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 7e68d3ecf3..8e720444bc 100644 --- a/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java +++ b/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java @@ -27,13 +27,13 @@ import com.termux.shared.interact.MessageDialogUtils; import com.termux.shared.shell.ShellUtils; import com.termux.shared.terminal.TermuxTerminalViewClientBase; +import com.termux.shared.terminal.io.extrakeys.SpecialButton; import com.termux.shared.termux.AndroidUtils; import com.termux.shared.termux.TermuxConstants; import com.termux.shared.activities.ReportActivity; import com.termux.shared.models.ReportInfo; import com.termux.app.models.UserAction; import com.termux.app.terminal.io.KeyboardShortcut; -import com.termux.app.terminal.io.extrakeys.ExtraKeysView; import com.termux.shared.settings.properties.TermuxPropertyConstants; import com.termux.shared.data.DataUtils; import com.termux.shared.logger.Logger; @@ -289,12 +289,22 @@ private boolean handleVirtualKeys(int keyCode, KeyEvent event, boolean down) { @Override public boolean readControlKey() { - return (mActivity.getExtraKeysView() != null && mActivity.getExtraKeysView().readSpecialButton(ExtraKeysView.SpecialButton.CTRL)) || mVirtualControlKeyDown; + return readExtraKeysSpecialButton(SpecialButton.CTRL) || mVirtualControlKeyDown; } @Override public boolean readAltKey() { - return (mActivity.getExtraKeysView() != null && mActivity.getExtraKeysView().readSpecialButton(ExtraKeysView.SpecialButton.ALT)); + return readExtraKeysSpecialButton(SpecialButton.ALT); + } + + public boolean readExtraKeysSpecialButton(SpecialButton specialButton) { + if (mActivity.getExtraKeysView() == null) return false; + Boolean state = mActivity.getExtraKeysView().readSpecialButton(specialButton, true); + if (state == null) { + Logger.logError(LOG_TAG,"Failed to read an unregistered " + specialButton + " special button value from extra keys."); + return false; + } + return state; } @Override 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 dc306852b2..56f28fc0c2 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 @@ -11,7 +11,7 @@ import com.termux.R; import com.termux.app.TermuxActivity; -import com.termux.app.terminal.io.extrakeys.ExtraKeysView; +import com.termux.shared.terminal.io.extrakeys.ExtraKeysView; import com.termux.terminal.TerminalSession; public class TerminalToolbarViewPager { @@ -44,8 +44,8 @@ public Object instantiateItem(@NonNull ViewGroup collection, int position) { if (position == 0) { layout = inflater.inflate(R.layout.view_terminal_toolbar_extra_keys, collection, false); ExtraKeysView extraKeysView = (ExtraKeysView) layout; - extraKeysView.setTermuxTerminalViewClient(mActivity.getTermuxTerminalViewClient()); - extraKeysView.setTermuxTerminalSessionClient(mActivity.getTermuxTerminalSessionClient()); + extraKeysView.setExtraKeysViewClient(new TermuxTerminalExtraKeys(mActivity.getTerminalView(), + mActivity.getTermuxTerminalViewClient(), mActivity.getTermuxTerminalSessionClient())); mActivity.setExtraKeysView(extraKeysView); extraKeysView.reload(mActivity.getProperties().getExtraKeysInfo()); diff --git a/app/src/main/java/com/termux/app/terminal/io/TermuxTerminalExtraKeys.java b/app/src/main/java/com/termux/app/terminal/io/TermuxTerminalExtraKeys.java new file mode 100644 index 0000000000..483e6c0f2e --- /dev/null +++ b/app/src/main/java/com/termux/app/terminal/io/TermuxTerminalExtraKeys.java @@ -0,0 +1,47 @@ +package com.termux.app.terminal.io; + +import android.annotation.SuppressLint; +import android.view.Gravity; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.drawerlayout.widget.DrawerLayout; + +import com.termux.R; +import com.termux.app.terminal.TermuxTerminalSessionClient; +import com.termux.app.terminal.TermuxTerminalViewClient; +import com.termux.shared.terminal.io.TerminalExtraKeys; +import com.termux.view.TerminalView; + +public class TermuxTerminalExtraKeys extends TerminalExtraKeys { + + + TermuxTerminalViewClient mTermuxTerminalViewClient; + TermuxTerminalSessionClient mTermuxTerminalSessionClient; + + public TermuxTerminalExtraKeys(@NonNull TerminalView terminalView, + TermuxTerminalViewClient termuxTerminalViewClient, + TermuxTerminalSessionClient termuxTerminalSessionClient) { + super(terminalView); + mTermuxTerminalViewClient = termuxTerminalViewClient; + mTermuxTerminalSessionClient = termuxTerminalSessionClient; + } + + @SuppressLint("RtlHardcoded") + @Override + public void onTerminalExtraKeyButtonClick(View view, String key, boolean ctrlDown, boolean altDown, boolean shiftDown, boolean fnDown) { + if ("KEYBOARD".equals(key)) { + if(mTermuxTerminalViewClient != null) + mTermuxTerminalViewClient.onToggleSoftKeyboardRequest(); + } else if ("DRAWER".equals(key)) { + DrawerLayout drawer = view.findViewById(R.id.drawer_layout); + drawer.openDrawer(Gravity.LEFT); + } else if ("PASTE".equals(key)) { + if(mTermuxTerminalSessionClient != null) + mTermuxTerminalSessionClient.onPasteTextFromClipboard(null); + } else { + super.onTerminalExtraKeyButtonClick(view, key, ctrlDown, altDown, shiftDown, fnDown); + } + } + +} diff --git a/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeyButton.java b/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeyButton.java deleted file mode 100644 index 9454081970..0000000000 --- a/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeyButton.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.termux.app.terminal.io.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; - - 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/terminal/io/extrakeys/ExtraKeysInfo.java b/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysInfo.java deleted file mode 100644 index ceaad78739..0000000000 --- a/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysInfo.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.termux.app.terminal.io.extrakeys; - -import com.termux.shared.logger.Logger; -import com.termux.shared.settings.properties.TermuxPropertyConstants; -import com.termux.shared.settings.properties.TermuxSharedProperties; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; - -public class ExtraKeysInfo { - - /** - * Matrix of buttons displayed - */ - private final ExtraKeyButton[][] buttons; - - /** - * This corresponds to one of the CharMapDisplay below - */ - private String style; - - public ExtraKeysInfo(String propertiesInfo, String style) throws JSONException { - this.style = style; - - // Convert String propertiesInfo to Array of Arrays - JSONArray arr = new JSONArray(propertiesInfo); - Object[][] matrix = new Object[arr.length()][]; - for (int i = 0; i < arr.length(); i++) { - JSONArray line = arr.getJSONArray(i); - matrix[i] = new Object[line.length()]; - for (int j = 0; j < line.length(); j++) { - matrix[i][j] = line.get(j); - } - } - - // convert matrix to buttons - this.buttons = new ExtraKeyButton[matrix.length][]; - for (int i = 0; i < matrix.length; i++) { - this.buttons[i] = new ExtraKeyButton[matrix[i].length]; - for (int j = 0; j < matrix[i].length; j++) { - Object key = matrix[i][j]; - - JSONObject jobject = normalizeKeyConfig(key); - - ExtraKeyButton button; - - if (! jobject.has("popup")) { - // no popup - button = new ExtraKeyButton(getSelectedCharMap(), jobject); - } else { - // a popup - JSONObject popupJobject = normalizeKeyConfig(jobject.get("popup")); - ExtraKeyButton popup = new ExtraKeyButton(getSelectedCharMap(), popupJobject); - button = new ExtraKeyButton(getSelectedCharMap(), jobject, popup); - } - - this.buttons[i][j] = button; - } - } - } - - /** - * "hello" -> {"key": "hello"} - */ - private static JSONObject normalizeKeyConfig(Object key) throws JSONException { - JSONObject jobject; - if (key instanceof String) { - jobject = new JSONObject(); - jobject.put("key", key); - } else if (key instanceof JSONObject) { - jobject = (JSONObject) key; - } else { - throw new JSONException("An key in the extra-key matrix must be a string or an object"); - } - return jobject; - } - - public ExtraKeyButton[][] getMatrix() { - return buttons; - } - - /** - * HashMap that implements Python dict.get(key, default) function. - * Default java.util .get(key) is then the same as .get(key, null); - */ - static class CleverMap extends HashMap { - V get(K key, V defaultValue) { - if (containsKey(key)) - return get(key); - else - return defaultValue; - } - } - - static class CharDisplayMap extends CleverMap {} - - /** - * Keys are displayed in a natural looking way, like "→" for "RIGHT" - */ - static final CharDisplayMap classicArrowsDisplay = new CharDisplayMap() {{ - // classic arrow keys (for ◀ ▶ ▲ ▼ @see arrowVariationDisplay) - put("LEFT", "←"); // U+2190 ← LEFTWARDS ARROW - put("RIGHT", "→"); // U+2192 → RIGHTWARDS ARROW - put("UP", "↑"); // U+2191 ↑ UPWARDS ARROW - put("DOWN", "↓"); // U+2193 ↓ DOWNWARDS ARROW - }}; - - static final CharDisplayMap wellKnownCharactersDisplay = new CharDisplayMap() {{ - // well known characters // https://en.wikipedia.org/wiki/{Enter_key, Tab_key, Delete_key} - put("ENTER", "↲"); // U+21B2 ↲ DOWNWARDS ARROW WITH TIP LEFTWARDS - put("TAB", "↹"); // U+21B9 ↹ LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR - put("BKSP", "⌫"); // U+232B ⌫ ERASE TO THE LEFT sometimes seen and easy to understand - put("DEL", "⌦"); // U+2326 ⌦ ERASE TO THE RIGHT not well known but easy to understand - put("DRAWER", "☰"); // U+2630 ☰ TRIGRAM FOR HEAVEN not well known but easy to understand - put("KEYBOARD", "⌨"); // U+2328 ⌨ KEYBOARD not well known but easy to understand - put("PASTE", "⎘"); // U+2398 - }}; - - static final CharDisplayMap lessKnownCharactersDisplay = new CharDisplayMap() {{ - // https://en.wikipedia.org/wiki/{Home_key, End_key, Page_Up_and_Page_Down_keys} - // home key can mean "goto the beginning of line" or "goto first page" depending on context, hence the diagonal - put("HOME", "⇱"); // from IEC 9995 // U+21F1 ⇱ NORTH WEST ARROW TO CORNER - put("END", "⇲"); // from IEC 9995 // ⇲ // U+21F2 ⇲ SOUTH EAST ARROW TO CORNER - put("PGUP", "⇑"); // no ISO character exists, U+21D1 ⇑ UPWARDS DOUBLE ARROW will do the trick - put("PGDN", "⇓"); // no ISO character exists, U+21D3 ⇓ DOWNWARDS DOUBLE ARROW will do the trick - }}; - - static final CharDisplayMap arrowTriangleVariationDisplay = new CharDisplayMap() {{ - // alternative to classic arrow keys - put("LEFT", "◀"); // U+25C0 ◀ BLACK LEFT-POINTING TRIANGLE - put("RIGHT", "▶"); // U+25B6 ▶ BLACK RIGHT-POINTING TRIANGLE - put("UP", "▲"); // U+25B2 ▲ BLACK UP-POINTING TRIANGLE - put("DOWN", "▼"); // U+25BC ▼ BLACK DOWN-POINTING TRIANGLE - }}; - - static final CharDisplayMap notKnownIsoCharacters = new CharDisplayMap() {{ - // Control chars that are more clear as text // https://en.wikipedia.org/wiki/{Function_key, Alt_key, Control_key, Esc_key} - // put("FN", "FN"); // no ISO character exists - put("CTRL", "⎈"); // ISO character "U+2388 ⎈ HELM SYMBOL" is unknown to people and never printed on computers, however "U+25C7 ◇ WHITE DIAMOND" is a nice presentation, and "^" for terminal app and mac is often used - put("ALT", "⎇"); // ISO character "U+2387 ⎇ ALTERNATIVE KEY SYMBOL'" is unknown to people and only printed as the Option key "⌥" on Mac computer - put("ESC", "⎋"); // ISO character "U+238B ⎋ BROKEN CIRCLE WITH NORTHWEST ARROW" is unknown to people and not often printed on computers - }}; - - static final CharDisplayMap nicerLookingDisplay = new CharDisplayMap() {{ - // nicer looking for most cases - put("-", "―"); // U+2015 ― HORIZONTAL BAR - }}; - - /* - * Multiple maps are available to quickly change - * the style of the keys. - */ - - /** - * Some classic symbols everybody knows - */ - private static final CharDisplayMap defaultCharDisplay = new CharDisplayMap() {{ - putAll(classicArrowsDisplay); - putAll(wellKnownCharactersDisplay); - putAll(nicerLookingDisplay); - // all other characters are displayed as themselves - }}; - - /** - * Classic symbols and less known symbols - */ - private static final CharDisplayMap lotsOfArrowsCharDisplay = new CharDisplayMap() {{ - putAll(classicArrowsDisplay); - putAll(wellKnownCharactersDisplay); - putAll(lessKnownCharactersDisplay); // NEW - putAll(nicerLookingDisplay); - }}; - - /** - * Only arrows - */ - private static final CharDisplayMap arrowsOnlyCharDisplay = new CharDisplayMap() {{ - putAll(classicArrowsDisplay); - // putAll(wellKnownCharactersDisplay); // REMOVED - // putAll(lessKnownCharactersDisplay); // REMOVED - putAll(nicerLookingDisplay); - }}; - - /** - * Full Iso - */ - private static final CharDisplayMap fullIsoCharDisplay = new CharDisplayMap() {{ - putAll(classicArrowsDisplay); - putAll(wellKnownCharactersDisplay); - putAll(lessKnownCharactersDisplay); // NEW - putAll(nicerLookingDisplay); - putAll(notKnownIsoCharacters); // NEW - }}; - - /** - * Some people might call our keys differently - */ - static private final CharDisplayMap controlCharsAliases = new CharDisplayMap() {{ - put("ESCAPE", "ESC"); - put("CONTROL", "CTRL"); - put("RETURN", "ENTER"); // Technically different keys, but most applications won't see the difference - put("FUNCTION", "FN"); - // no alias for ALT - - // Directions are sometimes written as first and last letter for brevety - put("LT", "LEFT"); - put("RT", "RIGHT"); - put("DN", "DOWN"); - // put("UP", "UP"); well, "UP" is already two letters - - put("PAGEUP", "PGUP"); - put("PAGE_UP", "PGUP"); - put("PAGE UP", "PGUP"); - put("PAGE-UP", "PGUP"); - - // no alias for HOME - // no alias for END - - put("PAGEDOWN", "PGDN"); - put("PAGE_DOWN", "PGDN"); - put("PAGE-DOWN", "PGDN"); - - put("DELETE", "DEL"); - put("BACKSPACE", "BKSP"); - - // easier for writing in termux.properties - put("BACKSLASH", "\\"); - put("QUOTE", "\""); - put("APOSTROPHE", "'"); - }}; - - CharDisplayMap getSelectedCharMap() { - switch (style) { - case "arrows-only": - return arrowsOnlyCharDisplay; - case "arrows-all": - return lotsOfArrowsCharDisplay; - case "all": - return fullIsoCharDisplay; - case "none": - return new CharDisplayMap(); - default: - if (!TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS_STYLE.equals(style)) - Logger.logError(TermuxSharedProperties.LOG_TAG, "The style \"" + style + "\" for the key \"" + TermuxPropertyConstants.KEY_EXTRA_KEYS_STYLE + "\" is invalid. Using default style instead."); - return defaultCharDisplay; - } - } - - /** - * Applies the 'controlCharsAliases' mapping to all the strings in *buttons* - * Modifies the array, doesn't return a new one. - */ - public static String replaceAlias(String key) { - return controlCharsAliases.get(key, key); - } -} - 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 deleted file mode 100644 index 79aceaa17d..0000000000 --- a/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysView.java +++ /dev/null @@ -1,401 +0,0 @@ -package com.termux.app.terminal.io.extrakeys; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.os.Build; -import android.provider.Settings; -import android.util.AttributeSet; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.ScheduledExecutorService; - -import java.util.Map; -import java.util.HashMap; -import java.util.Arrays; -import java.util.stream.Collectors; - -import android.view.Gravity; -import android.view.HapticFeedbackConstants; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.widget.Button; -import android.widget.GridLayout; -import android.widget.PopupWindow; - -import com.termux.R; -import com.termux.app.terminal.TermuxTerminalSessionClient; -import com.termux.app.terminal.TermuxTerminalViewClient; -import com.termux.view.TerminalView; - -import androidx.drawerlayout.widget.DrawerLayout; - -/** - * A view showing extra keys (such as Escape, Ctrl, Alt) not normally available on an Android soft - * keyboard. - */ -public final class ExtraKeysView extends GridLayout { - - private static final int TEXT_COLOR = 0xFFFFFFFF; - private static final int BUTTON_COLOR = 0x00000000; - private static final int INTERESTING_COLOR = 0xFF80DEEA; - private static final int BUTTON_PRESSED_COLOR = 0xFF7F7F7F; - - TermuxTerminalViewClient mTermuxTerminalViewClient; - TermuxTerminalSessionClient mTermuxTerminalSessionClient; - - public ExtraKeysView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - static final Map keyCodesForString = new HashMap() {{ - put("SPACE", KeyEvent.KEYCODE_SPACE); - put("ESC", KeyEvent.KEYCODE_ESCAPE); - put("TAB", KeyEvent.KEYCODE_TAB); - put("HOME", KeyEvent.KEYCODE_MOVE_HOME); - put("END", KeyEvent.KEYCODE_MOVE_END); - put("PGUP", KeyEvent.KEYCODE_PAGE_UP); - put("PGDN", KeyEvent.KEYCODE_PAGE_DOWN); - put("INS", KeyEvent.KEYCODE_INSERT); - put("DEL", KeyEvent.KEYCODE_FORWARD_DEL); - put("BKSP", KeyEvent.KEYCODE_DEL); - put("UP", KeyEvent.KEYCODE_DPAD_UP); - put("LEFT", KeyEvent.KEYCODE_DPAD_LEFT); - put("RIGHT", KeyEvent.KEYCODE_DPAD_RIGHT); - put("DOWN", KeyEvent.KEYCODE_DPAD_DOWN); - put("ENTER", KeyEvent.KEYCODE_ENTER); - put("F1", KeyEvent.KEYCODE_F1); - put("F2", KeyEvent.KEYCODE_F2); - put("F3", KeyEvent.KEYCODE_F3); - put("F4", KeyEvent.KEYCODE_F4); - put("F5", KeyEvent.KEYCODE_F5); - put("F6", KeyEvent.KEYCODE_F6); - put("F7", KeyEvent.KEYCODE_F7); - put("F8", KeyEvent.KEYCODE_F8); - put("F9", KeyEvent.KEYCODE_F9); - put("F10", KeyEvent.KEYCODE_F10); - put("F11", KeyEvent.KEYCODE_F11); - 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)) { - if(mTermuxTerminalViewClient != null) - mTermuxTerminalViewClient.onToggleSoftKeyboardRequest(); - } else if ("DRAWER".equals(keyName)) { - DrawerLayout drawer = view.findViewById(R.id.drawer_layout); - drawer.openDrawer(Gravity.LEFT); - } else if ("PASTE".equals(keyName)) { - if(mTermuxTerminalSessionClient != null) - mTermuxTerminalSessionClient.onPasteTextFromClipboard(null); - } else if (keyCodesForString.containsKey(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; - } - if (forceLeftAltDown) { - metaState |= KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON; - } - KeyEvent keyEvent = new KeyEvent(0, 0, KeyEvent.ACTION_UP, keyCode, 0, metaState); - terminalView.onKeyDown(keyCode, keyEvent); - } else { - // not a control char - keyName.codePoints().forEach(codePoint -> { - terminalView.inputCodePoint(codePoint, forceCtrlDown, forceLeftAltDown); - }); - } - } - - private void sendKey(View view, ExtraKeyButton buttonInfo) { - if (buttonInfo.isMacro()) { - String[] keys = buttonInfo.getKey().split(" "); - boolean ctrlDown = false; - boolean altDown = false; - for (String key : keys) { - if ("CTRL".equals(key)) { - ctrlDown = true; - } else if ("ALT".equals(key)) { - altDown = true; - } else { - sendKey(view, key, ctrlDown, altDown); - ctrlDown = false; - altDown = false; - } - } - } else { - sendKey(view, buttonInfo.getKey(), false, false); - } - } - - public enum SpecialButton { - CTRL, ALT, FN - } - - private static class SpecialButtonState { - boolean isOn = false; - boolean isActive = false; - List