Standard auto-capitalisation only after space

Change the capitalisation algorithm to use Android's
'getCursorCapsMode'. This requires a bit of cursor calculations but
should feel more standard.

The auto completion only triggers after a space is typed or backspace is
pressed.
This commit is contained in:
Jules Aguillon 2022-07-30 17:42:58 +02:00
parent dec0a7471b
commit 85d798299e
2 changed files with 32 additions and 87 deletions

View File

@ -9,32 +9,36 @@ import android.view.KeyEvent;
final class Autocapitalisation final class Autocapitalisation
{ {
private boolean _enabled = false; private boolean _enabled = false;
private boolean _beginning_of_sentence = false; private boolean _should_enable_shift = false;
/** Used to avoid enabling shift after an arrow key is pressed. */
private boolean _skip_next_selection_update = false; private InputConnection _ic;
/** Keep track of the cursor to differentiate 'selection_updated' events private int _caps_mode;
corresponding to typing from cursor movement. */
private int _cursor = 0; /** Keep track of the cursor to recognize cursor movements from typing. */
private int _cursor;
static private int SUPPORTED_CAPS_MODES =
InputType.TYPE_TEXT_FLAG_CAP_SENTENCES |
InputType.TYPE_TEXT_FLAG_CAP_WORDS;
public boolean should_enable_shift() public boolean should_enable_shift()
{ {
return _enabled && _beginning_of_sentence; return _should_enable_shift;
} }
/** Returns [true] if shift should be on initially. The input connection /** Returns [true] if shift should be on initially. The input connection
isn't stored. */ isn't stored. */
public void started(EditorInfo info, InputConnection ic) public void started(EditorInfo info, InputConnection ic)
{ {
if (!Config.globalConfig().autocapitalisation _ic = ic;
|| (info.inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) == 0) _caps_mode = info.inputType & TextUtils.CAP_MODE_SENTENCES;
if (!Config.globalConfig().autocapitalisation || _caps_mode == 0)
{ {
_enabled = false; _enabled = false;
return; return;
} }
_enabled = true; _enabled = true;
_beginning_of_sentence = ((info.initialCapsMode & TextUtils.CAP_MODE_SENTENCES) != 0); _should_enable_shift = (info.initialCapsMode != 0);
_cursor = 0; // Just a guess
scan_text_before_cursor(10, ic);
} }
public void typed(CharSequence c) public void typed(CharSequence c)
@ -46,101 +50,43 @@ final class Autocapitalisation
public void typed(char c) public void typed(char c)
{ {
_cursor++; _cursor++;
if (is_beginning_of_sentence(c)) if (is_trigger_character(c))
_beginning_of_sentence = true; update_caps_mode();
else if (!ignore_at_beginning_of_sentence(c)) else
_beginning_of_sentence = false; _should_enable_shift = false;
} }
public void event_sent(int code) public void event_sent(int code)
{ {
switch (code) switch (code)
{ {
// Disable temporarily after a keyboard cursor movement case KeyEvent.KEYCODE_DEL:
case KeyEvent.KEYCODE_DPAD_UP: _cursor--;
case KeyEvent.KEYCODE_DPAD_RIGHT: update_caps_mode();
case KeyEvent.KEYCODE_DPAD_DOWN:
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_PAGE_UP:
case KeyEvent.KEYCODE_PAGE_DOWN:
case KeyEvent.KEYCODE_MOVE_HOME:
case KeyEvent.KEYCODE_MOVE_END:
_skip_next_selection_update = true;
_beginning_of_sentence = false;
break; break;
} }
} }
/** Returns [true] if shift might be disabled. */ /** Returns [true] if shift might be disabled. */
public boolean selection_updated(int old_cursor, int new_cursor, InputConnection ic) public boolean selection_updated(int old_cursor, int new_cursor)
{ {
if (_skip_next_selection_update) if (new_cursor == _cursor) // Just typing
{
_cursor = new_cursor;
_skip_next_selection_update = false;
return false; return false;
} _cursor = new_cursor;
if (new_cursor == _cursor) _should_enable_shift = false;
return false; return true;
// Text has been inserted or cursor moved forward
if (old_cursor == _cursor && new_cursor > old_cursor)
{
scan_text_before_cursor(Math.min(new_cursor - old_cursor, 10), ic);
return true;
}
else
{
// Cursor has moved backward or text deleted
_beginning_of_sentence = false;
scan_text_before_cursor(10, ic);
_cursor = new_cursor;
return true;
}
} }
/** Updates [_cursor]. */ private void update_caps_mode()
private void scan_text_before_cursor(int range, InputConnection ic)
{ {
if (!_enabled) // Don't query characters if disabled _should_enable_shift = _enabled && (_ic.getCursorCapsMode(_caps_mode) != 0);
return;
CharSequence text_before = ic.getTextBeforeCursor(range, 0);
if (text_before == null)
{
_beginning_of_sentence = false;
}
else
{
_beginning_of_sentence = true;
typed(text_before);
}
} }
private boolean ignore_at_beginning_of_sentence(char c) private boolean is_trigger_character(char c)
{ {
switch (c) switch (c)
{ {
case ' ': case ' ':
case '"':
case '\'':
case '(':
case '«':
return true;
default:
return false;
}
}
private boolean is_beginning_of_sentence(char c)
{
switch (c)
{
case '.':
case ';':
case '\n':
case '!':
case '?':
case '¿':
case '¡':
return true; return true;
default: default:
return false; return false;

View File

@ -251,8 +251,7 @@ public class Keyboard2 extends InputMethodService
public void onUpdateSelection(int oldSelStart, int oldSelEnd, int newSelStart, int newSelEnd, int candidatesStart, int candidatesEnd) public void onUpdateSelection(int oldSelStart, int oldSelEnd, int newSelStart, int newSelEnd, int candidatesStart, int candidatesEnd)
{ {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd); super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd);
update_shift_state( update_shift_state(_autocap.selection_updated(oldSelStart, newSelStart));
_autocap.selection_updated(oldSelStart, newSelStart, getCurrentInputConnection()));
} }
@Override @Override