abouttreesummaryrefslogcommitdiff
path: root/srcs
diff options
context:
space:
mode:
authorJules Aguillon2025-12-18 19:15:32 +0100
committerGitHub2025-12-18 19:15:32 +0100
commit41777fdda61715a59be241f0be9a8e3385222888 (patch)
treebcddb5a4a29af2caf37e1f565efcfbffdd6814be /srcs
parentbe0aa07a2a728509b6244e00247bfe2fff5c66e0 (diff)
downloadunexpected-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')
-rw-r--r--srcs/juloo.keyboard2/Autocapitalisation.java39
-rw-r--r--srcs/juloo.keyboard2/Config.java9
-rw-r--r--srcs/juloo.keyboard2/EditorConfig.java120
-rw-r--r--srcs/juloo.keyboard2/KeyEventHandler.java20
-rw-r--r--srcs/juloo.keyboard2/Keyboard2.java65
-rw-r--r--srcs/juloo.keyboard2/Keyboard2View.java5
-rw-r--r--srcs/juloo.keyboard2/LayoutModifier.java12
-rw-r--r--srcs/juloo.keyboard2/Logs.java5
8 files changed, 157 insertions, 118 deletions
diff --git a/srcs/juloo.keyboard2/Autocapitalisation.java b/srcs/juloo.keyboard2/Autocapitalisation.java
index ec730d5..31d9a7b 100644
--- a/srcs/juloo.keyboard2/Autocapitalisation.java
+++ b/srcs/juloo.keyboard2/Autocapitalisation.java
@@ -2,8 +2,6 @@ package juloo.keyboard2;
import android.os.Handler;
import android.text.InputType;
-import android.text.TextUtils;
-import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.KeyEvent;
@@ -22,10 +20,6 @@ public final class Autocapitalisation
/** Keep track of the cursor to recognize cursor movements from typing. */
int _cursor;
- static int SUPPORTED_CAPS_MODES =
- InputType.TYPE_TEXT_FLAG_CAP_SENTENCES |
- InputType.TYPE_TEXT_FLAG_CAP_WORDS;
-
public Autocapitalisation(Handler h, Callback cb)
{
_handler = h;
@@ -37,18 +31,19 @@ public final class Autocapitalisation
* [started] does initialisation work and must be called before any other
* event.
*/
- public void started(EditorInfo info, InputConnection ic)
+ public void started(Config config, InputConnection ic)
{
_ic = ic;
- _caps_mode = info.inputType & TextUtils.CAP_MODE_SENTENCES;
- if (!Config.globalConfig().autocapitalisation || _caps_mode == 0)
+ EditorConfig ec = config.editor_config;
+ if (!config.autocapitalisation || ec.caps_mode == 0)
{
_enabled = false;
return;
}
_enabled = true;
- _should_enable_shift = (info.initialCapsMode != 0);
- _should_update_caps_mode = started_should_update_state(info.inputType);
+ _caps_mode = ec.caps_mode;
+ _should_enable_shift = ec.caps_initially_enabled;
+ _should_update_caps_mode = ec.caps_initially_updated;
callback_now(true);
}
@@ -178,26 +173,4 @@ public final class Autocapitalisation
return false;
}
}
-
- /** Whether the caps state should be updated when input starts. [inputType]
- is the field from the editor info object. */
- boolean started_should_update_state(int inputType)
- {
- int class_ = inputType & InputType.TYPE_MASK_CLASS;
- int variation = 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;
- }
- }
}
diff --git a/srcs/juloo.keyboard2/Config.java b/srcs/juloo.keyboard2/Config.java
index 5dbf030..577ace5 100644
--- a/srcs/juloo.keyboard2/Config.java
+++ b/srcs/juloo.keyboard2/Config.java
@@ -73,10 +73,9 @@ public final class Config
public int clipboard_history_duration;
// Dynamically set
+ /** Configuration options implied by the connected editor. */
+ public EditorConfig editor_config;
public boolean shouldOfferVoiceTyping;
- public String actionLabel; // Might be 'null'
- public int actionId; // Meaningful only when 'actionLabel' isn't 'null'
- public boolean swapEnterActionKey; // Swap the "enter" and "action" keys
public ExtraKeys extra_keys_subtype;
public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_param;
public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_custom;
@@ -93,6 +92,7 @@ public final class Config
private Config(SharedPreferences prefs, Resources res, IKeyEventHandler h, Boolean foldableUnfolded)
{
_prefs = prefs;
+ editor_config = new EditorConfig();
// static values
marginTop = res.getDimension(R.dimen.margin_top);
keyPadding = res.getDimension(R.dimen.key_padding);
@@ -102,9 +102,6 @@ public final class Config
refresh(res, foldableUnfolded);
// initialized later
shouldOfferVoiceTyping = false;
- actionLabel = null;
- actionId = 0;
- swapEnterActionKey = false;
extra_keys_subtype = null;
handler = h;
}
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;
+ }
+ }
+}
diff --git a/srcs/juloo.keyboard2/KeyEventHandler.java b/srcs/juloo.keyboard2/KeyEventHandler.java
index 33089d9..21a60c1 100644
--- a/srcs/juloo.keyboard2/KeyEventHandler.java
+++ b/srcs/juloo.keyboard2/KeyEventHandler.java
@@ -3,10 +3,8 @@ package juloo.keyboard2;
import android.annotation.SuppressLint;
import android.os.Looper;
import android.os.Handler;
-import android.text.InputType;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
-import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
@@ -38,10 +36,11 @@ public final class KeyEventHandler
}
/** Editing just started. */
- public void started(EditorInfo info)
+ public void started(Config conf)
{
- _autocap.started(info, _recv.getCurrentInputConnection());
- _move_cursor_force_fallback = should_move_cursor_force_fallback(info);
+ _autocap.started(conf, _recv.getCurrentInputConnection());
+ _move_cursor_force_fallback =
+ conf.editor_config.should_move_cursor_force_fallback;
}
/** Selection has been updated. */
@@ -468,17 +467,6 @@ public final class KeyEventHandler
return (conn.getSelectedText(0) != null);
}
- /** Workaround some apps which answers to [getExtractedText] but do not react
- to [setSelection] while returning [true]. */
- 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");
- }
-
public static interface IReceiver
{
public void handle_event_key(KeyValue.Event ev);
diff --git a/srcs/juloo.keyboard2/Keyboard2.java b/srcs/juloo.keyboard2/Keyboard2.java
index 0297cc4..f0408e0 100644
--- a/srcs/juloo.keyboard2/Keyboard2.java
+++ b/srcs/juloo.keyboard2/Keyboard2.java
@@ -38,7 +38,6 @@ public class Keyboard2 extends InputMethodService
private KeyboardData _localeTextLayout;
private ViewGroup _emojiPane = null;
private ViewGroup _clipboard_pane = null;
- public int actionId; // Action performed by the Action key.
private Handler _handler;
private Config _config;
@@ -202,44 +201,6 @@ public class Keyboard2 extends InputMethodService
_localeTextLayout = default_layout;
}
- private String actionLabel_of_imeAction(int action)
- {
- int res;
- switch (action)
- {
- case EditorInfo.IME_ACTION_NEXT: res = R.string.key_action_next; break;
- case EditorInfo.IME_ACTION_DONE: res = R.string.key_action_done; break;
- case EditorInfo.IME_ACTION_GO: res = R.string.key_action_go; break;
- case EditorInfo.IME_ACTION_PREVIOUS: res = R.string.key_action_prev; break;
- case EditorInfo.IME_ACTION_SEARCH: res = R.string.key_action_search; break;
- case EditorInfo.IME_ACTION_SEND: res = R.string.key_action_send; break;
- case EditorInfo.IME_ACTION_UNSPECIFIED:
- case EditorInfo.IME_ACTION_NONE:
- default: return null;
- }
- return getResources().getString(res);
- }
-
- private void refresh_action_label(EditorInfo info)
- {
- // First try to look at 'info.actionLabel', if it isn't set, look at
- // 'imeOptions'.
- if (info.actionLabel != null)
- {
- _config.actionLabel = info.actionLabel.toString();
- actionId = info.actionId;
- _config.swapEnterActionKey = false;
- }
- else
- {
- int action = info.imeOptions & EditorInfo.IME_MASK_ACTION;
- _config.actionLabel = actionLabel_of_imeAction(action); // Might be null
- actionId = action;
- _config.swapEnterActionKey =
- (info.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) == 0;
- }
- }
-
/** Might re-create the keyboard view. [_keyboardView.setKeyboard()] and
[setInputView()] must be called soon after. */
private void refresh_config()
@@ -258,19 +219,15 @@ public class Keyboard2 extends InputMethodService
_keyboardView.reset();
}
- private KeyboardData refresh_special_layout(EditorInfo info)
+ private KeyboardData refresh_special_layout()
{
- switch (info.inputType & InputType.TYPE_MASK_CLASS)
+ if (_config.editor_config.numeric_layout)
{
- case InputType.TYPE_CLASS_NUMBER:
- case InputType.TYPE_CLASS_PHONE:
- case InputType.TYPE_CLASS_DATETIME:
- if (_config.selected_number_layout == NumberLayout.PIN)
- return loadPinentry(R.xml.pin);
- else if (_config.selected_number_layout == NumberLayout.NUMBER)
- return loadNumpad(R.xml.numeric);
- default:
- break;
+ switch (_config.selected_number_layout)
+ {
+ case PIN: return loadPinentry(R.xml.pin);
+ case NUMBER: return loadNumpad(R.xml.numeric);
+ }
}
return null;
}
@@ -278,11 +235,11 @@ public class Keyboard2 extends InputMethodService
@Override
public void onStartInputView(EditorInfo info, boolean restarting)
{
+ _config.editor_config.refresh(info, getResources());
refresh_config();
- refresh_action_label(info);
- _currentSpecialLayout = refresh_special_layout(info);
+ _currentSpecialLayout = refresh_special_layout();
_keyboardView.setKeyboard(current_layout());
- _keyeventhandler.started(info);
+ _keyeventhandler.started(_config);
setInputView(_keyboardView);
Logs.debug_startup_input_view(info, _config);
}
@@ -453,7 +410,7 @@ public class Keyboard2 extends InputMethodService
case ACTION:
InputConnection conn = getCurrentInputConnection();
if (conn != null)
- conn.performEditorAction(actionId);
+ conn.performEditorAction(_config.editor_config.actionId);
break;
case SWITCH_FORWARD:
diff --git a/srcs/juloo.keyboard2/Keyboard2View.java b/srcs/juloo.keyboard2/Keyboard2View.java
index 01afe91..1532970 100644
--- a/srcs/juloo.keyboard2/Keyboard2View.java
+++ b/srcs/juloo.keyboard2/Keyboard2View.java
@@ -147,8 +147,9 @@ public class Keyboard2View extends View
/** Called from [Keybard2.onUpdateSelection]. */
public void set_selection_state(boolean selection_state)
{
- set_fake_ptr_latched(KeyboardData.Key.EMPTY,
- KeyValue.getKeyByName("selection_mode"), selection_state, true);
+ if (_config.editor_config.selection_mode_enabled)
+ set_fake_ptr_latched(KeyboardData.Key.EMPTY,
+ KeyValue.getKeyByName("selection_mode"), selection_state, true);
}
public KeyValue modifyKey(KeyValue k, Pointers.Modifiers mods)
diff --git a/srcs/juloo.keyboard2/LayoutModifier.java b/srcs/juloo.keyboard2/LayoutModifier.java
index 22f15ec..fa7be0c 100644
--- a/srcs/juloo.keyboard2/LayoutModifier.java
+++ b/srcs/juloo.keyboard2/LayoutModifier.java
@@ -149,6 +149,7 @@ public final class LayoutModifier
*/
static KeyValue modify_key(KeyValue orig)
{
+ EditorConfig ec = globalConfig.editor_config;
switch (orig.getKind())
{
case Event:
@@ -159,11 +160,12 @@ public final class LayoutModifier
return KeyValue.getKeyByName("change_method_prev");
break;
case ACTION:
- if (globalConfig.actionLabel == null)
+ String action_label = ec.actionLabel;
+ if (action_label == null)
return null; // Remove the action key
- if (globalConfig.swapEnterActionKey)
+ if (ec.swapEnterActionKey)
return KeyValue.getKeyByName("enter");
- return KeyValue.makeActionKey(globalConfig.actionLabel);
+ return KeyValue.makeActionKey(action_label);
case SWITCH_FORWARD:
return (globalConfig.layouts.size() > 1) ? orig : null;
case SWITCH_BACKWARD:
@@ -177,8 +179,8 @@ public final class LayoutModifier
switch (orig.getKeyevent())
{
case KeyEvent.KEYCODE_ENTER:
- if (globalConfig.swapEnterActionKey && globalConfig.actionLabel != null)
- return KeyValue.makeActionKey(globalConfig.actionLabel);
+ if (ec.swapEnterActionKey && ec.actionLabel != null)
+ return KeyValue.makeActionKey(ec.actionLabel);
break;
}
break;
diff --git a/srcs/juloo.keyboard2/Logs.java b/srcs/juloo.keyboard2/Logs.java
index 8843052..1bef51c 100644
--- a/srcs/juloo.keyboard2/Logs.java
+++ b/srcs/juloo.keyboard2/Logs.java
@@ -23,8 +23,9 @@ public final class Logs
info.dump(_debug_logs, "");
if (info.extras != null)
_debug_logs.println("extras: "+info.extras.toString());
- _debug_logs.println("swapEnterActionKey: "+conf.swapEnterActionKey);
- _debug_logs.println("actionLabel: "+conf.actionLabel);
+ _debug_logs.println("swapEnterActionKey: "
+ +conf.editor_config.swapEnterActionKey);
+ _debug_logs.println("actionLabel: "+conf.editor_config.actionLabel);
}
public static void debug_config_migration(int from_version, int to_version)