Commit Graph

39 Commits

Author SHA1 Message Date
Jules Aguillon
23097921cf Disable automatic Shift when pressing Compose 2024-11-17 11:10:21 +01:00
Jules Aguillon
9f22e53a3b
Add complex keys (#774)
This allows to add new kinds of keys that need more data without making
KeyValue's footprint bigger for common keys.

This changes the [_symbol] field into [_payload], which holds the same
as the previous field for more common keys but can hold bigger objects
for keys of the new "Complex" kind.

This also adds a complex key: String keys with a symbol different than
the outputted string.

Unit tests are added as the Java language is not helpful in making
robust code.
2024-09-29 21:58:22 +02:00
Jules Aguillon
bf3b9c374e
Clipboard pane (#681)
This adds the clipboard pane, which allows to save an arbitrary number of
clipboards and to paste them later. The key can be disabled in settings.

Checking the "Recently copied text" checkbox will cause the keyboard to keep a
temporary history of copied text. This history can only contain 3 elements
which expire after 5 minutes.
If this is unchecked, no history is collected.

History entries can be pinned into the persisted list of pins.
2024-07-06 22:16:37 +02:00
Jules Aguillon
0f11a88418
More precise and faster spacebar slider (#593)
* Make slider speed independent from swipe distance

Swipe distances other than the default resulted in a slider that were
not easy to control.

* refactor: Add class Pointers.Sliding

It holds the states and the code needed to make the slider work.
'Pointer.sliding' is set to [null] when sliding is not in progress.

The implementation is changed not to depend on [downX] and [dx] but
instead use the pointer's [x] coordinate directly.

* Move the cursor further for faster slides

In sliding mode, compute the speed of the pointer and use it to increase
at which the cursor moves.

* refactor: Separate kind for cursor movement keys

This allows to define a key that moves the cursor more than one position
at a time.

This will be used to avoid lag during fast slider movements.

* Reduce lag when sliding quickly on the spacebar

Avoid sending key events in a loop while sliding quickly in a cursor
movement key. Key of kind Cursor_move are "multiplied", meaning a single
key event represents a movement of more than one position, reducing the
number of key events sent.
This is only for cursor move keys.
2024-05-02 19:31:48 +02:00
Jules Aguillon
e604f6fd57 refactor: Implement Compose without global state
Thanks to the previous commit, a modifier key can now be more complex
than just a KeyValue.Modifier. This allows a more elegant implementation
of the compose key, that could be taken as a base for other features
(eg. unicode hex entry, hangul)

The COMPOSE_PENDING modifier is removed as keys of kind Compose_pending
can act as a modifier. This has the advantage of highlighting the key
that was last pressed in the sequence.

Rules are added to Pointers: Non-special but latchable keys must clear
latches and cannot be locked with a long press. These rules were not
needed before but were intended.
2024-03-18 01:00:22 +01:00
Jules Aguillon
dc3a303af1 refactor: Allow modifier of other key kinds
Allow keys of a kind other than Modifier to be a modifier.

This requires writing a compareTo function for KeyValue. Fields are
compared in this order: Kind, value, flags, symbol.
2024-03-18 00:40:15 +01:00
Jules Aguillon
ec8e78d5cc refactor: Use Pointers.Modifiers.has less
The performance characteristics of this function will change in future
plans.
2024-03-18 00:09:32 +01:00
Jules Aguillon
8c29073260 Compose key
The COMPOSE_PENDING modifier indicate whether a compose sequence is in
progress. The new key of kind Compose_pending sets the current state of
the sequence.

The compose sequences are compiled into a state machine by a python
script into a compact encoding.

The state of the pending compose is determined by the index of a state.
2024-02-17 23:28:31 +01:00
Jules Aguillon
f4d88cc087 Fix various linter warnings
Among others:
- Use `apply` instead of `commit` when saving shared preferences.
- Avoid inlined Api
- Remove unused resources
2024-02-10 18:10:49 +01:00
Jules Aguillon
2c52e94e0b Workaround cursor slider bug in Acode
Moving the cursor with setSelection has no effect on Acode, for which
the fallback must be used.
2024-02-04 00:29:07 +01:00
Jules Aguillon
c5f2c0b727 Send down event for modifiers on time
This allows to use modifiers in combination with other inputs like a
mouse click, for example under termux-x11.

The key down event and notification about modifiers changing are sent
down to KeyEventHandler. A mutable state remember for which modifier
down events have been sent.

When pressing down a modifier with one finger and typing with the
other, it might appear that the modifier is released after the first
time an other key is pressed and then pressed and released for the
following keys.
This prevents unintentionally type two modified keys instead of one
when the second key is pressed while the other is not yet released.
2024-01-26 00:17:51 +01:00
Jules Aguillon
eddf9c6c11 Refactor: New namespace for preference classes 2024-01-13 20:59:05 +01:00
Jules Aguillon
9b917e79b1 Fix regression on Ctrl on space bar slider
This makes Ctrl+move_cursor the same as before 5123ce5.
2023-08-26 23:44:41 +02:00
Jules Aguillon
f4c11d99ed Disable automatically Shift when pressing Ctrl
Automatic capitalisation might interferes with keyboard shortcuts.
2023-08-26 23:37:22 +02:00
Jules Aguillon
5123ce5417 Fix slider movements changing input focus
The slider was repeatedly sending arrow keys, which change the focused
input when the end of a text box is hit.

A new key is added that implements cursor movements using the
`InputConnection` API.
The new keys are defined as `KeyValue.Editing`, which are no longer only
context menu actions.

The behavior when a selection has started is changed. The selection is
modified instead of cleared even when shift isn't pressed or the
selection would become empty.

Fallbacks to sending arrow keys for editors that do not support the API,
like Termux.
2023-08-17 12:47:44 +02:00
Jules Aguillon
a83a19a0a8 Refactor: Handle Event keys in Keyboard2
The `KeyEventHandler` class is intended to handle every keys and to call
into the main class through a limited API.
However, this is not true for `Event` keys, which in practice had each a
corresponding API call.
2023-06-03 20:06:44 +02:00
Jules Aguillon
85cdb9b2b5 Add Voice Typing key
The new key switches to any installed "voice" input method.
If several input methods matches, no effort is made to choose.
Might misbehave with some input methods other than Google's on API < 28.

It is placed on the middle of the arrows on the bottom bar. It is
enabled by default and can be removed in the "Extra keys" option.

The key is not removed from the keyboard if no voice input method
exists.
2023-06-03 18:11:42 +02:00
Jules Aguillon
0f62b3044c Option to switch to the previous input method
A new option changes the "change_method" into the new
"change_method_prev". It switch to the previously used input method.

A long press on "change_method_prev" sends "change_method".

A new section is added in the settings and existing options are moved.
2023-02-12 23:20:11 +01:00
Jules Aguillon
78a461f740 Modification step for the special layout
Refactor, follow up of 90b7944. Add a modification step to the "special"
layouts: numpad, greekmath, pin entry.

Remove the apply_key0 function, which is not expressive enough.
Add an enum instead of yet an other "switch_" function.
2023-01-30 23:46:02 +01:00
Jules Aguillon
6126578111 Avoid switching back from secondary layout automatically
Stay on the secondary layout after a config refresh or onStartInputView.
The information is kept until the keyboard is restarted.

Additionally, move tweaking the secondary layout to the Config class now
that physical equality is not needed.
2023-01-15 23:19:09 +01:00
Jules Aguillon
e333eb06fd Add keys for every context menu actions
The most requested keys are undo and redo. Unfortunatly redo doesn't
work reliably.

The other context menu actions like share, assist and autofill are added
even thought they are rarely useful or implemented.
2022-12-30 15:29:18 +01:00
Jules Aguillon
764cd882d2 Fix inaccessible text layout from pin
The "main" layout can now be pin layout. 'SWITCH_TEXT' and
'SWITCH_SECOND_BACK' don't mean to use that.
2022-12-29 12:43:02 +01:00
Jules Aguillon
2aa98de7aa Add editing keys: copy, paste, cut, select all 2022-11-13 16:45:57 +01:00
Jules Aguillon
078dbcd5ff Refactor: Move editing code from to KeyEventHandler
Remove the code dealing with InputMethodConnection from 'Keyboard2' and
move it into 'KeyEventHandler', where more editing actions can now be
implemented.

Autocapitalisation is also moved, the IReceiver interface is simplified.
2022-11-13 16:28:39 +01:00
Jules Aguillon
51b330c616 Allow switching quickly between two layouts
A new option allow to choose a secondary layout, the switching key is
placed on the top edge of the space bar.

The "Programming layout" option was basically doing that but it was
possible to choose from a few layouts only. It is improved and renamed.

The 'LayoutListPreference' allows setting the string for the first entry
but otherwise share the rest of the array.

Add nice icons from materialdesignicons.
2022-11-13 00:24:23 +01:00
Jules Aguillon
36e10a792f Add the capslock key
The key enable caps lock immediately. It does nothing if caps lock is
already enabled.

It is not present on the keyboard by default but a place is defined on
every layout, top-right of the shift key. It can be enabled in the
settings.

The icon is from materialdesignicons.com.
2022-10-23 21:37:04 +02:00
Jules Aguillon
d5836ebb97 Add key for switching to the greekmath pane
The key is placed on the 3rd row of the numeric pane, by taking some
space from the shift key.
2022-07-09 17:30:26 +02:00
Jules Aguillon
5cc7fdf6d7 Refactor: Separate Events and Keyevents and use enums
Negative values for internal events are preventing further refactoring.

Add a new kind of key and split internal events (now Event) and
Android's key events (now Keyevent).

Use enums events and modifiers outside of the KeyValue class.
Internally, they are converted to and from integer.
2022-06-05 19:30:53 +02:00
Jules Aguillon
cc571ea1ca Refactor: Merge KeyValue.char and code fields
These two fields couldn't have an interesting value at the same time.

As we can no longer rely on a special value to distinguish between
what's the kind, the kind of the key is explicitly encoded in the two
most significative bits of the _flags field.

Extra nice thing: This removes the special values 'EVENT_NONE' and 'CHAR_NONE'.
2022-06-05 18:14:50 +02:00
Jules Aguillon
c1a816d3d4 Refactor: Associate key events in KeyModifier
Two advantages:
- No need to distinguish modifiers in KeyEventHandler. The KeyValue is
  enough to decide what action to do.
- Keys are never a Char and Event at the same time, fields can be
  merged.
2022-06-05 17:46:28 +02:00
Jules Aguillon
e10c587dc5 Refactor: Abstract KeyValue fields
The meaning of the public fields of KeyValue was quite complicated and
not handled consistently accross the app.

Make these fields private and add a more abstract API on top.

The meaning of these fields changed recently and it wasn't an easy
change. I plan on making more changes in the future.
2022-06-05 17:46:22 +02:00
Jules Aguillon
4127aa6f03 Stop using flags for modifiers
There was no free bits left to add new modifiers. Instead of increasing
the width of the 'flags' field, refactor the way modifiers are
represented and used.

Modifers are now represented as independent values and stored in the
'code' field. A flag is added to distinguish between modifiers and keys
with a key event.

The most notable change is that modifiers can no longer be or-ed into a
single value but have to be represented as an array.
2022-06-05 01:43:58 +02:00
Jules Aguillon
aa78229b2a Add the Programming Layout option
Allow specifying a layout for programming and add a key for switching to
it easily.

The switching key is placed on the top edge of the space bar.

The option has no effect by default because the ergonomic isn't ideal,
it needs to be enabled explicitly.
Users of Latin-script languages certainly prefer to use one layout (for
programming or not). This feature might be removed in favor of a better
language-switching mechanisms in the future.
2022-04-03 17:15:12 +02:00
Jules Aguillon
e872c58788 Allow modifiers to hide keys
Modifiers can temporarily remove a key from the layout by returning
'null'.
Make sure pointer handling code handle these modified keys gracefully
and doesn't trigger a key event and a vibration for the removed key.
2022-03-19 15:39:20 +01:00
Jules Aguillon
a57bdf8cfb Avoid showing some symbols twice in Fn mode 2022-03-13 00:35:15 +01:00
Jules Aguillon
14dabb6f51 Send key events for the modifiers
Before sending a key event while modifiers are active, send events for
the modifier keys.

Some applications don't look at the "metaState" flags but instead keep
track of the up and down events for the modifiers.

For example, the basic text views that are in every applications
correctly handle the "metaState" flags except for one binding:
Selecting text with the arrows while pressing shift.
2022-02-22 19:32:16 +01:00
Jules Aguillon
95c8acc31e Add the Meta key
Currently using the diamond symbol like the history meta key: https://en.wikipedia.org/wiki/Meta_key
However, this key is actually interpreted as the Super/Windows key but
Android calls it "meta" internally.
2022-02-06 23:01:35 +01:00
Jules Aguillon
53113cadd9 Add the Action key
It is placed on the top-right of the enter key on every layouts.
It sends a special event (performEditorAction) instead of writing a
newline.

The "actionId" is passed through the EditorInfo object in an obfuscated
way so it's not clear whether it's using the right one.
2022-01-09 20:26:06 +01:00
Jules Aguillon
15ce200ce3 Separate "handler" code
As with the previous commit, remove casts of the context.
The "handler" object is referenced in the "config" object for now.
2021-12-28 17:47:18 +01:00