diff options
| author | Jules Aguillon | 2025-03-10 23:41:51 +0100 |
|---|---|---|
| committer | GitHub | 2025-03-10 23:41:51 +0100 |
| commit | 9cfeb0f0c22dd649fcf32260925a5a84a731d1b3 (patch) | |
| tree | 447ceb35fe87b086ec7f75c0bee7addc4619a16c /srcs/juloo.keyboard2 | |
| parent | 5e77fa84cff5a55cc26f3e02e2823ad0ec845c51 (diff) | |
| download | unexpected-keyboard-9cfeb0f0c22dd649fcf32260925a5a84a731d1b3.tar.gz unexpected-keyboard-9cfeb0f0c22dd649fcf32260925a5a84a731d1b3.zip | |
Add a delay after a Keyevent key in a macro (#918)
* Construct a single handler
* Add a delay after a Keyevent key in a macro
Add a delay before sending the next key to avoid race conditions causing
keys to be handled in the wrong order. Notably, KeyEvent keys handling
is scheduled differently than the other edit functions.
Diffstat (limited to 'srcs/juloo.keyboard2')
| -rw-r--r-- | srcs/juloo.keyboard2/Autocapitalisation.java | 5 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/KeyEventHandler.java | 69 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/Keyboard2.java | 10 |
3 files changed, 67 insertions, 17 deletions
diff --git a/srcs/juloo.keyboard2/Autocapitalisation.java b/srcs/juloo.keyboard2/Autocapitalisation.java index a77d2e5..21fcaf6 100644 --- a/srcs/juloo.keyboard2/Autocapitalisation.java +++ b/srcs/juloo.keyboard2/Autocapitalisation.java @@ -1,7 +1,6 @@ package juloo.keyboard2; import android.os.Handler; -import android.os.Looper; import android.text.InputType; import android.text.TextUtils; import android.view.inputmethod.EditorInfo; @@ -27,9 +26,9 @@ public final class Autocapitalisation InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_CAP_WORDS; - public Autocapitalisation(Looper looper, Callback cb) + public Autocapitalisation(Handler h, Callback cb) { - _handler = new Handler(looper); + _handler = h; _callback = cb; } diff --git a/srcs/juloo.keyboard2/KeyEventHandler.java b/srcs/juloo.keyboard2/KeyEventHandler.java index a841c30..30282c7 100644 --- a/srcs/juloo.keyboard2/KeyEventHandler.java +++ b/srcs/juloo.keyboard2/KeyEventHandler.java @@ -2,6 +2,7 @@ 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; @@ -28,10 +29,10 @@ public final class KeyEventHandler [setSelection] could be used instead. */ boolean _move_cursor_force_fallback = false; - public KeyEventHandler(Looper looper, IReceiver recv) + public KeyEventHandler(IReceiver recv) { _recv = recv; - _autocap = new Autocapitalisation(looper, + _autocap = new Autocapitalisation(recv.getHandler(), this.new Autocapitalisation_callback()); _mods = Pointers.Modifiers.EMPTY; } @@ -324,31 +325,72 @@ public final class KeyEventHandler void evaluate_macro(KeyValue[] keys) { - final Pointers.Modifiers empty = Pointers.Modifiers.EMPTY; + if (keys.length == 0) + return; // Ignore modifiers that are activated at the time the macro is evaluated - mods_changed(empty); - Pointers.Modifiers mods = empty; - final boolean autocap_paused = _autocap.pause(); - for (KeyValue kv : keys) + mods_changed(Pointers.Modifiers.EMPTY); + evaluate_macro_loop(keys, 0, Pointers.Modifiers.EMPTY, _autocap.pause()); + } + + /** Evaluate the macro asynchronously to make sure event are processed in the + right order. */ + void evaluate_macro_loop(final KeyValue[] keys, int i, Pointers.Modifiers mods, final boolean autocap_paused) + { + boolean should_delay = false; + KeyValue kv = KeyModifier.modify(keys[i], mods); + if (kv != null) { - kv = KeyModifier.modify(kv, mods); - if (kv == null) - continue; if (kv.hasFlagsAny(KeyValue.FLAG_LATCH)) { // Non-special latchable keys clear latched modifiers if (!kv.hasFlagsAny(KeyValue.FLAG_SPECIAL)) - mods = empty; + mods = Pointers.Modifiers.EMPTY; mods = mods.with_extra_mod(kv); } else { key_down(kv, false); key_up(kv, mods); - mods = empty; + mods = Pointers.Modifiers.EMPTY; } + should_delay = wait_after_macro_key(kv); + } + i++; + if (i >= keys.length) // Stop looping + { + _autocap.unpause(autocap_paused); + } + else if (should_delay) + { + // Add a delay before sending the next key to avoid race conditions + // causing keys to be handled in the wrong order. Notably, KeyEvent keys + // handling is scheduled differently than the other edit functions. + final int i_ = i; + final Pointers.Modifiers mods_ = mods; + _recv.getHandler().postDelayed(new Runnable() { + public void run() + { + evaluate_macro_loop(keys, i_, mods_, autocap_paused); + } + }, 1000/30); + } + else + evaluate_macro_loop(keys, i, mods, autocap_paused); + } + + boolean wait_after_macro_key(KeyValue kv) + { + switch (kv.getKind()) + { + case Keyevent: + case Editing: + case Event: + return true; + case Slider: + return _move_cursor_force_fallback; + default: + return false; } - _autocap.unpause(autocap_paused); } /** Repeat calls to [send_key_down_up]. */ @@ -364,6 +406,7 @@ public final class KeyEventHandler public void set_shift_state(boolean state, boolean lock); public void set_compose_pending(boolean pending); public InputConnection getCurrentInputConnection(); + public Handler getHandler(); } class Autocapitalisation_callback implements Autocapitalisation.Callback diff --git a/srcs/juloo.keyboard2/Keyboard2.java b/srcs/juloo.keyboard2/Keyboard2.java index 6d3516d..02c062a 100644 --- a/srcs/juloo.keyboard2/Keyboard2.java +++ b/srcs/juloo.keyboard2/Keyboard2.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.inputmethodservice.InputMethodService; import android.os.Build.VERSION; +import android.os.Handler; import android.os.IBinder; import android.text.InputType; import android.util.Log; @@ -38,6 +39,7 @@ public class Keyboard2 extends InputMethodService private ViewGroup _emojiPane = null; private ViewGroup _clipboard_pane = null; public int actionId; // Action performed by the Action key. + private Handler _handler; private Config _config; @@ -107,7 +109,8 @@ public class Keyboard2 extends InputMethodService { super.onCreate(); SharedPreferences prefs = DirectBootAwarePreferences.get_shared_preferences(this); - _keyeventhandler = new KeyEventHandler(getMainLooper(), this.new Receiver()); + _handler = new Handler(getMainLooper()); + _keyeventhandler = new KeyEventHandler(this.new Receiver()); Config.initGlobalConfig(prefs, getResources(), _keyeventhandler); prefs.registerOnSharedPreferenceChangeListener(this); _config = Config.globalConfig(); @@ -481,6 +484,11 @@ public class Keyboard2 extends InputMethodService { return Keyboard2.this.getCurrentInputConnection(); } + + public Handler getHandler() + { + return _handler; + } } private IBinder getConnectionToken() |
