abouttreesummaryrefslogcommitdiff
path: root/srcs
diff options
context:
space:
mode:
authorJules Aguillon2025-08-16 18:48:00 +0200
committerJules Aguillon2025-12-28 18:08:12 +0100
commitf082fcdebc4f129cd262ee4a0a6b83d91fde72bb (patch)
tree74dd1045f5e2584c56246b40bd9904a5eb865a8e /srcs
parent98c1b8db82c0da8f49eb12d18c9001a57009eca5 (diff)
downloadunexpected-keyboard-f082fcdebc4f129cd262ee4a0a6b83d91fde72bb.tar.gz
unexpected-keyboard-f082fcdebc4f129cd262ee4a0a6b83d91fde72bb.zip
Track the currently typed word
The `CurrentlyTypedWord` class tracks the word that is being typed. It's implemented on the same model as Autocapitalisation and avoid expensive IPC calls when possible. The `Suggestions` class is where the suggestion lookup should go. It currently just echoes the current word.
Diffstat (limited to 'srcs')
-rw-r--r--srcs/juloo.keyboard2/CurrentlyTypedWord.java99
-rw-r--r--srcs/juloo.keyboard2/EditorConfig.java9
-rw-r--r--srcs/juloo.keyboard2/KeyEventHandler.java25
-rw-r--r--srcs/juloo.keyboard2/Keyboard2.java7
-rw-r--r--srcs/juloo.keyboard2/Suggestions.java27
5 files changed, 161 insertions, 6 deletions
diff --git a/srcs/juloo.keyboard2/CurrentlyTypedWord.java b/srcs/juloo.keyboard2/CurrentlyTypedWord.java
new file mode 100644
index 0000000..eba0bb0
--- /dev/null
+++ b/srcs/juloo.keyboard2/CurrentlyTypedWord.java
@@ -0,0 +1,99 @@
+package juloo.keyboard2;
+
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import java.util.List;
+
+/** Keep track of the word being typed. */
+public final class CurrentlyTypedWord
+{
+ InputConnection _ic = null;
+ Callback _callback;
+
+ StringBuilder _w = new StringBuilder();
+ boolean _enabled = false;
+
+ /** The estimated cursor position. Used to avoid expensive IPC calls when the
+ typed word can be estimated locally with [typed]. When the cursor
+ position gets out of sync, the text before the cursor is queried again to
+ the editor. */
+ int _cursor;
+
+ int refresh_count = 0;
+
+ public CurrentlyTypedWord(Callback cb)
+ {
+ _callback = cb;
+ }
+
+ public void started(Config conf, InputConnection ic)
+ {
+ _ic = ic;
+ EditorConfig e = conf.editor_config;
+ refresh_current_word(e.initial_text_before_cursor,
+ e.initial_sel_start != e.initial_sel_end);
+ _cursor = e.initial_sel_start;
+ }
+
+ public void typed(String s)
+ {
+ if (!_enabled)
+ return;
+ type_chars(s);
+ callback();
+ }
+
+ public void selection_updated(int oldSelStart, int newSelStart, int newSelEnd)
+ {
+ // Avoid the expensive [refresh_current_word] call when [typed] was called
+ // before.
+ if (!_enabled || newSelStart == _cursor)
+ return;
+ refresh_current_word(_ic.getTextBeforeCursor(10, 0),
+ newSelStart != newSelEnd);
+ _cursor = newSelStart;
+ }
+
+ private void callback()
+ {
+ _callback.currently_typed_word(_w.toString() + refresh_count);
+ }
+
+ /** Estimate the currently typed word after [chars] has been typed. */
+ private void type_chars(String s)
+ {
+ int len = s.length();
+ for (int i = 0; i < len;)
+ {
+ int c = s.codePointAt(i);
+ if (Character.isLetter(c))
+ _w.appendCodePoint(c);
+ else
+ _w.setLength(0);
+ _cursor++;
+ i += Character.charCount(c);
+ }
+ }
+
+ /** Set [_enabled]. */
+ private void refresh_current_word(CharSequence text_before_cursor, boolean has_selection)
+ {
+ _w.setLength(0);
+ if (_ic == null || text_before_cursor == null)
+ {
+ _enabled = false;
+ return;
+ }
+ _enabled = true;
+ if (has_selection)
+ return;
+ refresh_count++;
+ type_chars(text_before_cursor.toString());
+ callback();
+ }
+
+ public static interface Callback
+ {
+ public void currently_typed_word(String word);
+ }
+}
diff --git a/srcs/juloo.keyboard2/EditorConfig.java b/srcs/juloo.keyboard2/EditorConfig.java
index d9f1ae9..bdfab3c 100644
--- a/srcs/juloo.keyboard2/EditorConfig.java
+++ b/srcs/juloo.keyboard2/EditorConfig.java
@@ -26,6 +26,11 @@ public final class EditorConfig
// Whether caps state should be updated right away.
public boolean caps_initially_updated = false;
+ /** CurrentlyTypedWord. */
+ public CharSequence initial_text_before_cursor = null;
+ public int initial_sel_start;
+ public int initial_sel_end;
+
public EditorConfig() {}
public void refresh(EditorInfo info, Resources res)
@@ -66,6 +71,10 @@ public final class EditorConfig
caps_mode = info.inputType & TextUtils.CAP_MODE_SENTENCES;
caps_initially_enabled = (info.initialCapsMode != 0);
caps_initially_updated = caps_should_update_state(info);
+ /* CurrentlyTypedWord */
+ initial_text_before_cursor = info.getInitialTextBeforeCursor(10, 0);
+ initial_sel_start = info.initialSelStart;
+ initial_sel_end = info.initialSelEnd;
}
String actionLabel_of_imeAction(int action, Resources res)
diff --git a/srcs/juloo.keyboard2/KeyEventHandler.java b/srcs/juloo.keyboard2/KeyEventHandler.java
index 145acbe..336398c 100644
--- a/srcs/juloo.keyboard2/KeyEventHandler.java
+++ b/srcs/juloo.keyboard2/KeyEventHandler.java
@@ -12,10 +12,13 @@ import java.util.Iterator;
public final class KeyEventHandler
implements Config.IKeyEventHandler,
- ClipboardHistoryService.ClipboardPasteCallback
+ ClipboardHistoryService.ClipboardPasteCallback,
+ CurrentlyTypedWord.Callback
{
IReceiver _recv;
Autocapitalisation _autocap;
+ Suggestions _suggestions;
+ CurrentlyTypedWord _typedword;
/** State of the system modifiers. It is updated whether a modifier is down
or up and a corresponding key event is sent. */
Pointers.Modifiers _mods;
@@ -33,20 +36,25 @@ public final class KeyEventHandler
_autocap = new Autocapitalisation(recv.getHandler(),
this.new Autocapitalisation_callback());
_mods = Pointers.Modifiers.EMPTY;
+ _suggestions = new Suggestions(recv);
+ _typedword = new CurrentlyTypedWord(this);
}
/** Editing just started. */
public void started(Config conf)
{
- _autocap.started(conf, _recv.getCurrentInputConnection());
+ InputConnection ic = _recv.getCurrentInputConnection();
+ _autocap.started(conf, ic);
+ _typedword.started(conf, ic);
_move_cursor_force_fallback =
conf.editor_config.should_move_cursor_force_fallback;
}
/** Selection has been updated. */
- public void selection_updated(int oldSelStart, int newSelStart)
+ public void selection_updated(int oldSelStart, int newSelStart, int newSelEnd)
{
_autocap.selection_updated(oldSelStart, newSelStart);
+ _typedword.selection_updated(oldSelStart, newSelStart, newSelEnd);
}
/** A key is being pressed. There will not necessarily be a corresponding
@@ -122,6 +130,12 @@ public final class KeyEventHandler
send_text(content);
}
+ @Override
+ public void currently_typed_word(String word)
+ {
+ _suggestions.currently_typed_word(word);
+ }
+
/** Update [_mods] to be consistent with the [mods], sending key events if
needed. */
void update_meta_state(Pointers.Modifiers mods)
@@ -211,13 +225,14 @@ public final class KeyEventHandler
_autocap.event_sent(eventCode, metaState);
}
- void send_text(CharSequence text)
+ void send_text(String text)
{
InputConnection conn = _recv.getCurrentInputConnection();
if (conn == null)
return;
conn.commitText(text, 1);
_autocap.typed(text);
+ _typedword.typed(text);
}
/** See {!InputConnection.performContextMenuAction}. */
@@ -473,7 +488,7 @@ public final class KeyEventHandler
return (conn.getSelectedText(0) != null);
}
- public static interface IReceiver
+ public static interface IReceiver extends Suggestions.Callback
{
public void handle_event_key(KeyValue.Event ev);
public void set_shift_state(boolean state, boolean lock);
diff --git a/srcs/juloo.keyboard2/Keyboard2.java b/srcs/juloo.keyboard2/Keyboard2.java
index c7d7e3d..a2940d5 100644
--- a/srcs/juloo.keyboard2/Keyboard2.java
+++ b/srcs/juloo.keyboard2/Keyboard2.java
@@ -346,7 +346,7 @@ public class Keyboard2 extends InputMethodService
public void onUpdateSelection(int oldSelStart, int oldSelEnd, int newSelStart, int newSelEnd, int candidatesStart, int candidatesEnd)
{
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd);
- _keyeventhandler.selection_updated(oldSelStart, newSelStart);
+ _keyeventhandler.selection_updated(oldSelStart, newSelStart, newSelEnd);
if ((oldSelStart == oldSelEnd) != (newSelStart == newSelEnd))
_keyboardView.set_selection_state(newSelStart != newSelEnd);
}
@@ -481,6 +481,11 @@ public class Keyboard2 extends InputMethodService
{
return _handler;
}
+
+ public void set_suggestions(List<String> suggestions)
+ {
+ _candidates_view.set_candidates(suggestions);
+ }
}
private IBinder getConnectionToken()
diff --git a/srcs/juloo.keyboard2/Suggestions.java b/srcs/juloo.keyboard2/Suggestions.java
new file mode 100644
index 0000000..2009d9a
--- /dev/null
+++ b/srcs/juloo.keyboard2/Suggestions.java
@@ -0,0 +1,27 @@
+package juloo.keyboard2;
+
+import java.util.List;
+import java.util.Arrays;
+
+/** Keep track of the word being typed and provide suggestions for
+ [CandidatesView]. */
+public final class Suggestions
+{
+ Callback _callback;
+
+ public Suggestions(Callback c)
+ {
+ _callback = c;
+ }
+
+ public void currently_typed_word(String word)
+ {
+ // TODO
+ _callback.set_suggestions(Arrays.asList(word));
+ }
+
+ public static interface Callback
+ {
+ public void set_suggestions(List<String> suggestions);
+ }
+}