100 Commits
Author SHA1 Message Date
Jules Aguillon 9c70f1113e Suggestion bar to the middle of split layouts (#1350)
When the layout is split, insert a middle column showing the
complete_first, complete_second, etc.. keys.
These keys are rendered without borders and background with a new role.

The suggestion bar is hidden for split layouts. The intention is to gain
much needed vertical space.
2026-07-05 00:59:21 +02:00
Jules Aguillon c0a4bca8e2 Fix compose-space sequences not working (#1352)
* Add tests

* Fix compose-space sequences not working

KeyModifier didn't pass editing keys to ComposeKey.

* Cleanup test code

* Show the nbsp symbol when typing compose-space-space
2026-07-04 23:04:34 +02:00
Jules Aguillon b6ba00a1f6 More informative "download failed" message (#1353)
Ask users to allow internet access, which will make sense to users of
grapheneOS and other systems that restrict internet access to apps.
2026-07-04 22:43:26 +02:00
Jules Aguillon 43550a3ad1 Fix the default layout for Hebrew (#1351)
The default layout for Hebrew was not specified correctly.
2026-07-03 03:01:53 +02:00
Jules Aguillon b73ac529e8 Small improvements to the complete keys (#1349)
* Make complete keys not repeatable

* Fix complete keys not updated when suggestions change

* Code cleanup
2026-07-03 02:50:21 +02:00
Jules Aguillon f192dfcb32 Add landscape variant for the number and pin layouts (#1341)
The number pane and the pin entry layouts are split in landscape
orientation. Instead of inserting empty space in the middle of the
layout, the numpad is duplicated. The other keys are not duplicated.
2026-07-01 01:09:36 +02:00
Jules Aguillon 4ab921f112 Add keys for entering the current suggestions (#1176)
This adds the new "Stateful" kind of keys, for which the symbol is
dynamically computed from the app's state. This is implemented with a
hook directly in KeyValue.

3 keys are added for accessing the 3 words on the candidates view.
2026-06-30 16:57:27 +02:00
Jules Aguillon 44dcf6e753 Split layout on tablets and foldables (#1339)
Split the layout on wide screens by default, not just in landscape
orientation.
2026-06-27 19:08:01 +02:00
Jules Aguillon ccd9568e3d CI: Set gradle version (#1340)
Since gradle release, the CI fails due to the android plugin.
2026-06-25 00:52:12 +02:00
Jules Aguillon 21633f22fd Split layout in landscape mode (#1334)
* Automatically split layouts in landscape

This inserts empty space in the center of layouts when in landscape
orientation. The keys are smaller and pushed to the edges of the screen.
This way, the fingers don't have to reach the center of the screen,
which is inconvenient in landscape orientation.

* Duplicate keys that are on the middle

Keys that are almost aligned on the middle of the screen are duplicated
on both sides. These keys are most probably hit with both thumbs.
This is especially useful for large keys like the space bar on the
bottom row.

* Split the bottom row

* Add an option to control layout splitting
2026-06-23 21:33:30 +02:00
Jules Aguillon 241e034a3f Change the appareance of some keys (#896)
* Different color for action keys and space bar

Keys can be made darker or dimmer individually in layouts.
This is done by setting the new 'role' attributes. Roles are "normal",
"action" and "space_bar".

The "action" role is intended to be used for keys like shift, backspace
and other keys from the bottom row.

Themes and special layouts are updated.

* Set 'role="action"' for shift and backspace keys, the number row and numpad.

* check_layout.py: Check that some keys have a role
2026-06-20 14:49:46 +02:00
Jules Aguillon 374c47af9d Fix exclusion rects overlapping with the navigation bar (#1326)
Since SDK 29, calling setSystemGestureExclusionRects is mandatory to
continue supporting the keyboard's gestures but since SDK 30, this is
done automatically.
2026-06-14 12:14:08 +02:00
Jules Aguillon 49627b63e3 Add option to control behavior with physical keyboard (#1324)
The option can be set to "Show everything" to show the keyboard even
when a physical keyboard is present.
This is a list preference to allow adding a "Show suggestions" option
later.
2026-06-13 15:34:42 +02:00
Jules Aguillon 2a14ec777c Release 2.0.4 (55) 2026-05-25 00:43:37 +02:00
Jules Aguillonandsolokot 6b6491c47a Integrate changes made in Weblate (#1307)
Co-authored-by: solokot <solokot@gmail.com>
2026-05-25 00:39:23 +02:00
Jules Aguillon dbe09902d4 Add missing dictionary for English (#1304)
* gen_method_xml.py: Add missing dictionary for English

* gen_method_xml.py: Propagate dictionary specified in default locales

For example, propagate the dictionary specified for 'en' to 'en-IN',
'en-NG', etc..

* Use the dictionary en_US for locale en_CA
2026-05-25 00:05:05 +02:00
+3 ff769489c3 Integrate changes made in Weblate (#1302)
Co-authored-by: Chasm Solacer <chasmsolacer@users.noreply.hosted.weblate.org>
Co-authored-by: E. Ta. <eta00823@gmail.com>
Co-authored-by: Edgars Andersons <Edgars+Weblate@gaitenis.id.lv>
Co-authored-by: Guzleon <guzleon@yahoo.es>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Janosch <janosch.walde@posteo.de>
Co-authored-by: Joppla <joppla@gmx.com>
Co-authored-by: Mehrdad Shaeri <mehrdad.shaeri@gmail.com>
Co-authored-by: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>
Co-authored-by: Summer-Box1228 <tingrong1228@gmail.com>
Co-authored-by: solokot <solokot@gmail.com>
Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <coool@mail.lv>
2026-05-23 20:41:16 +02:00
Jules Aguillon bfdb1a9604 Remove comments in translations files (#1301)
This helps reduce conflicts when merging changes made in Weblate.
2026-05-23 20:33:09 +02:00
Jules Aguillon 0eb0e6b76f Show the current locale when no dictionary is installed (#1300)
* Refactor: Move DeviceLocales instance to Config

Allows accesses from CandidatesView.

* Show the current locale when no dictionary is installed

This helps understand why installing a dictionary doesn't remove the
message asking to install a dictionary.

The "Install" button is removed and the message is more informative.

* Update translation files
2026-05-23 20:20:26 +02:00
Jules Aguillon 76ee5b2134 Add a background color under suggestions (#1299)
* Fix unwanted mutation of background drawable

* Add a background color under suggestions

Suggestions might be unreadable when the keyboard opacity is very low
(eg. black on black).

The new background is normally invisible, unless the opacity option is
not set to 100%. The corner are rounded like the keys on the keyboard.

* Add themes attributes for suggestion background

Future themes can use them.
2026-05-23 19:59:01 +02:00
Jules Aguillon b81f4acac9 Suggestions: Add digits and ' to word characters (#1298)
This adds support for English words (like "don't") and for correcting
typos containing digits (eg. "s9mething" → "something").
2026-05-23 15:30:48 +02:00
Jules Aguillon 7e19b1f68e Hide keyboard when physical keyboard is connected (#1295)
This is broken since 958900ca
2026-05-20 21:49:12 +02:00
Jules Aguillon e64da8eefe suggestions: Reduce text size and add padding (#1296) 2026-05-20 01:03:36 +02:00
Jules Aguillon aa11bb25fd Avoid Github redirection when downloading dictionaries (#1291)
This removes a domain from connection logs and avoids an unecessary
redirection.
2026-05-17 13:01:39 +02:00
Jules Aguillon 779d438fa0 README: Mention keepandroidopen.org (#1292) 2026-05-14 13:49:27 +02:00
Jules Aguillon b807f217a0 Release 2.0.3 (54) 2026-05-06 23:29:15 +02:00
Jules Aguillon 9d0a849d34 Make building libcdict reproducible (#1282)
This is needed to release on F-Droid.
2026-05-06 23:25:37 +02:00
Jules Aguillon 267894b5ff Release 2.0.2 (53) 2026-05-06 01:29:04 +02:00
Jules Aguillon 56edba7b18 Remove mention of network access from store description (#1280)
This part of the store description is no longer true, as the application
makes a network request when downloading a dictionary.
2026-05-06 01:16:47 +02:00
7587c68d7f Merge weblate translations before 2.0.2 (#1277)
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Juan M Sevilla <jumase@disroot.org>
Co-authored-by: Jules <jules@j3s.fr>
Co-authored-by: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>
Co-authored-by: Summer-Box1228 <tingrong1228@gmail.com>
2026-05-05 12:43:05 +02:00
Jules Aguillon e57cdc45f2 Revert to the 1.32.1 Russian layout (#1276)
Partly revert be0aa07.
2026-05-05 12:37:39 +02:00
Jules Aguillon 063756eb50 Release 2.0.1 (52) 2026-05-03 19:30:18 +02:00
Jules Aguillon 9189921719 Add languages for which a dictionary is available (#1267)
* gen_method_xml.py: Warn for unused dictionaries

Helps catch missing locales.

* Add languages for which a dictionary is available

Make dictionaries are available to more languages. Extra keys are added
for as many languages as possible but no layout is added.

Some languages are still not added, mainly because they use a script
that the keyboard doesn't support yet:

    pa, gu, or, te, mai, sat, km, iw, zgh, sd, ml, sa
2026-05-03 19:19:51 +02:00
Jules Aguillon 2e1859fb1a Fix the keyboard drawing behind the navigation bar (#1265)
The width of the navigation was not accounted correctly.

This reverts be8a99bd
2026-05-03 18:10:43 +02:00
Jules Aguillon 139d1c5691 Fix crash when the cursor moves past an emoji (#1264)
The cursor might move in the middle of a surrogate pair.
2026-05-03 17:09:43 +02:00
Jules Aguillon 20a4916ff6 Fix wrong locale selection for English (#1263)
The "en" locale, which was meant to be the default for English locales
that are not in the list, was used instead of exact locales like "en_US".

The "en" locale was also used as the default locale for languages that
are not in the list at all. The "en_GB" locale is used for this instead.
2026-05-03 16:50:41 +02:00
Jules Aguillon 54c25b79e4 Update dictionaries.xml (#1262)
The dictionary sizes were not correct.
2026-05-03 13:50:51 +02:00
Jules Aguillon 82d61d4406 Fix crash when installing dictionaries (#1261)
This happens in release mode due to minification.
2026-05-03 12:55:27 +02:00
Jules Aguillon e2fdced765 releases: Update languages supported by Google Play (#1257)
Remove languages from fastlane metadata that are not supported by Google
Play and prevented the release from continuing.
2026-05-02 21:34:19 +02:00
Jules Aguillon 78a7ffc473 Release 2.0.0 (51) 2026-05-02 21:11:07 +02:00
+34 467d7e83a5 Merge changes from Weblate (#1256)
Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: solokot <solokot@gmail.com>
Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <coool@mail.lv>
Co-authored-by: Packss <enzoana@hotmail.com>
Co-authored-by: A <meow98317@gmail.com>
Co-authored-by: Joppla <joppla@gmx.com>
Co-authored-by: Validbit <validbit@outlook.com>
Co-authored-by: Chasm Solacer <chasmsolacer@users.noreply.hosted.weblate.org>
Co-authored-by: Akal! <ihsani.akmal.0@gmail.com>
Co-authored-by: Edgars Andersons <Edgars+Weblate@gaitenis.id.lv>
Co-authored-by: Mehmet Ali Cuma <v6lhost@proton.me>
Co-authored-by: 是果宝呐 <shiguobaona@163.com>
Co-authored-by: Giuseppe Barichello <beppuz@gmx.com>
Co-authored-by: marciozomb13 <marciozomb13@outlook.com>
Co-authored-by: Bora Atıcı <boratici.acc@gmail.com>
Co-authored-by: Péter Czeglédy <czegledyp2@gmail.com>
Co-authored-by: Jonatas P <jonatasp5592@gmail.com>
Co-authored-by: Rasel Molla <msg4mrm@gmail.com>
Co-authored-by: Bi Bi Le <lebibibioihandsomeboy.ghost@gmail.com>
Co-authored-by: Juan M Sevilla <jumase@disroot.org>
Co-authored-by: Shine WaiLinn <shinelinn1897@users.noreply.hosted.weblate.org>
Co-authored-by: Sai Hak Moe Htike <pekhejdj@gmail.com>
Co-authored-by: Matteo Borella <borella.matteo@gmail.com>
Co-authored-by: Ulpi Antor <weblate.residual441@passmail.net>
Co-authored-by: Nataniel Dika Kurniawan <hikawaart2@gmail.com>
Co-authored-by: Yusif Omran <yusifrad20@gmail.com>
Co-authored-by: Samuel Jabez P <jrbros2346@gmail.com>
Co-authored-by: Regu_Miabyss <cyanogenmod.cid@gmail.com>
Co-authored-by: Tannaz M <tannaz.monajemi@gmail.com>
Co-authored-by: winver <kirillstuzhuk@gmail.com>
Co-authored-by: Summer-Box1228 <tingrong1228@gmail.com>
Co-authored-by: E. Ta. <eta00823@gmail.com>
Co-authored-by: Abo Moayd <aboeanas0y2014@gmail.com>
Co-authored-by: meQ Qentlh <brynnhold@gmail.com>
Co-authored-by: Adrià Vilanova Martínez <me@avm99963.com>
Co-authored-by: QonDonion <dolchanat.a@gmail.com>
Co-authored-by: Leonardo Taglialegne <leonardo@taglialegne.it>
Co-authored-by: Mikael Kujanpää <mikael.pajunen@gmail.com>
Co-authored-by: Vaisakh K M <vaisakhkm2625@gmail.com>
Co-authored-by: Debojit Mozumder <debojitmozumder38@gmail.com>
Co-authored-by: Rifat <rifatstudent463@gmail.com>
Co-authored-by: Guzleon <guzleon@yahoo.es>
2026-05-02 20:11:56 +02:00
Jules Aguillon 5d9a105e5d Update the README and screenshots in preparation for the release (#1255)
* README: Acknowledge NLnet

* Move FUNDING.yml into .github/

* Update screenshots

Redo the screenshots with the suggestions visible.
2026-05-02 19:43:23 +02:00
Jules Aguillon 9c23e6c5f3 Emoji suggestion (#1235)
Suggest an emoji in addition to the 3 suggested words when the
current word matches an alias in the emoji dictionary, if
available.
2026-05-02 19:32:21 +02:00
Jules Aguillon d164820bca Reduce the size of suggestions to fit (#1248)
The font size of the suggested words is reduced if the word would
otherwise split on two lines.
2026-05-01 20:25:20 +02:00
Jules Aguillon b844af1f28 Fix the spacebar in Hangul combining (#1244)
* Fix the spacebar in Hangul combining

The encoding for the spacebar changed and the Hangul combining code was
not updated.

* Change the default layout for Korean
2026-04-24 11:32:19 +02:00
Jules Aguillon 6477c90506 CI: Run the tests (#1245)
Run the tests before building the debug APK in CI. This checks that the
unit tests pass and that the generated files are uptodate.

Doesn't fail if the generated files are outdated. Instead, the APK is
built with them updated.
2026-04-18 21:09:55 +02:00
Jules Aguillon c6774196ea Add more symbols to superscript and small_caps (#1198)
* Add more symbols to accent_syperscript
* Add all uppercase and lowercase variants to accent_small_caps
* Use ʁ instead of ᴚ in accent_small_caps
2026-04-18 16:18:13 +02:00
Jules Aguillon af5f6df02c Autocorrect middle word (#1242)
* Fix crash when typing space in the middle of a word

* Don't trigger autocorrect when the cursor is not at the end of a word

This prevented from editing a word that was already typed.

* Don't undo autocorrect at the wrong time

Backspace was trying to undo autocorrect even after some other action
were done after the last autocorrect. This ensures that the keyboard
remembers accurately the last action.
2026-04-16 15:33:28 +02:00
Jules Aguillon e832c3cd80 Fix crash added in #1233 (#1234)
Crash added in https://github.com/Julow/Unexpected-Keyboard/pull/1233
2026-04-12 14:41:28 +02:00
Jules Aguillon a1d0342033 Better spell check with cursor in the middle of a word (#1233)
* Better spell check with cursor in the middle of a word

Suggestions are based on the entire word and no longer the part of the
word just before the cursor. Also, tapping a suggestion or the space bar
autocorrect replaces the entire word.

* Reduce the number of calls to refresh_current_word

While the cursor moves, calls to refresh_current_word are now only done
when the cursor exits the current word.
2026-04-12 14:33:27 +02:00
Jules Aguillon 5ec663c306 Insert a space when undoing autocorrect (#1232)
This prevents the same suggestions to be presented again and autocorrect
to be activated again when pressing space.

This extra space is wanted because pressing the spacebar triggered
autocorrect in the first place.
2026-04-12 14:30:04 +02:00
Jules Aguillon 833b4a2154 Better suggestion with diacritics (#1223)
* Update cdict

* scripts/subst_of_compose.py: Compute substitutions

from compose mappings. They are used when building dictionaries.

* Add substitutions compose data

* Better suggestion with diacritics

This improves the suggestions for words that contain diacritics and
uppercase letters.

This works by stripping diacritics both when building the dictionaries
(using word aliases added in cdict: https://github.com/Julow/cdict/pull/3)
and during lookup. Cdict then takes care of resolving the correct word.

The substitutions are generated using mappings from `fn`, `shift` and
all the `accent_*` modifiers into srcs/compose/substitutions.json
This can be updated easily when more mappings are added.
2026-04-10 19:08:23 +02:00
Jules Aguillon 8921de7f02 Handle Google Keep bug (#1230)
The Google Keep text area sends contradictory flags to keyboards,
resulting in the suggestions to be disabled.
This seems to be a bug in Google Keep.
2026-04-10 19:04:03 +02:00
Jules Aguillon afa7c0187a Refresh suggestions immediately after language switch (#1229)
* Switch dictionary when language changes

The dictionary was otherwise updated by closing and opening the keyboard
again.

* Refresh suggestions immediately after language switch
2026-04-10 19:03:51 +02:00
Jules Aguillon 7bd9306a9f Dictionary activity: Status message when the keyboard is not enabled (#1228)
This shows a reason why the list is empty and removes confusion.
2026-04-10 19:03:37 +02:00
Jules Aguillon f29ae92ba7 Disable spacebar autocomplete when suggestions are hidden (#1227)
The spacebar autocomplete option was still working even when the
suggestions strip was correctly hidden in applications like Termux.
2026-04-10 19:03:20 +02:00
Jules Aguillon 5f63214c08 Increase lookback when looking for the last word (#1226)
For example, typing "dictionarirs" suggests "dictionaries" but moving
the cursor away and back results in no suggestion. Because the lookback
was 10 characters long, the keyboard was seeing "ctionarirs".
2026-04-10 15:18:50 +02:00
Jules Aguillon 4dab3a609c CI: Check whether ComposeKeyData is uptodate (#1204) 2026-03-16 00:00:41 +01:00
Jules Aguillon 2966a45922 CI: Disable workflow runs on push (#1202) 2026-03-15 01:34:19 +01:00
Jules Aguillon ece8fb51ce Add Assamese layout (#1196) 2026-03-06 13:45:01 +01:00
Jules Aguillon 958900ca2f Update target SDK version to 36 (#1190)
* Fix keyboard not showing on Android 16

* Update target SDK version to 36
2026-02-25 00:12:43 +01:00
Jules Aguillon ae4a9d4514 Fix no keyboard after switching from clipboard manager (#1189) 2026-02-24 23:57:10 +01:00
Jules Aguillon 91b2970c1f Fix crash introduced in #1183 (#1187) 2026-02-24 22:50:28 +01:00
Jules Aguillon 9863dcea9e gradle: Show an error when Git submodules are not initialized (#1188)
* CONTRIBUTING: Document Git submodules

* build: Error during build if the submodules are not initialized
2026-02-24 22:50:16 +01:00
Jules Aguillon a80afa5fbe Improve suggestion for capitalized words (#1183)
Suggestions were previously case-sensitive, which gave very bad results
for the first word of a sentence.

This makes sure that the suggestions for capitalized words are as good
as for all lower-case words and that the suggestion doesn't turn the
uppercase letter into lower case.
2026-02-22 21:13:11 +01:00
Jules Aguillon d172455eb4 Fix space and delete not repeating (#1182) 2026-02-21 13:08:42 +01:00
Jules Aguillon df3594bd53 Autocomplete on space bar and undo on delete (#1179)
* Refactor: Implement the space key as an editing action

The space key is no longer a CHAR key but now an EDITING key. This
allows changing the behavior of the space bar while allowing custom
layout users to define a key outputing a space as before.

KeyModifier and ComposeKey are updated to treat the space key as before.

* Enter the best suggestion when the space bar is pressed

* Refactor: Implement backspace as an editing action

* Undo suggestion when delete is pressed

The delete key (backspace internally) undoes the suggestion if the last
action done was entering the suggestion with either the space bar or the
candidates view.

* Add an option to enable space bar autocomplete

This option is off by default. Undoing a completion with backspace works
in any case.

* Refactor: Track selection emptyness in CurrentlyTypedWord

This removes an expensive RPC call.
2026-02-19 00:37:42 +01:00
Jules Aguillon ebf80415d8 Refactor: KeyValue constants (#1180)
* Refactor: KeyValue constants

Add constants for keys that are accessed from the app's code. This
simplifies the fake pointer handling in Keyboard2View.

* Refactor: Pre-compute action key replacement

The action key and the enter swap are pre-computed in EditorConfig. This
simplifies the code.
2026-02-19 00:35:14 +01:00
Jules Aguillon 1cd252f8fa Increase maximum value for the bottom margin option (#1178) 2026-02-14 16:04:30 +01:00
Jules Aguillon 0109f30e22 Fix label color when keys are pressed (#1173)
The color of labels on a pressed key that were not the label being
activated (eg. the labels on the corners when activating the label in
the centre) was not correct.
2026-02-08 00:33:52 +01:00
Jules Aguillon 77c4a27c4c Spell checking (#1137)
This adds dictionary-based spell checking to the keyboard. The keyboard looks at the word being typed and matches it against a dictionary to either complete the rest of the word or find alternative spellings.

The core of this feature is implemented in cdict, which is included as a
submodule in vendor/cidct.

Cdict is developped at https://github.com/Julow/cdict
The dictionaries are hosted at https://github.com/Julow/Unexpected-Keyboard-dictionaries/
The wordlists used to build the dictionaries are the same ones used by
HeliBoard from https://codeberg.org/Helium314/aosp-dictionaries

- Add an activity accessible from the launcher app that lists available
  dictionaries with a download button.
  The DictionaryListView view shows the list of available dictionaries and
  handles downloading and installing them.

- The Dictionaries class manages installed dictionaries. Dictionaries are
  installed as individual files into the app's private directory.

- Available dictionaries are listed in dictionaries.xml, which is generated
  when building Unexpected-Keyboard-dictionaries.
  method.xml mentions the dictionary name for each locales.
2026-02-02 00:20:00 +01:00
Jules Aguillon 2ecf93d990 Candidates view improvements (#1168)
* Refactor: Create subpackage 'suggestions'

* Candidates view: Status message when no dictionary installed

Show a message on the candidates view instead of leaving it empty. A
button points to the dictionary installation activity.

* Add an option to disable the suggestions

* Refactor: Remove Config.should_show_candidates_view

This was moved to EditorConfig.

* Don't disable text suggestions in some text boxes

* Suggestion text size matching settings

The candidates view height is based on the height of keyboard rows and
the suggestion text size is based on the size of labels on the keys.

This is influenced by symbol size and keyboard height options.
2026-02-01 23:25:38 +01:00
Jules Aguillon b9072daaf6 Avoid loops in modmaps (#1167)
It was possible to define a loop that would crash the app with the
following modmap:

    <ctrl a="left" b="left:ctrl,left"/>

With this change, modmap are not taken into account while evaluating
macros. The modmap above modifies ctrl+left into ctrl+left.
2026-01-31 15:36:22 +01:00
Jules Aguillon 1b8506876a Option to switch to the previously used keyboard (#1165)
The "Switch to the last used keyboard" is renamed to "Switching between
input methods" and allows to select "Switch to last used", which was the
default in older releases.
2026-01-30 21:18:48 +01:00
Jules Aguillon e05be0821b README: Remove the "Similar apps" section (#1163) 2026-01-25 13:47:44 +01:00
Jules Aguillon c669a755a6 Add the small capital letters dead key (#1156)
* Add the small capital letters dead key

It can be added to the keyboard from the settings or into custom layouts
as `accent_small_caps`.

Add all the symbols listed on https://en.wikipedia.org/wiki/Small_caps
2026-01-18 21:57:17 +01:00
Jules Aguillon 3b4aa33ff3 Fix crash when using the Monet themes on Android 9 (#1155)
The color resources starting with `@android:color/system_` are not
available on API < 31.

No effort is made to implement the Monet feature on Android 9. Instead,
the monet themes look like the Dark and Light themes.
2026-01-18 17:28:10 +01:00
Jules Aguillon a848897586 Refactor: Split DeviceLocales out of Keyboard2 (#1154)
* Refactor: Split DeviceLocales out of Keyboard2

This moves the code from Keyboard2 that handles the active IME subtypes
and the current one.

The goal is to access this information from the dictionary activity
while simplifying the code of Keyboard2.

* Refresh the candidates view when subtype changes

This fixes the status message being inconsistently shown.

* Refactor: Load DeviceLocales less often

Previously, [DeviceLocales.load()] was called everytime the keyboard was
shown on the screen. This operation is moderately costly and only need
to be done when the IME subtype changes.

* EditorConfig: Fix crash on Android 9
2026-01-18 17:26:41 +01:00
Jules Aguillon 4d4c22b4e2 Merge pull request #1150 from Julow/candidates_view
Candidates view
2025-12-28 19:02:45 +01:00
Jules Aguillon bdb05bcef0 Fix CurrentlyTypedWord counting the first letter twice 2025-12-28 18:13:17 +01:00
Jules Aguillon 2208079e48 CurrentlyTypedWord: Handle key events
Currently, refreshing the current word on each key event.
Refreshing is done after a short delay, to ensure the editor has handled
the event.
2025-12-28 18:13:17 +01:00
Jules Aguillon c4d802d873 CurrentlyTypedWord: Handle selection
When selection is entered, the current word is cleared.
2025-12-28 18:13:16 +01:00
Jules Aguillon 2b60f94ead Enter the suggestion when it's pressed
The current word is replaced by the pressed suggestion.
2025-12-28 18:08:36 +01:00
Jules Aguillon f082fcdebc 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.
2025-12-28 18:08:12 +01:00
Jules Aguillon 98c1b8db82 Candidates view
The `CandidatesView` is implemented as a `LinearLayout` that is divided
horizontally with up to 3 `TextView`. It might in the future contain
buttons on the sides.

The candidate view is nested into the input view rather than using
Android's `setCandidatesView` and callbacks as the API is unreliable and
complicated.

The first suggestion goes in the middle to be more accessible. The
second suggestion goes on the right to be more accessible to the
right-handed, because it must go somewhere.
2025-12-28 17:56:37 +01:00
Jules Aguillon dfaf4dbb57 More practical definition of method.xml (#1149)
Locale are now defined in `gen_method_xml.py` in a more convenient and
checked way. It contains both the locale definition and the generation
script.

`method.xml` is generated with:

    gradle test

The goal is to support dictionaries for spell checking.
2025-12-27 23:49:50 +01:00
Jules Aguillon dab50e0572 Fix clipboard manager crashes (#1148)
* Fix background crash in clipboard history service

The clipboard history service might crash when the connection between
the keyboard and the system is in a bad state.

* Fix race condition in clipboard history service

The clipboard history service callback appears to be called concurrently
leading to concurrent accesses to data and to concurrent calls to
'on_clipboard_history_change'. Access are now synchronized.

* Fix clipboard manager crash when device is locked
2025-12-26 16:43:34 +01:00
Jules Aguillon b40be68773 Fix various linting issues (#1146) 2025-12-22 01:27:07 +01:00
Jules Aguillon 258215f26c gradle: Remove unecessary rule
The output APKs used to be named 'juloo.keyboard2.apk' are now named
'Unexpected-Keyboard-release.apk' since the Gradle upgrade and the rule
setting it hasn't been working since.
2025-12-18 19:50:22 +01:00
Jules Aguillon 41777fdda6 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.
2025-12-18 19:15:32 +01:00
Jules Aguillon 5fc1da0a2e Remove emoji history migration function (#1139)
This function was used to migrate the representation of the emoji
history and needed a very large table.

This reduces the app size by 22KB.
2025-12-13 22:12:36 +01:00
Jules Aguillon f834b2a82a AZERTY: Make sure the accents are available (#1140)
Remove the `loc` prefix for important accent dead keys and add ê.
2025-12-13 22:09:57 +01:00
Jules Aguillon 498194231f Update the emoji list to Unicode 17.0 (#1138) 2025-12-13 21:40:46 +01:00
Jules Aguillon 08ebf8fabc Fix parsing of escaped characters in macros (#1126)
* refactor: Better printing for KeyValue in tests

* Fix parsing of escaped characters in macros

The parsing code was bugged with custom macros like `symbol:\abc` and
`symbol:\\abc`.
2025-12-13 15:58:34 +01:00
Jules Aguillon 00cf534e00 build: Avoid unreproducible rules in regular builds (#1125)
The genEmojis rule makes a network request and must not be done during a
regular build.
The compileComposeSequences updates a file that is checked in the
repository and doesn't need to be updated in a regular build. Both are
now handled like 'genLayoutsList'.
2025-11-10 16:27:29 +01:00
Jules Aguillon eae05bb9bd gradle: Set explicit dependency for rule genLayoutsList 2025-11-01 23:43:03 +01:00
Jules Aguillon ac498d4ee9 Update ComposeKeyData.java
Missing from previous commit.
2025-11-01 23:24:34 +01:00
Jules Aguillon 8db00d51ab Allow smaller row height in custom layouts (#1100)
The height of row set with `<row height="...">` cannot be lower than 0.5
to avoid rendering problems.
This restriction is not necessary when the row has no key and is lifted
in this case.
2025-09-15 14:15:55 +02:00
Jules Aguillon ab85fb717d shell.nix: Remove repoJson
nixpkgs-unstable is now uptodate.
2025-09-04 00:25:56 +02:00
Jules Aguillon 795889bf81 README: Remove capitals in "Open Source" 2025-09-01 00:02:02 +02:00