diff options
| author | Jules Aguillon | 2025-12-18 19:15:32 +0100 |
|---|---|---|
| committer | GitHub | 2025-12-18 19:15:32 +0100 |
| commit | 41777fdda61715a59be241f0be9a8e3385222888 (patch) | |
| tree | bcddb5a4a29af2caf37e1f565efcfbffdd6814be /srcs/juloo.keyboard2/EditorConfig.java | |
| parent | be0aa07a2a728509b6244e00247bfe2fff5c66e0 (diff) | |
| download | unexpected-keyboard-41777fdda61715a59be241f0be9a8e3385222888.tar.gz unexpected-keyboard-41777fdda61715a59be241f0be9a8e3385222888.zip | |
Disable selection mode in text editors (#1141)
* Disable selection mode in text editors
Selection mode removes the space bar key (which is replaced by the Esc
key) and can be annoying in Emacs for example.
Text editor users probably have the `esc` key available.
* Refactor: Move EditorInfo related code to EditorConfig
Add the new EditorConfig class that handles configuration extracted from
the EditorInfo. It is accessible from the Config class for convenience.
This aims at reducing the length of already large classes and group the
code that was spread over several classes.
Diffstat (limited to 'srcs/juloo.keyboard2/EditorConfig.java')
| -rw-r--r-- | srcs/juloo.keyboard2/EditorConfig.java | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/srcs/juloo.keyboard2/EditorConfig.java b/srcs/juloo.keyboard2/EditorConfig.java new file mode 100644 index 0000000..d9f1ae9 --- /dev/null +++ b/srcs/juloo.keyboard2/EditorConfig.java @@ -0,0 +1,120 @@ +package juloo.keyboard2; + +import android.content.res.Resources; +import android.text.InputType; +import android.text.TextUtils; +import android.view.inputmethod.EditorInfo; + +public final class EditorConfig +{ + public String actionLabel = null; // Might be [null] + /** Action performed by the Action key. Only when [actionLabel != null]. */ + public int actionId; + public boolean swapEnterActionKey = false; // Swap the "enter" and "action" keys + /** Whether selection mode turns on automatically when text is selected. */ + public boolean selection_mode_enabled = true; + /** Whether the numeric layout should be shown by default. */ + public boolean numeric_layout = false; + /** Workaround some apps which answers to [getExtractedText] but do not react + to [setSelection] while returning [true]. */ + public boolean should_move_cursor_force_fallback = false; + + /** Autocapitalisation. */ + public int caps_mode; // Argument for [getCursorCapsMode()] + // Whether caps state is on initially. + public boolean caps_initially_enabled = false; + // Whether caps state should be updated right away. + public boolean caps_initially_updated = false; + + public EditorConfig() {} + + public void refresh(EditorInfo info, Resources res) + { + int inputType = info.inputType & InputType.TYPE_MASK_CLASS; + int options = info.imeOptions; + /* Selection mode. + Editors with [TYPE_NULL] are for example Termux and Emacs. */ + selection_mode_enabled = inputType != InputType.TYPE_NULL; + /* Action key. Looks at [info.actionLabel] first. */ + if (info.actionLabel != null) + { + actionLabel = info.actionLabel.toString(); + actionId = info.actionId; + swapEnterActionKey = false; + } + else + { + actionId = options & EditorInfo.IME_MASK_ACTION; + actionLabel = actionLabel_of_imeAction(actionId, res); + swapEnterActionKey = (options & EditorInfo.IME_FLAG_NO_ENTER_ACTION) == 0; + } + /* Numeric layout */ + switch (inputType) + { + case InputType.TYPE_CLASS_NUMBER: + case InputType.TYPE_CLASS_PHONE: + case InputType.TYPE_CLASS_DATETIME: + numeric_layout = true; + break; + default: + numeric_layout = false; + break; + } + /* setSelection fallback */ + should_move_cursor_force_fallback = _should_move_cursor_force_fallback(info); + /* Autocapitalisation */ + caps_mode = info.inputType & TextUtils.CAP_MODE_SENTENCES; + caps_initially_enabled = (info.initialCapsMode != 0); + caps_initially_updated = caps_should_update_state(info); + } + + String actionLabel_of_imeAction(int action, Resources res) + { + int id; + switch (action) + { + case EditorInfo.IME_ACTION_NEXT: id = R.string.key_action_next; break; + case EditorInfo.IME_ACTION_DONE: id = R.string.key_action_done; break; + case EditorInfo.IME_ACTION_GO: id = R.string.key_action_go; break; + case EditorInfo.IME_ACTION_PREVIOUS: id = R.string.key_action_prev; break; + case EditorInfo.IME_ACTION_SEARCH: id = R.string.key_action_search; break; + case EditorInfo.IME_ACTION_SEND: id = R.string.key_action_send; break; + case EditorInfo.IME_ACTION_UNSPECIFIED: + case EditorInfo.IME_ACTION_NONE: + default: return null; + } + return res.getString(id); + } + + boolean _should_move_cursor_force_fallback(EditorInfo info) + { + // This catch Acode: which sets several variations at once. + if ((info.inputType & InputType.TYPE_MASK_VARIATION & + InputType.TYPE_TEXT_VARIATION_PASSWORD) != 0) + return true; + // Godot editor: Doesn't handle setSelection() but returns true. + return info.packageName.startsWith("org.godotengine.editor"); + } + + /** Whether the caps state should be updated when input starts. [inputType] + is the field from the editor info object. */ + boolean caps_should_update_state(EditorInfo info) + { + int class_ = info.inputType & InputType.TYPE_MASK_CLASS; + int variation = info.inputType & InputType.TYPE_MASK_VARIATION; + if (class_ != InputType.TYPE_CLASS_TEXT) + return false; + switch (variation) + { + case InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE: + case InputType.TYPE_TEXT_VARIATION_NORMAL: + case InputType.TYPE_TEXT_VARIATION_PERSON_NAME: + case InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE: + case InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT: + case InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT: + return true; + default: + return false; + } + } +} |
