Compare commits

...
Author SHA1 Message Date
nyra 681cb29686 Space bar ribbon: fail-safe host graph fetch and parser 2026-09-27 18:35:02 +00:00
nyra 73b73d89a2 Merge: gauge low-usage fill uses the space bar button colour 2026-09-27 18:27:49 +00:00
nyra 06cb2526a4 Gauge: low-usage fill reuses the space bar button colour 2026-09-27 18:27:49 +00:00
nyra 12a95a4604 Merge: gauge low-usage fill matches the Orchid theme 2026-09-27 18:25:24 +00:00
nyra b263d75373 Gauge: low-usage fill matches the Orchid theme instead of cockpit green 2026-09-27 18:25:24 +00:00
nyra 495da34e37 Merge: long-press the usage gauge key to open the usage page 2026-09-27 18:20:59 +00:00
nyra a2fc16baeb Long-press the usage gauge key to open the usage page 2026-09-27 18:20:55 +00:00
nyra 98cf27a3a9 Merge keyboard work: emoji key, live usage gauge key, Orchid theme 2026-09-27 18:13:10 +00:00
nyra 31eecc2a13 Add the Orchid theme: pink letters, violet alternates, violet activated keys
Harley wanted a pink/violet keyboard. The alternates use the exact violet sampled
from his own UI accent (#c67dff); letters are pink (#ff8ad8), activated keys
(shift/Esc/123+) are filled violet (#a855f7) with dark glyphs, caps-lock is
periwinkle blue (#9db8ff), background is violet-black (#100a1c). Contrast checked:
9.13 / 7.19 / 9.92 / 4.9 :1. Five edits: themes.xml style, arrays.xml entries+values
(kept index-aligned), strings.xml label, Config.java case.
2026-09-27 18:07:05 +00:00
nyra 08c895aa12 Add live usage gauge key (GPT gradient + DeepSeek spend) beside L
- UsageGauge: WireGuard-only JSON fetch, cached, background thread, stale-aware
- Gauge key: gradient fill rises with the tightest Codex window, %.1f of today's
  DeepSeek spend, red below a $1.00 balance, flat grey when stale/offline
- Display-only: marker lives in the key indication field, no character, touch swallowed
- Settings entries; cleartext permitted only for 10.10.10.1
- ComposeKey: composing to U+00A0 keeps the named nbsp key, since adding a layout
  key perturbs the generated compose table and would otherwise emit the display glyph
- 5 new unit tests; all 21 tests pass
2026-09-27 17:38:18 +00:00
nyra be6f455b01 Rename app id to harley.keyboard and add agent notes 2026-09-27 17:09:44 +00:00
Nyra 5cba22a19a Move the emoji selector onto the Alt key top-right corner
Standalone top-row emoji key replaced by a badge in the Alt key key2 swipe slot, drawn as a smile-in-a-circle glyph: new special-font codepoint 0xE01D from Font Awesome face-smile, rebuilt into assets/special_font.ttf with fontforge. Corner slots carry FLAG_SECONDARY so labelColor dims them to secondaryLabelColor; the badge overrides to _theme.labelColor to match the rest of the keyboard labels, and is identified by its codepoint rather than an Event or Kind accessor, because those are only valid for specific kinds and crashed the IME when called unguarded in the draw path. Swipe toward the key top-right to reach it; the config gear stays in the bottom-left. check_layout.output excluded on purpose - unrelated latn_neo2 drift.
2026-09-27 14:16:47 +00:00
Nyra 0f2f8a47ff Fix crash: guard getEditing with a getKind check before colouring the space bar
KeyValue.getEditing is only defined when getKind is Kind.Editing. _code is overloaded, so on a character key it holds the character and Editing.values() indexed with it threw ArrayIndexOutOfBoundsException length=16 index=113 from drawLabel, crashing the IME on every draw. The phone was rolled back to the previous build first, then this fix was installed. Verified no crash after reinstall.
2026-09-27 13:56:49 +00:00
Nyra affc78fb63 Space bar joystick glyph carries the DeepSeek peak colour; drop the candidate-bar dot
The indicator is the space bar label itself (Editing.SPACE_BAR), so it needs no extra UI. Keyboard2 repaints the keyboard view every 60s while the input view is visible. Regenerated ComposeKeyData follows the layout change (moving the tilde and equals keys changes which keys compose), which is also what made the two unit tests pass again: they were failing on a stale generated state, not on real behaviour.
2026-09-27 09:25:52 +00:00
Nyra 5781fb6efc Add emoji key in the top-right corner, DeepSeek peak/off-peak dot, move tilde/backtick to s and equals/plus to f
switch_emoji uses a normal-font smiley label: 0xE001 is the joypad glyph in this fork. Peak dot: UTC Mon-Fri 01-04 and 06-10 pink, else blue; refreshes every 60s while the keyboard is visible.
2026-09-27 09:19:25 +00:00
Harley 6be0938566 Shrink suggestion text size to 85% to prevent bottom clipping 2026-07-07 19:30:44 -04:00
Harley 4520271c8f Increase suggestion strip height to 63.7% (another +3%) 2026-07-07 19:29:11 -04:00
Harley 656c1e24f4 Increase text suggestion area height from 60% to 61.8% (+3%) 2026-07-07 19:16:30 -04:00
harley eb9a5103c2 Increase key spacing margins: horizontal 13, vertical 6 2026-07-07 06:12:12 -04:00
harley f59603c90b Full layout overhaul: Fn grid, bottom row reorg, symbol moves, dictionary, compose relocation 2026-07-07 05:59:17 -04:00
harley 4534df8bcb Layout: compose on pg key, keyboard height 0.81, smaller sublabels 2026-07-07 04:50:38 -04:00
harley ecdb43a593 Layout: compose on pg key, keyboard height 0.81, smaller sublabels 2026-07-07 04:50:29 -04:00
harley 939e8da252 Save state before swipe engine work 2026-07-07 02:59:52 -04:00
harley e2d5b47c7c Layout overhaul: symbol moves, bottom row reorg, Tux meta key
- '!' moved to bottom-left of '1' (q sw), removed from e ne
- Dash on o sw, underscore on o se
- ':' on l sw (replaced backslash)
- Bottom row: Ctrl | Alt | Space | Fn | Enter
- Fn moved right of space bar, corner swipes cleaned up
- Voice typing moved from Enter to Fn bottom-left (key6)
- Clipboard on Ctrl bottom-left (key6)
- New 'tux' key: META modifier displayed as Tux penguin (0xE002)
  from special_font/002.svg, toggleable (latch+double-tap lock)
- Enter only has action corner (key2), no voice typing
- Config (settings) kept on Fn up-swipe (key1)
2026-07-07 02:18:32 -04:00
harley 96966332ce Bump long-press timeout 600→700ms 2026-07-07 02:08:47 -04:00
harley b034191a1c Move numbers to left side of top row, restore shift next to Z, add config to Fn
- Top row numbers moved from ne (top-right) to nw (top-left) per request
- Existing nw symbols (tilde, !) shifted to ne positions
- Shift restored in z-row (normal key width)
- Backspace now normal key width (no more 1.5x)
- Fn key now has corner swipes: config, change_method, emoji, switch_numeric
- Bottom row: Fn | Ctrl | Alt | Space | Enter
2026-07-07 02:02:35 -04:00
harley b86481461a Rewrite joypad as direction-lock + auto-repeat
- Joypad no longer uses displacement-accumulation (useless on space bar).
- After long-press space bar, determine direction from finger offset vs origin.
- Direction locks, fires one cursor event, then auto-repeats at
  longPressInterval rate via _longpress_handler.
- Changing finger direction updates the lock (fires in new dir immediately).
- Returning finger to dead zone stops auto-repeat.
- Removed SPEED_VERTICAL_MULT and startup threshold:space bar has no room.
- Space bar icon changed to 0xE001 (4-directional arrows).
2026-07-07 01:55:34 -04:00
harley 5fbd21c7d9 Move joypad to space bar long-press, remove separate joystick key
- Space bar long-press now activates Joypad cursor mode
  (long-press detected in handleLongPress before key-repeat)
- Removed separate cursor_joystick key from bottom row
- Widened space bar (4.2 → 6.0) to compensate
- Bottom row: Shift | Fn | Ctrl | Alt | Space (joypad on long-press) | Enter
2026-07-07 01:49:56 -04:00
harley b6618444a2 Fix: remove shift from z-row, rebuild special font with joystick icon
- Removed redundant shift key from latn_qwerty_us.xml third row
  (shift is now on the bottom row only)
- Rebuilt assets/special_font.ttf to include 001.svg (4-directional
  joystick icon at codepoint 0xE001)
2026-07-07 01:45:14 -04:00
harley 4a05bf54d5 Add 2D joypad cursor slider + custom bottom row layout 2026-07-07 01:38:43 -04:00
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
Lokesh Kumar c6a568a74b add new item on top for history view as well (#1330)
* when pinning history item, keep it on top

* add new item on top of history as well
2026-06-20 17:50:47 +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
Lokesh Kumar 27329091af add hide_self key to hide keyboard (#1329) 2026-06-14 12:57:06 +02:00
Lokesh Kumar a7645c3934 when pinning history item, keep it on top (#1328) 2026-06-14 12:50:21 +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
AndreiD049 8532acf814 fix: inclusive check for word boundaries (#1281) 2026-05-20 01:01:34 +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
alotbsol555 11b735bfe8 Update README (#1279)
Removed mention of network requests from the README, due to dictionary downloads.
2026-05-06 01:03: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
Jon Musselwhite 7b07b14a80 Fix missing null gate (#1273) 2026-05-05 02:26:41 +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
Tony O 08eb3a04a6 Change default locale for en_* and update IME layout (#1237)
Change default unknown locale dictionary from en_US to en_GB
2026-04-14 19:41:53 +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
Spike 0f3ec187c9 Documentation: Point to default mappings as requested in #1222 (#1225) 2026-04-10 14:46:29 +02:00
Jure Varlec 13f1996af9 Fix building on NixOS (#1219)
* shell.nix: bump platform version to match target

* shell.nix: make gradlew work on NixOS

This removes the wrapper provided by `shell.nix`. Folks expect the
`./gradlew` wrapper to work, so this approach is more straightforward.
2026-04-08 17:38:45 +02:00
Hopeine 35ccaafe65 doc: Fix hyperlink of bottomw_row.xml and number_row.xml (#1216)
Add blob/master/
2026-04-08 17:29:34 +02:00
Tony O 963399417e Add Finnish QWERTY keyboard layout XML (#1221) 2026-04-05 23:34:36 +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
Tyler b25b670c6b Making dictionaries compatible with 16 KB devices. (#1199) 2026-03-15 01:27:37 +01:00
Jules Aguillon ece8fb51ce Add Assamese layout (#1196) 2026-03-06 13:45:01 +01:00
dzaima 18157a1cd8 Make layout text editor not redraw every frame (#1192) 2026-03-06 13:44:48 +01:00
dzaima 27fdcb6bfc Some slider changes (#1195)
* Helper for whether a slider is vertical

* Only accumulate delta for the current slider's direction

* Slow down horizontal cursor movement while ctrl is held
2026-02-27 00:41:48 +01:00
dzaima 6a19f7ccd3 Separate colors for pressed vs activated labels (#1193) 2026-02-25 23:57:39 +01:00
dzaima 164c8732c0 Add missing alphabet + ~ compose sequences (#1194) 2026-02-25 23:55:31 +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
10Develops be0aa07a2a Added keyboards (#1129)
* Delete srcs/layouts/armenian_ph_am.xml

There is a phonetic layout which is used in old typewriters

* Amendments according to GOST 6431-90
* Russian traditional layout cyrl_jiuken.xml
* Create cyrl_yawerty.xml

Added ЯВЕРТЫ layout

* Update cyrl_jcuken_ru.xml

Typo fixed

* Added QZERTY layout for Italian and Latin
2025-12-13 23:05:29 +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
Andy Callisto 0ad03c6dea Ukrainian l10n update (#1128)
* Ukrainian l10n update

* "Debug" translated
2025-11-19 21:00:21 +01:00
dzaima be8a99bdc6 Fix insets being excluded from computed width (#1127) 2025-11-10 18:32:41 +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
Autissima c717461ef5 Turkish F layout (#1096) 2025-11-01 23:47:35 +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
Houfalafel 02c11132b2 Update extra.json (#1118)
change compose for n͠g to g + n + ~ to avoid overlap. this in order to add n + g = ŋ. also added lowercase Ğ.
2025-11-01 23:23:22 +01:00
wei lang 635c7d5882 Cobalt & Pine theme (#1084) 2025-09-29 01:03:35 +02:00
Matej Drobnič df8e7a01e0 Make history duration configurable (#1074) 2025-09-29 00:56:23 +02:00
J. Fronny 7fdf63b930 Upgrade Gradle (#1097)
* Enable configuration cache and up-to-date checking
2025-09-29 00:37:26 +02:00
Spike 462b860e4e Custom-layouts.md: Document minimum row height (#1101) 2025-09-15 14:16:26 +02: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
Autissima 5b3dc8d5ed Python script encoding fix (#1093)
* Changed Python scripts so they work on my machine

file open() used default encoding (cp1252 on my machine) but the text is utf-8, had to specify encoding in check_layout.py
2025-09-03 22:41:10 +02:00
Jules Aguillon 795889bf81 README: Remove capitals in "Open Source" 2025-09-01 00:02:02 +02:00
Jules Aguillon 6d0aa4cf51 Use the <fn /> mappings first when typing a gesture (#1085)
This allows assigning mappings to letters without changing the Shift
mappings and making uppercase impossible to type.

For gestures, the Shift modifier is still applied first, unless a custom
mapping for <fn/> is set for the key.
2025-08-31 23:35:34 +02:00
Animesh dfb2c7eaf9 add Everforest Light theme (#1080) 2025-08-24 22:36:45 +02:00
Jules Aguillon cedf3aeb1c Slider sensitivity option and improve slider ergonimics (#1070)
* Add option 'Space bar slider sensitivity'

* Fix slider moving the cursor twice at the beginning

The slider was generating two events when first activated.
Since 2bed42857.

* Make slider less sensitive for the first step

This moves the second slider step approximately 40% further and takes the
new sensitivity option into account.
Allows moving the cursor by one spot more easily.
2025-08-17 19:24:08 +02:00
Jules Aguillon c1d473b4a0 Add support for four important Nigerian languages (#1077)
This adds the English, Hausa, Yoruba and Igbo languages for Nigeria. The
goal is to add the ₦ symbol as well as basic support for these
languages. No layout is added.
2025-08-17 01:59:46 +02:00
Jules Aguillon 00d7d88271 gradle: Disable sync_translations (#1076)
The diffs created by sync_translations.py creates conflicts with the
changes made on Weblate. It is disable to make merging translations from
Weblate easier.
2025-08-16 18:55:26 +02:00
dom 7e4e4bf4d9 Update Custom-layouts.md reference to web editor (#1064) 2025-08-07 20:15:55 +02:00
Jules Aguillon 020e80019b Fix very small label size on 11+ columns layouts (#1046)
The label size was computed against the width of keys on the keyboard,
which resulted in a different label size on different layouts.
Notably, it made the labels very small on a 11 columns layout and
relatively larger on the numpad.

The label size is now computed against a baseline of 1/10 of the width
of the screen.
2025-08-07 20:07:59 +02:00
Jules Aguillon 679f52cf45 Add '⊢' to the greekmath layout 2025-08-07 12:25:42 +02:00
cillyvms 9588f55619 Fix alternate keyboard layouts rendering behind navbar on some devices. (#1062) 2025-07-30 22:47:37 +02:00
Skynetcat 5c7484388f doc: Added Arabic diacritics to documentation of possible key values (#1061) 2025-07-26 12:35:24 +02:00
Jules Aguillon 2bed42857b Fix missing swipe vibration and visual feedback (#1054)
This was removed by mistake in 42528ab211.
2025-07-22 22:03:53 +02:00
Harry-Ais0 fad74bb123 Add compose sequences for ꜩ Ꜩ (#1058) 2025-07-22 22:02:55 +02:00
Anastázius Kaejatídarján 43dd3a2818 Added Majuscules to the Cyrillic Compose Sequences (#1042)
* add majuscules to compose
* add tse to compose
* added reverse ya FN to modernize it FROM the older form
* fix accent FN and add reverse arabic-heh FN
* little improvements and additions
* QoL improvements for Kurdish Sorani
2025-07-19 17:54:57 +02:00
JeelsBoobz c4a1e2e664 Fix autocapitalisation flicker (#1047) 2025-07-19 17:50:27 +02:00
Mal Bajun 13acf90541 Replaced combining_acute with combining_aigu (#1040) 2025-07-13 19:51:55 +02:00
Matej Drobnič a83b40066e Use screen width to switch layouts (#1029)
This changes layout switching logic to detect screen width rather than increasingly specific portrait/landscape/unfolded state.

This reduces number of different auto-layouts back to 2: narrow devices (such as a phone in portrait) and wide devices (such as a phone in landscape or a tablet).
2025-07-11 19:14:36 +02:00
Mal Bajun c6e35ba4b6 Improve layout cyrl_jcuken_as (#1039) 2025-07-11 18:55:20 +02:00
Jules Aguillon e013128142 Release 1.32.1 (50)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2025-07-09 00:24:29 +02:00
Jules Aguillon 898956256a Workaround Godot editor not implementing setSelection() (#1033)
This was tested against:

    org.godotengine.editor.v3
    org.godotengine.editor.v4
2025-07-06 23:18:58 +02:00
Jules Aguillon 8cb9b30461 Fix crash with unexpected value in NumberLayout pref (#1036) 2025-07-06 21:57:41 +02:00
solokot 309fba4766 Update Russian translation (#1035) 2025-07-05 12:45:51 +02:00
Jules Aguillon d1dfc80df6 ci: Disable translation check
The translation check is creating conflicts with changes done on Weblate
and is superfluous.
2025-07-02 23:15:33 +02:00
Joey Schaff 5c4964e438 Add a missing comma in /res/values/strings.xml (#1026) 2025-07-02 23:13:12 +02:00
Jules Aguillon 957dbdc7fe Fix fastlane metadata 2025-07-02 01:52:43 +02:00
Jules Aguillon babc3ec88a Release 1.32.0 (49)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2025-07-02 01:05:52 +02:00
Jules Aguillon 42fa47459c Promote ComposeKeyData.java 2025-07-02 00:30:58 +02:00
Jules Aguillon 30d1f5635c Update French translation 2025-07-02 00:30:50 +02:00
+9 75c1ce38df Pull translations from Weblate (#1025)
Translated using Weblate

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>
2025-07-02 00:28:53 +02:00
Mal BajunandPavel «Mal Bajun» Skrylev c308b57611 feat: added јcuken leyout for all slavic language (#992)
Co-authored-by: Pavel «Mal Bajun» Skrylev <majioa@yandex.ru>
2025-07-01 23:56:07 +02:00
Jules Aguillon 52c0e8c798 Add cyrillic combining kavyka and palatalization (#998) 2025-07-01 23:42:49 +02:00
Jules Aguillon 1ff3bf2fc9 Make vertical sliders slower (#1023)
Make vertical sliders slower. The intention is to make the up/down
slider slower, as we have less visibility and do smaller movements in
that direction.
2025-07-01 23:41:49 +02:00
Jules Aguillon a08db25661 Fix extra bottom margin when navbar buttons absent (#1024)
* Fix extra bottom margin when navbar buttons absent

Fix the extra space that was appearing when the gesture-navigation bar
didn't contain the "switch IME" or "close IME" buttons.
This was found on OneUI 7 with the two "keyboard key" related options
turned off.

* Remove unneeded nav bar detection and width computation
2025-07-01 23:27:24 +02:00
Matej Drobnič 4ed8594794 Add option to also disable number entry layout (#1007) 2025-06-29 16:50:56 +02:00
Jules Aguillon f36a7c8e9d Fix unwanted bottom margin on Samsung OneUI 7 (#1022)
This fixes the unwanted margin at the bottom of the screen on
Samsung One UI 7 based on Android 15.
2025-06-29 16:18:49 +02:00
solokot 004ed95dfd Update Russian translation (#1021) 2025-06-29 11:41:12 +02:00
alotbsol555 9d12981b34 cut and copy with built in keys only if text is selected (#1019)
cut and copy with built in keys only if text is selected to keep existing clipboard content. does not work for key combinations like ctrl+x or ctrl+c.
2025-06-21 22:15:22 +02:00
Jules Aguillon c6da6d6ab5 Fix selection mode not exited when selection cleared (#1020)
The selection mode was not exited when the selection was cleared with,
for example, ctrl+x.
2025-06-19 23:12:37 +02:00
David 2e0be0b32b Added Macedonian language layout (#1016) 2025-06-19 23:11:17 +02:00
Jules Aguillon 42528ab211 Improve selection mode when selection ends cross (#1013)
Emptying the selection with the spacebar slider puts the selection mode
in an unexpected state. This checks that this doesn't happen.

The selection ends can now cross each other, reversing the selection
order. Special care is made to make sure that the sliders go in the
expected direction.

Pointers is changed to send a `onPointerDown` for the first slider event
instead of a `onPointerHold`. This event is detected in
`KeyEventHandler` and the selection ends are reordered if needed when
sliding again.
2025-06-19 01:10:06 +02:00
Jules Aguillon 71d2784026 Add <row scale=""> attribute (#1018)
* Add <row scale=""> attribute

Scale the width of the keys in the row to match a value. Useful to
remove space on the right of the row without adding a 'width' attribute
to each key.

* layouts: Use the 'scale=""' attribute in builtin layouts

This removes the very specific 'width' values.
2025-06-18 00:49:34 +02:00
Jules Aguillon f9b844e988 Increase the clipboard history size to 6 2025-06-14 11:12:21 +02:00
Jules Aguillon 6f0244a29e Add funding.json 2025-06-04 02:08:31 +02:00
Jules Aguillon 2a50a4a129 Fix high keyboard height making it overflows
The calculation for the size of each rows now avoid making the keyboard
bigger than the screen if the Keyboard Height option is unusually high.

The height calculation with the default settings is changed slightly, it
is now assuming that a layout is 3.95 rows high instead of 4. This is
because the bottom row is usually 0.95% the size of other rows.
2025-05-30 20:07:26 +02:00
Jules Aguillon 9ab099175d Fix label size when the keyboard is unusually high
The label size is computed relatively to the width of the keyboard when
the height is larger than 3/2 of the width. This ensures that the labels
have a reasonable size when the keyboard height increases.
2025-05-30 20:07:26 +02:00
Jules Aguillon 0445c310ad Settings: Remove the upper limit in keyboard height
This can be used on phones that have several screens.
2025-05-30 20:07:26 +02:00
tenextractor 536b8d1f67 Add icelandic layout (#999) 2025-05-25 16:44:50 +02:00
Jore d36452d9c3 Update layout customization info in srcs/layouts/latn_qwerty_us.xml (#1001)
- Added info on bottom row customization. (#637)
- Added useful links.
2025-05-25 16:40:15 +02:00
Matej Drobnič 97355881a8 Better support for foldable devices (#982)
* Add AndroidX WindowManager

unfortunately, this seems to be the only way to get fold state, native Android APIs are internal. To add this, we need to update some dependencies, raise java version and raise compile SDK.

* adds separate layouts and separate layout settings for folded and unfolded state of the device.

The affected settings are:
+ the margin bottom settings
+ the horizontal margin settings
+ the keyboard height settings

* Update shell.nix
2025-05-22 23:54:13 +02:00
Jules Aguillon a7312054b5 compose: Add compose+A+e as compose+A+E and many others
compile.py is changed to report when compose+Upper+Upper exists but
compse+Upper+Lower do not.

With these findings, many sequences are added.
2025-05-16 00:59:35 +02:00
Jules Aguillon 3b94bf6a17 Fix duplicated or missing keys and more in layouts
Fix several warnings spotted by check_layout.
2025-05-11 23:06:19 +02:00
Jules Aguillon ff9d2e7d31 check_layout: Check for unknown keys
This can spot mispelled special keys.
2025-05-11 23:05:57 +02:00
Spike b670fe0da2 Clarify use of \\ per Julow in Julow#989 (#990) 2025-05-08 23:04:45 +02:00
solokot 32e82d6791 Update Russian translation (#986) 2025-04-27 00:16:45 +02:00
Anton Karmanov de5c5b5b60 Sinhala phonetic layout (#965) 2025-04-20 20:05:02 +02:00
Jules Aguillon d6dfb5c18c Add compose sequences for n͠g, N͠g and g̃ 2025-04-19 15:10:07 +02:00
Jules Aguillon 460e5214a2 Add class Modmap and test KeyModifier 2025-04-15 00:05:52 +02:00
Jules Aguillon 5ae3ec05e7 strings: Improve "remove clipboard item" prompt 2025-04-14 22:44:37 +02:00
Jules Aguillon 70fb1e8fc1 strings: Shorter name for the settings activity 2025-04-14 22:39:42 +02:00
Jules Aguillon 2bd3e107ac Remove the Share key from preferences 2025-04-14 22:32:38 +02:00
Jules Aguillon 4ae45bd00f Add ù and û to French languages 2025-04-14 22:29:52 +02:00
Jules Aguillon 7a6aef3360 launcher: Fix animations overlapping 2025-04-12 23:30:22 +02:00
Jules Aguillon 9fac081ab8 launcher: Remove fade-in in animations
The fade-in caused the trace to be hidden when animations are disabled.
2025-04-12 23:25:41 +02:00
solokot b4e8b10e2b Update Russian translation (#976) 2025-04-06 22:49:26 +02:00
Jules Aguillon a7d73ebd8a Release 1.31.1 (48)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2025-03-29 15:09:38 +01:00
Jules Aguillon 0acf66d455 Restore previous swipe sensibility
The distance at which a swipe was considered successful was reduced in
188c682 to allow making circle gestures on a key that also had a slider.
It was also useful in reducing accidental sliding.

This is impractical for normal typing so it is reverted. The reduced
range continues to be used for sliders.
2025-03-29 12:04:36 +01:00
Jules Aguillon 85c73d9f62 CONTRIBUTING.md: Update section on srcs/compose 2025-03-29 11:21:50 +01:00
Jules Aguillon 58dabfaa07 Fix emoji flag group missing
Off by one error when parsing the emoji groups.
2025-03-28 00:27:44 +01:00
Haley Halcyon 3d7925340b Update latn_qwerty_jp.xml (#962)
Add macron, used in rōmaji for long vowels
2025-03-28 00:04:31 +01:00
Jules Aguillon e746ccd5d0 Place editing keys on the bottom-right of Z/X/C/V
The code is changed to ensure that extra keys all use a consistent
location.
2025-03-27 23:49:49 +01:00
Jules AguillonandJoey Schaff 6541054cce Remove symbols from the number row by default (#964)
The number row option is changed into a ListPreference and controls whether the number row contains symbols or not.

Co-authored-by: Joey Schaff <j@jaoh.xyz>
2025-03-27 23:25:32 +01:00
Spike 3971f6243c Possible-key-values.md—Note syntax change for slider (#958)
The non-backward-compatible change to the XML should be mentioned as users must revise their layouts.
2025-03-27 22:50:34 +01:00
Jules Aguillon 6c40e0604a Add a preferred position for selectAll 2025-03-23 14:58:11 +01:00
Jules Aguillon 1d6a115ce4 Add link to Weblate on the README 2025-03-22 16:32:57 +01:00
Jules Aguillon 6717613b5e Fix label brightness not being applied
This is due to Paint.setColor overriding any alpha value set with
Paint.setAlpha. Bug was added in 653c598.
2025-03-22 12:25:59 +01:00
Joey Schaff 35219a458a Swapping the default placement of ! and | on the Colemak layout (#949)
Swapped placement of ! and | to make it more reasonable.
2025-03-22 11:46:52 +01:00
Jules Aguillon f0ebe45439 Release 1.31.0 (47)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2025-03-16 15:45:05 +01:00
Jules Aguillon 0ef36d52e1 Fix crash on API < 26 in settings 2025-03-16 15:44:02 +01:00
0skar2 08860eed17 Better material themes (#904) 2025-03-16 14:59:41 +01:00
Jules Aguillon b8bd3f7b0f Pull changes from Weblate 2025-03-16 14:47:59 +01:00
Jules Aguillon 60b01927ab Selection mode (#913)
* Selection mode: Space to cancel the selection

This adds the "selection mode", which is activated when text is selected
in the text box. The selection mode is exited when the selection is
cleared.

While the selection mode is activated, the Space and Esc keys are
modified into the "selection cancel" key, which remove the selection
without changing the text.
The space bar is otherwise easy to type by accident during a selection
and causes the selected text to be deleted.

* Selection mode: Move each ends of selection separately with slider

When the selection mode is activated, the space bar sliders change how
they affect the selection:

- The left side of the slider moves the left position of the selection.
  To shrink the selection from the left side, the slider must be
  activated by sliding to the left, extending the selection
  temporarilly, then by sliding to the right.

- The right side of the slider affects the right position if the
  selection.
2025-03-15 16:13:16 +01:00
Jules Aguillon 9cfeb0f0c2 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.
2025-03-10 23:41:51 +01:00
Spike 5e77fa84cf doc: Massage section on "Escape codes" (#912)
* Add introductory text to the tables

And mention characters that don't have escapes

* Turn tables around

Tables should be structured by what the user wants, not by what the code does.

* Address Julow review #1

- Merge tables, no matter which rule requires escaping; "in the usual way for XML" applies to both
- 3 escapes not mandatory removed from table to new ¶ below
- Found one more symbol → legend

* doc: Clarify escaping of comma and colon per #915
2025-03-08 12:11:54 +01:00
Jules Aguillon 06fbc83c9c sync_translations.py: Handle '\n' in store descriptions
These are added by Weblate.
2025-03-08 12:08:57 +01:00
Jules Aguillon a123810247 Change indentation of strings.xml files to match Weblate
This runs sync_translations.py, which also remove uneeded comments.
2025-03-08 12:05:35 +01:00
Jules Aguillon 906755b787 prefs: Add 'delete_word' and 'forward_delete_word' to extra keys
The gesture combination is mentioned. Preferred position are added.
2025-03-01 16:52:46 +01:00
Jules Aguillon 80c52460c7 Add 'delete_word' and 'forward_delete_word' keys
These keys are the equivalent of ctrl+backspace and ctrl+delete,
respectively.

They can be reached with Gesture+backspace and Gesture+delete
respectively.
2025-03-01 16:52:46 +01:00
dzaima 2b978dd2e0 APL and BQN layouts (#899)
* Add compact BQN layout

* Add compact APL layout
2025-02-28 00:47:49 +01:00
Jules Aguillon 55cb5f5315 Make key symbol smaller when 2 characters long or more
This was the case for string keys but not for macros or keys with custom
symbols.
2025-02-28 00:36:14 +01:00
Jules Aguillon b7d1508d7b Refactor: Remove StringWithSymbol
It's replaced with a macro containing one key.
2025-02-28 00:17:28 +01:00
Jules Aguillon 77b0c30728 cyrl_lynyertz_sr: Use the newer key syntax for ctrl mappings 2025-02-27 23:56:26 +01:00
Jules Aguillon 466e0b8218 KeyValue: Don't wrap keys into a macro when possible
Many kind of KeyValues don't need to be wrapped into a Macro to show a
specific symbol. This is especially useful as Macro keys are not
affected by modifiers.
The parser is changed to have a fast-path when a key value is not a
macro.
2025-02-27 23:53:42 +01:00
Jules Aguillon 75fdc2bfa9 Fix miscalculation of the bottom margin
'_marginBottom' might be uninitialized when used.
2025-02-27 23:20:49 +01:00
Jules Aguillon bee59aceaa Show a message in voice input chooser when empty
This avoids creating an empty dialog that appears as a mysterious white
rectangle.
2025-02-27 23:12:08 +01:00
Spike 92d50dd73f Clerical edits to "Possible values.md" (#907)
* Massage Intro

Start with definition, then use cases, then valid syntax.

Use "legend" rather than "symbol" for the visible legend on the keyboard

Rephrase to avoid "exhaustive". Other simplifications.

* Edit section "Modifiers"

Separate into two tables, each preceded by relevant introduction

* Shuffle sections

Retitle "Special keys"; as used in the Intro, this term refers to all the keywords in this file.

Put two contrasting sections together, add "In contrast," and reword.
2025-02-27 22:12:59 +01:00
Jules Aguillon ba05b2770e Fix crash due to empty strings in keys 2025-02-27 22:00:32 +01:00
Sergiy Stupar 44d1343b83 Update Ukrainian translation (#909) 2025-02-27 21:32:44 +01:00
Jules Aguillon ca25cc55f6 Apply compose sequences to String keys
This is mostly useful for characters that do not fit on a single 16-bit
char.
Shift sequences for 𝕨𝕩𝕗𝕘𝕤 are added for illustration.
2025-02-23 18:00:44 +01:00
Jules Aguillon 68be82a4f9 Macro keys (#878)
Add "macro" keys that behave as if a sequence of keys is typed.

Macro can be added to custom layouts or through the "Add keys to the
keyboard option". The syntax is:

    symbol:key1,key2,..

The symbol cannot contain a : character. 'key1', 'key2', etc.. are:

  - 'String with \' escaping'
    The key will generate the specified string.
  - keyevent:123
    The key will send a keyevent.
  - The name of any special key
2025-02-23 12:12:29 +01:00
Jules Aguillon 581b31bf99 ExtraKeysPreference: Allow title to span several lines
Some titles in the extra keys list are truncated and some information
are invisible.
2025-02-22 12:02:04 +01:00
Jules Aguillon 56903084f2 Remove Japanese from method.xml
This makes the keyboard incorrectly reports that it supports Japanese.
2025-02-15 11:55:26 +01:00
Jules Aguillon ac8fff599f prefs: Add key description for dead keys 2025-02-15 11:51:35 +01:00
Zitrone a22cc39a45 layouts/latn_bone.xml: improve (#760)
* layouts/latn_bone.xml: use new syntax and add most missing keys

new syntax: n/s/e/w/ne/nw/se/sw instead of key{1..8}

Some keys were missing keys according to the tests, this adds them in a
similar way to latn_neo2.
Only `switch_forward` didn't fit (because of the 0
at the bottom of the spacebar).

* layouts/latn_bone.xml: even better bone

- use number row to unclutter rest of keyboard
- use modmap for special shift functions of bone layout
- add missing loc characters
- use standard bottom bar
- add diacritics from the 3 dead key keys on bone
- 2 small keys left and right of the number row (don't fit all 6
  diacritics, so they leak onto the number keys)
- row 1 is full too, so the dead keys from the left of that row leak
  onto the keys there as well

open questions:
- should bone rely on the math layer or use modmap?
- possibility to combine diacritics?
2025-02-15 11:28:21 +01:00
Luke Videckis 7e86ca70cd misc changes to deva alt layout (#880)
* misc changes to deva alt layout

* add indication for numpad for discoverability

* change key* notation to c/nw/ne/sw/se notation
2025-02-15 11:09:27 +01:00
Edgars 33f8bf9dea Fix typo in Latvian translation (#902) 2025-02-15 10:56:14 +01:00
Jules Aguillon 653c598a1c Refactor: Compute appearance values before onDraw
This moves some computations that used to be done during onDraw into the
new Theme.Computed class. This also removes Paint objects from the Theme
class, making it data-only.

This is a requirement for making some keys render differently.
2025-02-09 14:09:45 +01:00
Jules Aguillon bd5c815a6f Refactor: Cleanup KeyValue flag declarations
Flag 'FLAGS_OFFSET << 8' was incorrectly mentionned as free and the
value bits were not taking free flags into account and were bigger than
expected.
2025-02-09 13:13:15 +01:00
Jules Aguillon 06b76d58c2 Fix the compose key being lockable
The compose key was lockable because it had the flag "FLAG_SPECIAL".
Without this flag, the key is not lockable with a long press.
2025-02-09 13:10:16 +01:00
dzaima 255d7f80d7 Add swipe actions on number row (#892) 2025-02-09 12:53:49 +01:00
Jules Aguillon d3753cc455 Add a glyph for cancelling the compose key 2025-02-08 23:16:18 +01:00
Jules Aguillon 96dabde7c8 Make the left and right keys symbol smaller
Prevents the arrow symbols from colliding with the compose key symbol as
the dpad key is very narrow.
2025-02-08 23:14:01 +01:00
Jules Aguillon bd1a72d01e Improve the compose key symbol
Make the symbol bolder and slimmer.
2025-02-08 23:14:01 +01:00
Jules Aguillon 87667a2438 Remove binding fn+shift = capslock
This made is hard to type fn+shift.
gesture+shift still locks shift.
2025-02-08 22:16:37 +01:00
dzaima 8f729bb90a Add embedded_number_row keyboard attribute (#891) 2025-02-08 21:52:41 +01:00
Jules Aguillon aaf0a9a249 Improve the check_layout CI and output
Change the format of check_layout.output to avoid adding any logs for
layouts that do not trigger any warning.

Fix the check_layout CI, which was broken since check_layout.py was
changed to take arguments.
2025-02-04 17:17:46 +01:00
Jules Aguillon ae9c2fa626 check_layout.py: Adjust Shift, Tab and Esc checks 2025-02-04 16:46:49 +01:00
Jules Aguillon 0061911ef3 Pressing the compose key exits the pending sequence
Allows stopping a compose sequence without typing anything.
This is also a more intuitive behavior rather than starting a new
sequence.
2025-02-04 15:50:17 +01:00
Jules Aguillon 6b40803fa4 prefs: Mention Fn combination for accessing extra keys 2025-02-04 15:35:06 +01:00
dzaima defc4bc0bd Even slower slide 2025-02-03 12:49:32 +01:00
Jules Aguillon e1191f3add Fix Enter key sending message in Discord
Set the flag FLAG_SOFT_KEYBOARD when sending key events stops Discord
from sending message when typing Enter.
The other values are the same that are sent when using sendDownUpKeyEvents().
2025-01-25 23:20:05 +01:00
Jules Aguillon 188c68279d Slightly less permissive swipe detection
This allows starting an anticircle gesture on a key with sliders on two
opposite sides.
2025-01-25 22:31:23 +01:00
tenextractor 3e3fd6ffda Maltese layout (#825) 2025-01-25 22:31:04 +01:00
solokot 81c493bff2 Update Russian translation (#884) 2025-01-25 22:24:01 +01:00
David Holdeman e97dbbc771 Add Mongolian layout (#882) 2025-01-25 22:23:39 +01:00
tenextractor 1f9e450dfa Azerbaijani layout (#827) 2025-01-18 12:00:51 +01:00
Jules Aguillon b93bc90242 Vibrate when a circle gesture ends
This is especially useful when discovering the circle gestures and to
feel when a gesture has been entered by accident.
2025-01-18 11:45:13 +01:00
Jules Aguillon c6908ec846 Stable ordering or extra keys
Extra keys were ordered randomly everytime the settings were changed.
Now, there's a single ordering for each combinations of options in the
settings.
2025-01-18 11:34:08 +01:00
Jules Aguillon 16c2be96b3 latn_qwerty_gb: Better position for ',.' 2025-01-18 11:26:14 +01:00
Lokesh Kumar d4a6bfe122 Add /release to .gitignore 2025-01-18 11:13:35 +01:00
Jules Aguillon e3f9341ed1 Refactor: KeyValue: Simplify StringWithSymbol
This removes the Complex key kind and class by making StringWithSymbol a
new kind of key.
2025-01-12 23:24:04 +01:00
Jules Aguillon 3ea5c8d6b7 Refactor: KeyValue: Don't require _payload.equals
Don't require _payload.equals to be implemented (correctly) and avoids
inconsistencies with _payload.compareTo, which is required by type.
2025-01-12 23:10:40 +01:00
Jules Aguillonandgoyalyashpal f7c5b74940 Improve layout WORKMAN (US)
Co-authored-by: goyalyashpal <yashpalgoyal1304@gmail.com>
2025-01-12 23:09:47 +01:00
Jules Aguillon 4351b3eb6e Add "paste" to the pin entry layout 2025-01-12 21:45:10 +01:00
Jules Aguillon bffc76907a Add cursor_up and cursor_down slider keys
Implement up and down cursor movement slider. This is not added to any
layout yet due to the undesirable behavior when moving the focus out of
the text box being edited.
2025-01-12 19:16:04 +01:00
Jules Aguillon ca05c073d2 Allow sliders in every directions
Sliders are no longer limited to the x dimension and can be placed in
corners or purely on the y dimension.
2025-01-11 17:13:58 +01:00
Jules Aguillon ddd2eebb0e Remove the 'slider="true"' attribute
Whether a key behaves as a slider is now purely defined by the key
values present on it.
2025-01-11 16:30:36 +01:00
Jules Aguillon 1783dcdb35 Refactor: Restrict sliders to new 'Slider' key kind
Setting 'slider="true"' on a key is no longer enough to make a slider,
the key must also be of kind 'Slider'.

Only the KeyValue that started sliding is now considered, they can be
generated with negative values. This allows keys that don't have the
complementary cursor movement key on the opposite direction.

This will help implement other kind of sliders as well as up/down
sliders.
2025-01-11 16:18:58 +01:00
Jules Aguillon 4f8b5fa6ce Refactor: Make KeyValue payload Comparable
and use 'toString()' instead of 'getSymbol()'.

This removes unecessary casts when computing symbols and comparing key
values. This will make adding other kind of keys easier.
2025-01-11 15:54:24 +01:00
Jules Aguillon c4e2b446e5 Make the space bar slider slightly less sensitive 2025-01-11 14:24:10 +01:00
Jules Aguillon 7b8f739400 More precise 1-position movement with space bar slider
Moving the cursor by 1 position is hard because the finger has to travel
far enough to activate the slider but then becomes very sensitive.

With this change, swiping on the space bar slider will immediately move
the cursor by 1 position but the slider will activate only if the finger
travel an other swiping distance.
2025-01-11 14:12:43 +01:00
Jules Aguillon a3023a7f18 Lock shift with a gesture
The circle gesture locks shift. It is also the case for the round-trip
gesture if shift is in a corner.
2025-01-03 16:08:13 +01:00
Jules Aguillonand@srikanban 6ce2195253 Add glyphs for zwj and zwnj
Co-authored-by: @srikanban
2025-01-03 15:50:30 +01:00
Jules Aguillon 9ba718694b Refactor: Make all glyph file names 3 character long
For easier reading.
2025-01-03 15:04:33 +01:00
Jules Aguillon 11c9bd850b Remove numpad keys from the main layout
When the numpad is visible, remove the digits and arithmetic symbols
from the main layout. Similarly to when the number row is added.
2025-01-03 12:33:48 +01:00
Jules Aguillon b120fa8f09 Allow 'loc' keys to be present several times 2025-01-03 12:29:44 +01:00
Jules Aguillon e8c20bf521 test: Add ComposeKeyTest 2025-01-03 11:43:38 +01:00
Jules Aguillon 56c62a005d Add zwj, zwnj, nbsp, nnbsp to extra keys preferences 2025-01-02 11:08:04 +01:00
tenextractor 115eda4084 Lithuanian QWERTY layout (#824) 2025-01-02 10:43:01 +01:00
Jules Aguillon 55060f656e Don't double tap for capslock after automatic capitalisation
Allow to more easily disable automatic capitalisation when it's
unwanted.
2024-12-31 12:17:22 +01:00
Jules Aguillon 42c23d3864 Refactor: Simplify double tap for capslock
This doesn't fix a bug but remove some tricky code. The shift key is no
longer different when the "double tap for capslock" option is on.
The handling of the option is moved to Pointer instead and becomes
simpler.
2024-12-31 12:17:22 +01:00
Jules Aguillon f64a0be6fa Fn: redo and pasteAsPlainText as undo and paste
Allows typing redo and pasteAsPlainText easily with Fn or the round-trip
gesture without adding them to the keyboard.
2024-12-31 12:17:22 +01:00
srikanban b43cbf77c2 Update kann_kannada.xml (#858)
* Update kann_kannada.xml

Added zwnj & zwj
1. zwnj used for writing non Kannada words or names like Leo Tolstoy as ಲಿಯೊ ಟಾಲ್‌ಸ್ಟಾಯ್ (also can be written as ಲಿಯೊ ಟಾಲ್ಸ್ಟಾಯ್)
2. zwj used for writing ಅರ್ಕ as ಅರ‍್ಕ

Removed unecessary symbols not present in Kannada language:
1. ∪ is a set symbol, a similar symbol is used in Carnatic music, unfortunately not present in Unicode
2. ॰ used only in Devanagari
3. • bullet, not a character or alphabet in Kannada (Can't remember why I added it, maybe because I use it personally in non markdown texts)

* Update kann_kannada.xml

Cleaning up more
1. Removed ※, not found in other kannada keyboards
2. Moved `:` & `;`  on the key so that its easier to swipe
2024-12-31 10:51:58 +01:00
Jules Aguillon 568b5a99f6 Add preferred position for undo/cut/copy/paste
These keys are placed on the downward direction on the z/x/c/v keys when
they are enabled in the settings.
2024-12-31 10:42:23 +01:00
Jules Aguillon 12d9e5eaf8 Update Shift mappings for math symbols
Shift is the "not" version of some math operators.
∋ is added to the math layout.
2024-12-29 11:29:58 +01:00
tenextractor e594915e80 Uzbek layout (#828) 2024-12-29 10:56:54 +01:00
Jagadeeshan S 78974b7453 Tamil layout: Shift and fn changes (#853)
Signed-off-by: Jagadeeshan S <jagadeeshanmsj@gmail.com>
2024-12-29 10:48:43 +01:00
Jules Aguillon 1a4e61557f Release 1.30.3 (46)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-12-29 10:31:02 +01:00
Jules Aguillon e13f58658d Fix crash in LayoutModifier 2024-12-29 10:20:18 +01:00
Jules Aguillon e4695e1ff4 Release 1.30.2 (45)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-12-29 00:29:46 +01:00
Jules Aguillon a9b78923c0 Drop support for Android 3 and 4
Support for Android 4 was broken for several releases and no one
noticed. The lowest supported version is now Android 5.
2024-12-29 00:27:44 +01:00
Jules Aguillon d9b5b36c27 Null check on the payload of KeyValue
The code expect that the payload is never null but there are now a lot
of public constructor functions for KeyValue that don't check for this
property.
2024-12-28 23:24:03 +01:00
Jules Aguillon 5b5d8c692e Fix status bar artifact on opens and closes
On API 30 to 34, the status bar changes color when the keyboard appears
and disappears. A ghost of the changed status bar is animated by the
same animation used for the keyboard, which is unexpected.
2024-12-28 23:06:06 +01:00
Jules Aguillon 926b99cbfe Refactor: Move code to LayoutModifier
Layout modifying functions are removed from Config to LayoutModifier as
static classes.
The two classes are (weakly) mutually dependent, the refactoring is
purely for the purpose of making shorter classes.

The only change is that 'modify_numpad' is changed to remove duplicated
code. This has the side effect of making the "double tap for caps lock"
option affect the shift key in the numpad.
2024-12-26 19:59:43 +01:00
Jules Aguillon 52af262e16 Remove labels for the anti-clockwise circle gesture
These labels are often unwanted and easily collide with other labels.
2024-12-26 18:46:12 +01:00
Jules Aguillon 0d5954cc3a Add Estonian to method.xml 2024-12-26 18:38:31 +01:00
Jules Aguillon 370f921bc3 Proper support for Android 15 edge-to-edge (#848)
The keyboard background now extends under the system bars and display
cutout on Android 15 but the keys do not.

The back and IME switching buttons that appear in the navigation bar require
special care to not overlap with the keyboard.

The launcher and settings activity are also fixed.
2024-12-26 18:29:19 +01:00
Jules Aguillon 57dbf3292f shell.nix: Emulator for Android 15 2024-12-26 13:43:24 +01:00
Jules Aguillon 3162a5abe6 Fix unecessary bottom margin on Android 14 2024-12-24 14:16:30 +01:00
Jules Aguillon 3e5e5a1979 Release 1.30.1 (44)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-12-24 01:17:47 +01:00
Jules Aguillon c13e7608fa Fix keyboard drawing behind nav bar on Android 15
Bug added in 038f693.
2024-12-24 01:10:41 +01:00
Jules Aguillon 2e9f69d58c Fix crash on devices with only unsupported languages
This only affected Android 12 and up.
2024-12-23 11:04:39 +01:00
Jules Aguillon 02cbe0632f Release 1.30.0 (43)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-12-22 01:49:34 +01:00
tenextractor e09abdd330 Estonian layout (#826) 2024-12-21 11:42:04 +01:00
Jules Aguillon 7aec194cdb Make Monet (Dark) theme darker (#803) 2024-12-20 00:32:05 +01:00
npnpatidar 3da696276e Hindi Phonetic Keyboard Layout addition (#837) 2024-12-19 23:33:28 +01:00
marciozomb13 cbfd53a36b Update pt-br translation (#839) 2024-12-19 23:08:31 +01:00
Jagadeeshan S ae50ff2a5c Added tamil layout (#833)
Signed-off-by: Jagadeeshan S <jagadeeshan.s@addverb.com>
2024-12-19 01:05:36 +01:00
Jules Aguillon 82e472ba46 Compose: Allow to force string final states
Appending the ':' character to a sequence result forces it to be a
string final state. This will cause a KeyValue lookup that would
normally not happen for single-character results.
This is useful to make Tamil letters smaller, even when they are the
result of a Shift.
2024-12-19 00:59:27 +01:00
Jules Aguillonandnpnpatidar bd2170e04b Add Modern Hindi and Sanskrit shift layer
Co-authored-by: npnpatidar <7de6dkm1@duck.com>
2024-12-19 00:52:22 +01:00
cuhsy a1dd0b8f2b Added Greek accent symbol button (#830)
Added Greek accent symbol button; a necessary key that should always be on the keyboard, as every word over 2 syllables contains one
2024-12-19 00:43:39 +01:00
Jules Aguillon 4a429357ef compose: Fix parsing of long sequences from json files
Sequences longer than two characters were not read correctly from json
files, creating conflicts and causing dropped sequences.

The detection of collision in sequences is also improved. Two colliding
sequences are removed.
2024-12-19 00:34:24 +01:00
Jules Aguillon 83c6e5d2ad Fix crash when opening the numpad 2024-12-18 22:55:12 +01:00
Jules Aguillonandgoyalyashpal d73b9d638e Add the WORKMAN (US) layout
Co-authored-by: goyalyashpal <yashpalgoyal1304@gmail.com>
2024-12-17 00:39:34 +01:00
Jules Aguillon f9c92007db launcher: Show output of animated gesture 2024-12-15 11:57:01 +01:00
Jules Aguillon 908bb93f82 launcher: Circle gesture animation 2024-12-15 11:56:56 +01:00
Jules Aguillon c59af9cf89 launcher: Round-trip gesture animation 2024-12-14 12:21:41 +01:00
tenextractor 855b5359be Welsh layout (#816) 2024-12-14 11:58:00 +01:00
Jules Aguillon e4a49d5256 Move numpad script maps to the compose system
This removes the Map_char interface, which required a lot of boilerplate
to use.
2024-12-11 11:24:50 +01:00
Jules Aguillon fe7906a194 test: Numpad scripts 2024-12-11 11:00:46 +01:00
Jules Aguillon 7c85870352 Fix empty text box when editing custom extra keys 2024-12-08 11:43:40 +01:00
Jules Aguillon 2060e6ab07 Add :keyevent key syntax
Allow to add keyevent keys to the keyboard. For example to add a
Play/Pause button:

    :keyevent symbol='⏯' flags='small':85
2024-12-08 11:41:50 +01:00
Jules Aguillon b3d28a65d1 Add support for de-BE, en-IN, fr-BE, ga, haw, ka-GE, kk, sq 2024-12-07 23:06:24 +01:00
Jules Aguillon baa16d742b Add support for Kannada
Add language support for Kannada, including a layout and numerals.
2024-12-07 22:29:15 +01:00
tenextractor ba02a3e305 Kazakh Cyrillic and Latin layouts (#819) 2024-12-07 22:12:27 +01:00
tenextractor 5e312bfe58 Hawaiian layout (#817) 2024-12-07 13:49:52 +01:00
tenextractor dacd9ca6df Irish layout (#818) 2024-12-07 13:20:41 +01:00
Zitrone 4eb1f8bd9e Add double grave accent (#779) 2024-12-07 13:16:43 +01:00
Jules Aguillon dc922b0258 Persist state of clipboard history checkbox 2024-12-06 00:10:05 +01:00
Jules Aguillon 91751afec8 method.xml: Move en-US to the top of the list
The first language of the list can be used as the default.
2024-12-05 23:38:37 +01:00
Jules Aguillon 30fb50d912 Fix typos in cyrillic compose sequences 2024-12-05 22:47:19 +01:00
tenextractor b872c53798 Czech diacritic QWERTZ layout (#814) 2024-12-05 21:58:41 +01:00
tenextractor 905a78a541 Albanian QWERTZ layout (#813) 2024-12-05 21:55:12 +01:00
Kxeo 9ac823be2d Add Georgian layouts (#809) 2024-12-05 00:35:20 +01:00
Jules AguillonandAnastázius Kaejatídarján de6ee1858b Arabic diacritics (#807)
Add arabic combining diacritics and make them accessible via Fn and Compose combos.

Co-authored-by: Anastázius Kaejatídarján <32847759+anaskaejdar@users.noreply.github.com>
2024-12-05 00:00:51 +01:00
PtitGNU bd49ff5432 Add Belgian layout (#780) 2024-12-04 23:58:31 +01:00
Jules Aguillon ae323affca Fix doc about ':char' keys 2024-12-04 23:02:57 +01:00
Jules Aguillon b6a8b4a285 Update comment in res/values/layouts.xml 2024-12-04 23:01:39 +01:00
Anastázius Kaejatídarján 6ea5901775 New and Improved Kurdish layouts (#773)
* improved symmetry and incorrect chars
* new persian-based keyboard for kurdish
2024-11-24 11:06:06 +01:00
Jules Aguillon 6b1551d103 layouts format: Add 'c' as a synonym for 'key0'
The attribute 'c' specifies the symbol in the center of a key, just like
'key0'. This adds consistency with the cardinal direction attributes and
is intended to make layouts more readable.
2024-11-24 10:56:19 +01:00
Jules Aguillon ed36098439 Use cardinal directions in the QWERTY (US) layout
Ease reading and modifying the QWERTY (US) layout, which is used as the
default source for the custom layout option.
2024-11-24 10:45:41 +01:00
Jules Aguillon 997b7be4c0 launcher: Animated vector describing swipe gesture
Replace the short video with an animated vector image that shows the
swipe gesture.

This is much lighter and reliable than the mp4 video, which failed to
play on many devices.

Source for the image of the key is in inkscape SVG format in srcs/res
and is converted to an android drawable when needed. The swipe animation
is hand-written.
2024-11-18 00:13:08 +01:00
Jules Aguillon 23097921cf Disable automatic Shift when pressing Compose 2024-11-17 11:10:21 +01:00
Jules Aguillon 237c4e2cc2 Automatic Shift should be disabled when pressing Ctrl
This was caused by a programming error.
2024-11-17 11:09:24 +01:00
Jules Aguillon 9bf0a20226 method.xml: Add Australia 2024-11-17 10:38:33 +01:00
Jules Aguillon 354c0a6f1c compose: Add digits to accent_dot_above 2024-11-16 12:23:25 +01:00
Jules Aguillon 46408572bc font: Use standard symbols for home and end
The glyphs are taken from DejaVuSans, the lines are thickened to improve
readability.
2024-11-16 12:08:36 +01:00
Jules Aguillon 0d51f7ea1e Don't apply Fn to space bar left and right
"home" and "end" on the spacebar slider are not useful.
2024-11-16 11:46:43 +01:00
DocJr90 fcbaa23ccf Add "scroll_lock" key (#800)
Added "scroll_lock" equates to KeyEvent.KEYCODE_SCROLL_LOCK
2024-11-11 16:28:59 +01:00
Jules Aguillon 70365b48d4 Readme: Update link and status for Calculator++ 2024-10-27 11:12:34 +01:00
Jules Aguillon 3c30e8248e Stable extra keys position when number row is added
Add the extra keys to the keyboard before the number row is added, as
that interferes with the "preferred pos" system.
2024-10-27 11:04:05 +01:00
Kalan Walmsley 73742a853f Rosé Pine Theme (#788) 2024-10-26 00:54:25 +02:00
solokot 24a6dd0f2c Update Russian translation (#784) 2024-10-19 11:39:40 +02:00
Anastázius Kaejatídarján 2233250e4d Slavonictajiki (#776)
new layouts for old slavonic and tajik languages
2024-10-05 23:58:42 +02:00
Jules AguillonandAnastazius Kaejatidarjan c4a88e4d5b Update compose sequences for Cyrillic
Mainly add sequences for the combining diacritics.

Co-authored-by: Anastazius Kaejatidarjan <zdarian@asu.edu>
2024-10-05 11:39:11 +02:00
Jules AguillonandAnastazius Kaejatidarjan cd2932bde1 Add slavonic combining diacritics
Co-authored-by: Anastazius Kaejatidarjan <zdarian@asu.edu>
2024-10-05 11:28:14 +02:00
Zitrone 6fae23a432 compose/accent_*.json: improvements (more accents) (#770)
compose/accent_*.json: improve/complete implementation
compose/shift.json: uppercase for superscript letters & characters without preapplied uppercase versions
2024-10-05 11:06:24 +02:00
Sergiy Stupar 6e2494ca0b Update Ukrainian translation (#781) 2024-10-05 10:31:39 +02:00
Jules AguillonandAnastazius Kaejatidarjan 8a6dc34b2c Add combining diacritics keys
Co-authored-by: Anastazius Kaejatidarjan <zdarian@asu.edu>
2024-10-04 01:09:51 +02:00
Jules Aguillon 9f0cf15d2e Add Fn layer and Compose sequences for Cyrillic 2024-09-29 22:47:57 +02:00
Jules Aguillon 700ec23bd4 Improve Ctrl key labels for Serbian Cyrillic layout
Add the ':char' syntax for defining character keys with a different
symbol.
This new kind of keys is used to implement Ctrl combinations in the
Serbian Cyrillic layout without showing latin letters while the Ctrl
modifier is activated.
2024-09-29 22:05:54 +02:00
Jules Aguillon fb93d841a5 refactoring: safer KeyboardData.load 2024-09-29 22:05:09 +02:00
Jules Aguillon a1be402638 Fix crash with complex keys 2024-09-29 21:59:07 +02: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
bokidori e309b76c0a Increase default label size (#747)
Change default label size to 1.15
2024-09-21 23:30:01 +02:00
Mostafa Khorashadi Zadeh 4d686a8836 Change the place of چ and ژ in Persian Keyboard Layout (#757)
* Change place of "چ" and "ژ"

* rollback unexpected changes
2024-09-21 11:33:59 +02:00
Zitrone b21bf3fffd Improve bone layout (#748)
* shell.nix: fix gradle error

error was:
> \> Task :compileDebugJavaWithJavac FAILED
> error: Source option 7 is no longer supported. Use 8 or later.
> error: Target option 7 is no longer supported. Use 8 or later.

fixed by overriding the jdk version for gradle to openjdk17

* layouts/latn_bone: fix layout

- fix alignment with tabs mess
- make like actual bone layout, instead of trying to fit it into a 10 key
  wide keyboard
  - fixes missing üäö
  - fix missing $
  - moves q and ß where they belong
  - remove all of the diacritic keys (they can be added through the
    settings as extra keys)
  - kept the number row extra keys integration into top row
  - kept the idea of compressing , and . into the swipe actions of the
    bottom row
  - kept the number keys as key4 in the layer4 positions (instead of
    moving them to a number row, which i also considered)
2024-09-19 23:57:26 +02:00
Spike 7454389f48 doc: Point to code for built-in bottom row and number row for use as starting points (#756) 2024-09-19 23:48:56 +02:00
Jules Aguillon b61e9db21e compose: Deduplicate end states
Make compose sequences ending in the same character to share the ending
state.
This reduce the compiled compose key data size from 33kB to 27kB.
2024-09-14 15:13:04 +02:00
Jules Aguillon 24d6b96ad7 Add Serbian to method.xml 2024-09-14 14:28:56 +02:00
Jules Aguillon 13ad05c0b0 doc: Mention switch_clipboard 2024-09-14 14:26:34 +02:00
Jules Aguillon a8e331c322 Define the Shift modifier using the compose mechanism 2024-09-10 22:50:39 +02:00
Jules Aguillon b600332595 Define the Fn modifier using the compose mechanism
This removes 100Kb from the app.
2024-09-10 22:43:40 +02:00
Jules Aguillon e734d1d0e2 compose: Allow c-style comments in json files
Useful to manager growing the collection of sequences.
2024-09-10 22:43:05 +02:00
Jules Aguillon c57ae83bfa Compose sequences can end in internal key names
This adds the '\n' and '\t' sequences to showcase the new feature.
2024-09-10 22:16:49 +02:00
Jules Aguillon c886a89b11 Update autocapitalisation on Enter 2024-09-10 21:53:52 +02:00
cknight828 231c08eb97 Add Japanese translation and layout (#743) 2024-09-08 15:46:38 +02:00
IYO-OYI 4eca9caec1 Update Korean translations (#737) 2024-08-24 23:43:42 +02:00
Spike bc8fef11f1 Modmap: Reorganize (#730)
Put new example in Examples section; put all overview material at start; use "modmap" for the modmap tag but "mapping" for the various subtags; set out each subtag separately; stop illustrating example mappings as complete modmap.
2024-08-18 21:49:30 +02:00
Jules Aguillon 4d0598a011 Fix crash when clipboard contains an image 2024-08-18 21:24:32 +02:00
Jules Aguillon 038f693cae Update target SDK version to 35 2024-07-28 23:07:05 +02:00
bokidori 72d88a5298 Map Fn+Cursor_move to home/end (#728)
Fn modifier switches cursor_left to home key, cursor_right to end key
2024-07-28 21:29:50 +02:00
Jules Aguillon bd50964651 Release 1.29.1 (42)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-07-27 12:35:59 +02:00
Adrian 105a5a2f33 Added supported key for avoiding the pain of auto-caps (#725) 2024-07-27 12:27:05 +02:00
bokidori 62530e98b9 Update cyrl_lynyertz_sr.xml (#727)
Include comprehensive ctrl modmap, enabling the use of ctrl modifier with Serbian Cyrillic keys. Remove clunky fn modmap previously used for just a few actions such as cut/copy/paste/etc.
2024-07-27 12:17:40 +02:00
Nils Brederlow b3d1a3fc1a Add new keyevent "menu" (#726)
* Update ExtraKeysPreference.java

add "menu" to array of extra keys

* Update KeyValue.java

add menu keyevent
2024-07-27 12:00:20 +02:00
Jules Aguillon 50a3c0f5bc Fix scaling for layouts with few columns
This was causing a slight padding on the right of 4 columns layouts,
which turned into a large padding when the number row was added.
2024-07-27 00:48:18 +02:00
Jules Aguillon d8fc4e80e3 Fix crash on Android 6
The call to getLanguageTag() introduced in 4629410 requires API 24.
2024-07-27 00:25:33 +02:00
Jules Aguillon 9d76227982 check_layout.py: Handle compass-point attributes 2024-07-26 00:10:54 +02:00
Jules Aguillon 3967fb8a9f doc: Document the <ctrl /> modmap 2024-07-26 00:04:57 +02:00
Jules Aguillon 29b4b665dc Allow Ctrl modmaps in layouts
The 'ctrl' modmap is different from the other modmaps as it also applies
the built-in Ctrl modifier to the resulting character, even if it was
first modified by the custom modmap.

For example, this will map Ctrl+в to Ctrl+V (not to v):

    <ctrl a="в" b="v"/>

This is intended to add keyboard shortcuts in non-latin layouts.

A caveat is that the latin character appears on the keyboard while Ctrl
is activated.
2024-07-25 23:40:58 +02:00
Jules Aguillon 35f35b27be Update ComposeKeyData
Outdated since 6c786f2
2024-07-25 23:23:53 +02:00
asivery bf2bec0d4b Revert "latn_qwerty_pl: Consistent placement for ó" (#714)
This reverts commit c5e9e3ff5c.
2024-07-25 23:22:38 +02:00
bokidori 6e1364b5c2 Add Serbian Latin QWERTY layout (#720)
Adds Serbian Latin QWERTY layout. Serbian language uses both Latin and Cyrillic as its official scripts, and this variant should cover anyone from Serbo-Croatian speaking group that uses Latin script.
2024-07-25 23:21:39 +02:00
bokidori acddd70435 Add Serbian Cyrillic layout (#718)
Adds Serbian Cyrillic layout. Modmap of Fn key allows for desktop-like easier access to actions such as selectAll, copy, paste, etc. This is because, unlike desktop systems, on mobile ctrl does not combine with cyrillic keys to perform actions.
2024-07-25 23:14:30 +02:00
bokidori 6c786f2a1a Update accent_circonflexe.json (#719)
Allow combining circumflex \u0302 for Cyrillic vowels, enabling users to express themselves accurately.

ја сам са̂м = I am alone
ја сам сам = I am am

да = yes
да̂ = give

код = at
ко̂д = code

Similar to #437 for aigo.
2024-07-25 23:12:55 +02:00
Jules Aguillon 2696f42144 Allow extending the compose key (#713)
This allows adding more compose sequences without modifying
en_US_UTF_8_Compose.pre.

This is done by grouping sequences files that should be merged together
into a directory. This also allows moving keysymdef.h into that
directory.
2024-07-21 23:37:07 +02:00
Reza Hosseinzadeh 84e10e0470 Improve zwnj/halfspace symbol and Persian layout (#711)
* Fix persian's half-space invisibility
* Add a 0.5 space before ظ in persian
* Change the place of چ in persian
* Change the width of backspace in persian
* Rename zwnj to halfspace in KeyValue.java and beng_provat layout
2024-07-21 13:37:01 +02:00
Jules Aguillon 65f4ffd15b method.xml: Remove overridesImplicitlyEnabledSubtype
This was hoped to fix a random layouts to be shown by default to users
of unsupported languages. This breaks language switching using the
system dialog.
2024-07-20 12:20:24 +02:00
Jules Aguillon deb611a0d2 Release 1.29.0 (41)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-07-15 00:21:59 +02:00
solokot 29f03d0e96 Update Russian translation (#702) 2024-07-14 16:55:34 +02:00
Jules Aguillon 4629410230 Fix unintended layout used for unsupported languages
The arabic layout was used as the default on devices where all the
installed languages are not supported by the keyboard. This is not
intended.
This is probably caused by 'getCurrentInputMethodSubtype' returning the
first layout in the list of disabled subtypes in alphabetical or
language tag order.
Re-ordering the subtypes in method.xml had no effect.

Setting 'overridesImplicitlyEnabledSubtype' in method.xml has no
measured effect.
2024-07-14 16:15:18 +02:00
Jules Aguillon b9526d918d Fix crash when using a different script layout
This might happen when using a layout of a different script than the
installed languages.
2024-07-14 15:52:24 +02:00
Mehmet Ali db3b021bfc Update Turkish Translations (#699) 2024-07-13 11:16:06 +02:00
Spike 3862f4d6ba doc: Re-add text for better overview (#697) 2024-07-10 22:47:58 +02:00
Edgars 555ede0fee Add missing Latvian translations (#698) 2024-07-09 19:36:05 +02:00
Spike 7b90294b57 Clerical edits related to locale_extra_keys (#696)
* Post-edit on Metadata

① Tell reader exactly what to type to disable locale_extra_keys, as with prev. bullet
② Values should be quoted
③ Rephrase one passive

* locale_extra_keys obviates 2nd example under modmap
2024-07-08 22:45:11 +02:00
Spike 69881e75c7 Update Spanish translations (#695) 2024-07-08 00:17:16 +02:00
Chasm Solacer 533e22ab4f Update Polish translation (#691) 2024-07-07 14:21:35 +02:00
Sergiy Stupar 46c86a05bd Update Ukrainian translation (#692) 2024-07-07 14:21:03 +02:00
Validbit e053d4b20c Update Czech strings.xml (#693) 2024-07-07 14:20:13 +02:00
polyctena c1e19a21d0 Update values-de/strings.xml (#694) 2024-07-07 14:19:33 +02:00
Jules Aguillon 3164215879 Add locale_extra_keys keyboard attribute
This attribute can be used to disable adding the extra keys from
method.xml.
2024-07-06 23:09:51 +02:00
Jules Aguillon 99367a9ec6 Update French translations 2024-07-06 22:42:56 +02:00
TadaCZE cd0f61da74 Add support for Android 12+ dynamic colors (#647) 2024-07-06 22:32:01 +02:00
Jules Aguillon ce57b5a4a2 Make the emoji and clipboard bottom rows consistent 2024-07-06 22:19:34 +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 6021a0b83c Fix crash with narrow layouts
The PreferredPos mechanism cause an out of bound access since 773147a.
2024-07-06 13:34:08 +02:00
solokot 89d0e6c063 Update Russian translation (#689) 2024-07-06 11:15:49 +02:00
Jules Aguillon a2eea76e70 doc: Clarify the possible key values 2024-07-03 00:35:25 +02:00
Sergiy Stupar 2cb5e67d1f Update Ukrainian translation (#682) 2024-06-30 14:02:56 +02:00
Jules Aguillon 3a371c354b doc: Correct mentions of gestures 2024-06-30 00:46:25 +02:00
Jules Aguillon bdb080657d Option to disable key repeat
Internally "key repeat" is reword into "long press" when the same
mechanism was used for both features.

The constraint that 'timeoutWhat' must be set to '-1' when no message is
expected has been lifted to simplify the code.
2024-06-30 00:24:39 +02:00
Jules Aguillon bf33230c26 settings: Reword "Key repeat" into "Long press"
The long press timeout is used for long press on keys that do not
repeat, for example the keyboard switching key.

This must be detached from the key repeat as it might be disableable in
the future and more keys might be longpressable.
2024-06-30 00:06:17 +02:00
Jules Aguillon 45fc18576e Validate more fields in custom layouts
This adds some errors:

- 'script' or 'numpad_script' is set an empty string.
- Multiple '<modmap>' elements.
- 'shift', 'width' and 'height' on every nodes that support them are
  clamped to a valid value.
2024-06-29 22:48:47 +02:00
Jules Aguillon b432f1d773 Set preferred position for Norwegian extra keys
This should make the QWERTY (US) layout look the same to Norwegian users
as the current latn_qwerty_no layout, allowing it to be changed.
2024-06-24 00:14:26 +02:00
Jules Aguillon 66cf643574 Remove 'loc' keys from latn_qwerty_us
Use the "preferred position" feature to place the removed keys
approximately where they were.
2024-06-24 00:07:56 +02:00
Spike ada3b5f3b7 doc: Where to put <modmap> (#666)
* Modmap: Where to put it; cancelling built-in mods (#665)

* Correct per Julow: not only Euro layouts

* Post-edit: Doesn't depend on "built-in" layout

* P-vs-L: Change "That is to say", sentence is not a restatement

* Discussion with Julow: Swipe graphic to HTML; at most one modmap

* Swipes: Center tables
2024-06-22 23:27:29 +02:00
Jules Aguillon 6405e5e8be Don't stop keyrepeat after a circle gesture
This was inconsistent with the anticircle and roundtrip gestures.
2024-06-22 23:10:43 +02:00
Sergiy Stupar 460f25317f Update Ukrainian translation (#670) 2024-06-16 22:39:44 +02:00
alotbsol555 81d1a1a831 Update German translations (#667) 2024-06-16 22:39:26 +02:00
Jules Aguillon c01b289eaf Don't change input view when configuration changes
This doesn't seem necessary and won't play well with eventual keys that
change the configuration.
2024-06-16 22:20:14 +02:00
Jules Aguillon a7b79022e5 Launcher activity: Don't consume events in text field
Allow the keybindings to have an effect in the "Try here" text field.
2024-06-16 22:19:27 +02:00
Jules Aguillon bad2e8c237 Refactor: Remove unecessary view in emoji pane 2024-06-16 22:19:20 +02:00
solokot b7be19dc1f Update Russian translation (#656) 2024-06-11 00:54:19 +02:00
Jules Aguillon b5a96dc4dc Option to tweak or disable the circle gesture 2024-06-09 14:25:19 +02:00
Jules Aguillon 944ed32a37 Use preferred dir when placing a key next to an other 2024-06-09 14:03:02 +02:00
Jules Aguillon 773147ab9c Automatic placement of f11/f12 placeholders 2024-06-09 13:55:27 +02:00
Jules Aguillon 52805d9745 Allow to remove keys Tab and Esc 2024-06-09 13:18:25 +02:00
Jules Aguillon 8d793da6b6 Refactor: Remove the KeyModifier cache 2024-06-09 12:49:23 +02:00
Jules Aguillon 91ace060bc Move diacritics mapping to the compose state machine
This replaces the switch cases in KeyModifier.java with JSON files, one
for each diacritic.

The number of states increases from 6727 to 7377. The apk size slightly
decreases (around 3kb).
2024-06-09 11:53:17 +02:00
Jules Aguillon ecac6a77f8 compose: Compile several starting states
Sequences from several files are no longer merged but compiled to
separate starting states.

The plan is to use that to represent the diacritics.
2024-06-09 11:52:17 +02:00
Jules Aguillon a886f6eede compose: Fix misbehaving due to encoding errors
Encoding errors in the compose data compiler due to:
- 'UTF-16' adds a BOM, use 'UTF-16-LE' instead
- 'str.encode' returns a byte array, use 'array' to have a 16-bit char
  array.
2024-06-09 10:35:38 +02:00
Jules Aguillon 1197ce36b4 Update check_layout.output 2024-06-08 22:47:55 +02:00
Spike 8b99c04a21 Flesh out custom layout doc (#651) 2024-06-08 22:22:46 +02:00
Jules Aguillon 6ac973cfda Don't cap indication length
This was inadvertently changed when the anti-circle gesture was
introduced, which use the same rendering logic.
2024-06-06 00:30:22 +02:00
Jules Aguillonand@ZX-Commodore-ST c5e9e3ff5c latn_qwerty_pl: Consistent placement for ó
Co-authored-by: @ZX-Commodore-ST
2024-06-05 23:45:03 +02:00
Jules Aguillon cf1aaa3bdf Add compose sequences for Greek, Cyrillic, Hebrew and more
Parse key names from keysymdef.h, which is distributed with Xorg. The
Greek, Cyrillic and Hebrew sequences referenced these keysyms.

This increases the number of sequences from 2043 to 2668.
2024-05-29 15:56:08 +02:00
Jules Aguillon 39b3f50aa3 Allow compose sequence ending with more symbols
Change the compose state machine definition to allow final states that
are wider than 16-bits.

This increases the number of sequences that can be used from
en_US_UTF_8_Compose.pre from 2013 to 2043 (of 3201).
2024-05-29 15:02:08 +02:00
Jules Aguillon f7f1d85f80 Release 1.28.0
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-05-29 14:08:27 +02:00
Jules Aguillon 5d2eb35574 Increase target SDK to 34 2024-05-29 14:04:14 +02:00
Jules Aguillon 93d58571cc Fix overflow due to navigation on the right and cutouts (#641)
Take display cutouts and navigation bars when computing the keyboard
width on SDK >= 30.
2024-05-29 12:00:41 +02:00
Jules Aguillon 1a290f96f2 Configure anticircle gesture per-key (#644)
This adds the new 'anticircle' attribute to layouts '<key>' elements
that configure the key to send when doing a anti-clockwise circle
gesture on it.

Labels are drawn the same way as indication.

Updated docs.
2024-05-29 11:59:54 +02:00
Jules Aguillon 304375268d Fix uninitialized bottom_row when editing custom layout
This happen when opening the settings from the launcher activity without
ever opening the keyboard.

To remove this bug entirely, the KeyboardData.init method is removed,
the pieces needing initialization are now cached in Config.
2024-05-29 11:56:26 +02:00
Jules Aguillon 9d89297c15 Fix off-by-one error in 1-row layouts 2024-05-27 23:59:09 +02:00
Jules Aguillon 46f3b41393 Support the nnbsp character 2024-05-26 00:49:15 +02:00
Jules Aguillon bea2e6cd1f Update check_layout.output
Was outdated since previous commit
2024-05-26 00:20:36 +02:00
Jules Aguillon abf36e5d56 Add missing characters to hang_dubeolsik_kr 2024-05-25 23:56:35 +02:00
JapanYoshi c9b6380ed0 Add custom layout documentation in doc/ (#643) 2024-05-25 22:22:42 +02:00
Jules Aguillon 4906f8105f Circle and round trip gestures (#640)
This implements clockwise/anticlockwise circle and round trip gestures
inspired by Messagease.

The circle gestures start after a small threshold to avoid making the
regular swipe too hard to aim.

The gestures do:

- circle: The center symbol with Shift applied, with a fallback on Fn
- round trip: Same as the circle gesture but applied to a side symbol
- anticlockwise circle: Nothing currently. It is intended to be made
  configurable per-layout in the future.

The new Gesture class keeps track of what the pointer is doing while it moves
on a key. It replaces the 'selected_direction' integer.
2024-05-25 21:19:44 +02:00
NACAMURA Mitsuhiro 96fc4003f1 Update NixOS wiki link (#633) 2024-05-12 10:53:04 +02:00
Quinn Cypher a91332a903 Pull the emoji list from unicode.org (#612)
- Removing unused information (names and descriptions) from the Emoji class
- Creating a Gradle task that generates a more efficient res/raw/emojis.txt file from the most recent Unicode standard
- Saving recently used emoji preferences as emoji values rather than names
- Migrating old user preferences to the new system
2024-05-08 13:02:19 +02:00
Spike 53e04d5784 Compass-point synonyms for edge keys in layouts (#628) 2024-05-08 12:51:11 +02:00
alotbsol555 c7d33356bc Add settings button to launcher app (#629) 2024-05-05 11:22:34 +02:00
Jules Aguillon 69ab869079 Hangul support (#595)
* Hangul support

This works with two new kinds of keys (Hangul_initial and Hangul_medial)
that carry a precomposed hangul syllable and act as modifiers.

The hangul syllables are composed algorithmically.

* Add shift layer to Dubeolsik layout
2024-05-02 20:52:18 +02:00
Jules Aguillon d96414c6c6 Allow the newline character '\n' in layouts 2024-05-02 19:37:18 +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
alotbsol555 82e0840568 allow for <fn ...> in <modmap> (#626) 2024-05-02 12:09:39 +02:00
Jules Aguillon c7ed2bcae9 Clear cache when changing layout
Due to the modmap, the cache must be cleared when switching layout to or
from a layout that contain a modmap.

This is broken since 3f6b6fd23, which moves the modmap handling into
KeyModifier.
2024-05-02 12:06:15 +02:00
JapanYoshi 5386541db3 Add more accented characters to KeyModifier.java (#622) 2024-04-25 13:24:52 +02:00
复予 94b2ded843 Update Simplified Chinese translation (#617) 2024-04-24 13:31:29 +02:00
JapanYoshi 2684d1f041 Turkish: Correct shift behavior for ı and i (#615) 2024-04-19 14:38:35 +02:00
Jules Aguillon 78f85e52a2 Fix space key without a symbol
The symbol on the space key was accidentally lost in be97364 when the
string "\r" (Java's only way to write "\x0D") was not replaced by
"\xE00D".
2024-04-03 23:59:18 +02:00
Tomasz Cielecki 5e3a3f894b Add Danish layout (#606) 2024-04-03 23:46:39 +02:00
Jules Aguillon 3f6b6fd232 refactor: Apply the modmap in KeyModifier
This makes possible to apply other modifiers to mapped keys and ensures
that the modmap really override the shift key behavior.
2024-04-01 23:01:21 +02:00
Jules Aguillon f17afba7be sync_translations: Fix store descrs not updated 2024-03-24 21:37:41 +01:00
marciozomb13 7e9d8c73df Update pt-BR translations (#598) 2024-03-24 21:36:55 +01:00
Benson Muite b22b49d3e6 launcher: Grammar fixes (#599) 2024-03-24 21:36:18 +01:00
Lev Brekalov 7c3286078b Add Shaw Imperial layout (#592) 2024-03-23 00:06:23 +01: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 0549c6c8a1 Fix potential out of bounds access
The preferred pos mechanism could cause an out of bounds access on 1 row
layouts.
2024-03-16 23:42:37 +01:00
Jules Aguillon e74b45c2d6 Move fastlane metadata into fastlane/metadata/android 2024-03-16 23:37:38 +01:00
solokot 1cbaa7106c Update Russian translation (#588) 2024-03-14 00:37:37 +01:00
Jules Aguillon fe0f82436a Improve the QWERTY (Slovak) layout
The grid layout was not likeable.
2024-03-11 20:21:26 +01:00
Jules Aguillon 5c19140609 refactor: Pointers: Flag for sliding state 2024-03-11 00:38:37 +01:00
Jules Aguillon 47e2009da4 refactor: Add latched flag to Pointers 2024-03-11 00:29:12 +01:00
Jules Aguillon b33bcd8865 refactor: Use internal flags in Pointers
'FLAG_LOCKED' and 'FLAG_FAKE_PTR' are only used within Pointers.
Define new flags in Pointers and remove these from KeyValue. Also allows
to define new flags.
2024-03-11 00:24:25 +01:00
Spike c41a098924 Update Spanish translations (#586) 2024-03-10 19:31:58 +01:00
Quinn Cypher 8cd868ba76 Update to Unicode Emoji v15.1 (#583) 2024-03-09 11:37:15 +01:00
Validbit 07f9c1ffaa Update cs strings.xml (#582) 2024-03-07 19:36:48 +01:00
Edgars 9a07149efc Update Latvian translations (#580) 2024-03-04 19:35:28 +01:00
Jules Aguillon 0594127575 metadata: Remove metedata without a short_description
It is mandatory for Google Play.
2024-03-04 00:57:23 +01:00
Jules Aguillon a9f9bbec19 Revert renaming metadata locale directories
Metadata directories were renamed while adding store descriptions into
strings files for simplicity.

This interferes with releases so is released.
An hardcoded lookup table is used instead.
2024-03-04 00:57:23 +01:00
polyctena 35d1ebeab5 Update German strings.xml (#579) 2024-03-03 23:25:54 +01:00
Jules Aguillon 0739c6bd2c Release 1.27.0 (39)
Check layouts / Generated files (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-03-03 23:19:02 +01:00
Yogesh-Bandyogesh-b a1de69bcc4 Gujarati phonetic layout (#562)
added shift modifier characters
Add support for gujarati numerals

Co-authored-by: yogesh-b <yogesh@improwised.com>
2024-03-03 23:12:52 +01:00
Jules Aguillon 5e5937b0f4 Fix auto-capitalisation disabling locked shift
Shift locked via the "caps lock" key use the "fake pointer" mechanism
that is also used by auto-capitalisation.

Make sure that unlatching a fake pointer do not disabled a locked
modifier.

The implementation is moved into the Pointers class for a safer API and
easier implementation.
2024-03-03 17:14:01 +01:00
Chasm Solacer ce38a4f151 Update pl/strings.xml (#578) 2024-03-03 01:06:07 +01:00
Jules Aguillon 0e0c761a92 Add QWERTY (Slovak) layout
The original author is @sejkm in https://github.com/Julow/Unexpected-Keyboard/issues/573
2024-03-02 20:39:22 +01:00
Jules Aguillon 940cf0deb8 compose: Parse json files and fix edge cases
There's no json file yet, this was part of an experiment.

Add a missing escape rule and detect colliding sequences.
2024-03-02 19:12:37 +01:00
Jules Aguillon c2d5b14261 compose: Add a README.md
Mention the source of the sequences files.
2024-03-02 19:11:41 +01:00
Jules Aguillon ebda7b2c3e Improve the AZERTY layout
Add éèàç directly to the layout, which removes the corresponding dead
keys.

Remove the requirement for ù and ÿ from method.xml, which are extremely
rare and can be typed via the compose key.
2024-03-02 17:42:57 +01:00
Jules Aguillon 39f6d294fb translations: Remove outdated store descriptions 2024-03-02 17:22:22 +01:00
Jules Aguillon 8b5d971fb5 Modify the number row according to the numpad script
The same way as the numpad is modified.
2024-02-28 23:19:50 +01:00
Jules Aguillon 8c7559d8f6 Fix localized numpad outputing wester arabic numbers
The number keys were constructed in the wrong way: the rendered symbol
was correct but not the underlying character that is typed.
2024-02-28 20:42:52 +01:00
Jules Aguillon d7e5040873 method.xml: Add en-CA and fr-CA
Without this, the system might choose en-GB and fr-CH.
This makes them more similar to en-US and fr-FR (without € in extra keys).
2024-02-24 11:54:46 +01:00
Jules Aguillon b29a344cd0 Remove € from en-GB extra keys 2024-02-22 19:34:23 +01:00
Jules Aguillon b8e673b614 Ensure the layout contain the config key
Without the config key, the user risk being locked in a custom layout
that lacks an escape key like 'switch_numpad', 'change_method', etc..
2024-02-22 19:10:31 +01:00
Jules Aguillon bae82d6ed8 Add FUNDING.yml
Thanks to everyone considering funding the development of the app.
2024-02-21 19:07:34 +01:00
Jules Aguillon f913051dca Relicense layout definitions under CC0 (#528)
* Relicense layouts under CC0

Layout definitions are licensed differently from the rest of the
application source code to allow use in other projects related or
unrelated to Unexpected Keyboard.

Some layouts are not re-licensed and their original copyright continues
to apply. The copyright notice is added at the top of the files.

* Contributing: Mention layout licensing
2024-02-18 23:37:26 +01:00
Jules Aguillon dac702ad0b CI: Improve layout and store description checks (#565)
* CI: Run 'check_layout.py'

Ensures that 'check_layout.output' is not outdated.
Also, update it.

* CI: Check new store descriptions

When a store description is added, 'python3 sync_translations.py' leaves
an untracked file that is not checked.

This makes sure that untracked store descriptions are noticed in CI.
2024-02-18 17:55:41 +01:00
matthiakl f2f6ef0627 neo2: Update bottom row (#560) 2024-02-18 17:10:46 +01:00
Sergiy Stupar 6389d58553 Update Ukrainian translation (#561) 2024-02-18 17:08:56 +01:00
Jules Aguillon e40558677e Allow to remove the compose key in the settings 2024-02-17 23:28:31 +01:00
Jules Aguillon ae270b36f4 Add the compose key on alternate layouts
Though it is not useful in the greek-math layout, it could give ideas
for new sequences.
2024-02-17 23:28:31 +01:00
Jules Aguillon 146d520325 compose: Grey out keys that are not in sequence
Keys that are not in the pending compose sequence are greyed out with
the new 'FLAG_GREYED' flag.
2024-02-17 23:28:31 +01:00
Jules Aguillon 065d9520e5 Dim secondary keys in every themes
Themes do not dim secondary keys the same way due to the "offset"
mechanism. Instead, use a ratio that is the same for every themes.

It's still possible to override this ratio per theme.
2024-02-17 23:28:31 +01:00
Jules Aguillon bb60ed9b13 Fix KeyValue flags layout
The kind field wasn't large enough to hold the new Compose_pending kind.
The flags field is reduced in size by removing a free spot.

The FLAGS_BITS mask is defined in a safer way.
2024-02-17 23:28:31 +01:00
Jules Aguillon d56e4d129e compose: Add glyph 2024-02-17 23:28:31 +01:00
Jules Aguillon e9f734b6cc compose: Don't remove keys not in sequence
Keys that are not part of any possible sequences are now dimmed and
still usable instead of being removed, which felt weird.
2024-02-17 23:28:31 +01:00
Jules Aguillon 63e7ac2e94 compose: Add X11 compose sequences
compile.py implements a parser for X11's Compose.pre files. A lot of
code is necessary to interpret character names but thanksfully, the name
of most characters is contained in the file.

The state machine is compiled into two char arrays which unfortunately
requires an expensive initialisation and allocation.
2024-02-17 23:28:31 +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
Ryan Gibb 38deb810f9 Add QWERTY GB layout (#557)
Adapted from latn_qwerty_us

* Make it the default layout for en-GB
2024-02-16 21:09:28 +01:00
vedamanavi d8beda411d Improve latn_qwerty_tly.xml (#549)
Removing "g" as it was used two times as a main key.
shift="0.5" added
2024-02-14 22:55:56 +01:00
Jules Aguillon d96577963e Don't invert the pin entry layout
The pin entry layout shouldn't be inverted as the letter indications
would be meaningless and the order would be opposite to what the option
specifies.

The enter and action key are swapped as the automatic swapping is also
removed.
2024-02-14 22:52:25 +01:00
BogdanLata f369b5d90b Update README.md (#553)
I made more clearer how to use the keys
2024-02-11 20:54:35 +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 d5676d683f Fix compatibility with Android 3.0
Incompatible APIs were used in the custom layouts and the extra keys
options.

Add @TargetApi annotations to help catch similar issues in the future
with the help of 'gradle lint'.
2024-02-10 17:33:42 +01:00
Jules Aguillon 332413ed3c Drop support for Android versions below 3.0
Android 3.0 (API level 11) was released in Feb 2011.

These versions were already unsupported due to unavoidable calls to:
- MotionEvent.getActionMasked() (API 8)

And avoidable calls to:
- SharedPreferences.Editor.putStringSet() (API 11)
2024-02-10 17:24:15 +01:00
RetrogisusDEV 93d8af4505 Custom border settings (#524) 2024-02-10 11:38:46 +01:00
Mehmet Ali f74e5a9f73 Update Turkish translations (#550) 2024-02-10 00:43:34 +01:00
ErrrorMaxx 6513c21144 contributing: Fix typo (#551) 2024-02-10 00:42:35 +01:00
Rapha 79aec5b9bc CI: Update to node.js-20 (#546) 2024-02-07 00:01:54 +01:00
Jules Aguillon be053b082c Add more Russian vowels combined with acute accent 2024-02-06 23:32:58 +01:00
Jules Aguillon 5ce89d1b4b Move store descriptions into strings files
This makes translation easier as there's a single file to edit at.
Existing short and full descriptions are conserved.

sync_translations.py takes care of updating the metadata files.

The metadata directories are renamed to match the language codes used in `res/`.

Contributing guidelines are updated accordingly.
2024-02-06 23:11:14 +01:00
vedamanavi 82a9774f5a Update method.xml to support arab_hamvaj_tly (#547) 2024-02-06 22:24:43 +01:00
Jules Aguillon 5d1a503210 Release 1.26.0 (38)
Check layouts / check-layouts (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-02-04 23:24:34 +01:00
vedamanavi d1aa59768d Create layout arabic-hamvaj-tly (#542) 2024-02-04 23:18:33 +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
vedamanavi 3adf95a4c9 Add language support for Talysh New Latin (#534) 2024-01-31 01:06:47 +01:00
vedamanavi 44f39059e4 Add layout QWERTY (Talysh New Latin) (#529) 2024-01-28 23:49:27 +01:00
Jules Aguillon bbc6226839 Redefined the key margin options in percent
Define the key margin options relative to the baseline dimensions of
keys. This removes the doubling of the horizontal margin in landscape
mode.
2024-01-28 19:38:29 +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 fb27f8d36f check_layout: Warn against whitespaces and "loc" 2024-01-22 20:55:36 +01:00
Jules Aguillon 5beacf32b7 Add Russian vowels combined with the acute accent 2024-01-21 19:47:03 +01:00
Jules Aguillon ad7314a016 Move layout definitions into srcs/layouts
This separates the layout definitions from the special layouts
(bottom_row, greekmath) and other unrelated files (method, settings).

This is also a more intuitive location for layouts and make the resource
directory easier to navigate.

Under the hood, layouts are copied back into
build/generated-resources/xml.
2024-01-21 16:34:49 +01:00
marciozomb13 bef29da3de Update pt-br translation (#527)
Update translation pt-br
2024-01-21 16:10:26 +01:00
RetrogisusDEV a55506e607 Light and dark themes for the launcher and settings 2024-01-20 22:37:51 +01:00
abb128 b3dcd61c28 Add <queries> element for detecting IMEs (#526)
To detect voice IMEs, Unexpected Keyboard calls InputMethodManager.getEnabledInputMethodList

Internally, this method eventually calls a method that returns a filtered list of packages that may not include the installed voice IME, and thus Unexpected Keyboard unexpectedly claims no voice input is installed because it can't see it.

The fix is to explicitly state in the manifest that we want to query for other IMEs, based on https://developer.android.com/training/package-visibility/declaring

This is not an issue with Google's voice input or other preinstalled voice inputs because they usually have android:forceQueryable=true, but this is an issue with third-party voice inputs such as FUTO Voice Input. Launching the voice input app after activating the keyboard also usually makes the package visible, so a consistent way to replicate this issue on modern Android is to reboot the device and try triggering voice input from the keyboard
2024-01-18 23:42:29 +01:00
Sergiy Stupar 9257bf7392 Add Ukrainian translation (#525) 2024-01-18 22:44:22 +01:00
Jules Aguillon 95bd9312a7 Allow hidding the keyboard switching key
The keyboard switching key is now selected by default in the Extra Keys
option and can be deselected.
2024-01-15 23:26:40 +01:00
Jules Aguillon 0a86f9ab01 Always show the keyboard switching key
Android's shouldOfferSwitchingToNextInputMethod() method might return
false when an other IME is installed, perhaps when the other IME doesn't
specify android:supportsSwitchingToNextInputMethod="true".
2024-01-15 23:15:16 +01:00
Jules Aguillon 70d777253c Use switchToNextInputMethod instead of switchToPreviousInputMethod
This is warranted by the API.
2024-01-15 22:10:11 +01:00
Jules Aguillon d7fa5ffa9a Refactor: Clearer names for CHANGE_METHOD* events
The keys are not renamed to retain compatibility.
2024-01-15 22:09:15 +01:00
Jules Aguillon b114c78bf1 Refactor: Keyboard2View: Take layout id attr
Removes EmojiBottomRow.
2024-01-13 23:22:26 +01:00
Jules Aguillon eddf9c6c11 Refactor: New namespace for preference classes 2024-01-13 20:59:05 +01:00
Jules Aguillon 148f3dfc05 prefs: Show custom layout names if provided
Show the name of custom layouts in the list if it's provided using the
`name` attribute.
This should make managing several custom layouts easier.
2024-01-10 23:39:19 +01:00
Jules Aguillon 6725d3057b check_layout: Stronger bottom row key check 2024-01-10 23:00:40 +01:00
Jules Aguillon cf9fd3a0db CI: Fix debug build due to missing release keystore 2024-01-10 00:34:19 +01:00
Jules Aguillon 329a35e7d3 Fix layouts containing empty keys
This results in a key being the empty string and do not trigger an
error:

    key1="\"

Layouts are fixed and check_layout now checks for this case.
2024-01-10 00:28:21 +01:00
Jules Aguillon b319356a08 Fix crash on shift with empty keys
Tapping shift might call `Utils.capitalize_string` on some symbols
(notably custom keys), which crashes on empty string.

This also happens on builtin layouts with `key1="\"`.
2024-01-10 00:17:09 +01:00
Jules Aguillon 73267d68fb Revert "Remove the vibration settings"
This reverts commits ef03dfed5c and
ff01678ba6.

The "vibration duration" slider is bought back.
The "vibration enabled" option is replaced by "custom vibration", which switch between the system haptic feedback or the custom vibration.

The slider is greyed when "custom vibration" is unchecked and is
allowed to have a value of 0 to disable vibrations within the app.

The intermediate values "light", "medium" and "strong" are removed and
no migration of the setting is made.
2024-01-09 00:43:28 +01:00
Jules Aguillon 3f2f3177da gradle: Enforce release build is signed 2024-01-08 22:49:59 +01:00
Jules Aguillon e26e1d112c gradle: Name outputs after the application ID 2024-01-08 22:47:21 +01:00
Diego Puma 0005eb2dd5 Update Spanish translations (#517) 2024-01-07 02:18:40 +01:00
Jules Aguillon 8b2c7d9337 Release 1.25.0 (37)
Check layouts / check-layouts (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Make Apk CI / Build-Apk (push) Has been cancelled
2024-01-03 01:07:22 +01:00
Jules Aguillon 409362ddb4 launcher: Remove intro video when not supported
Previously, this would trigger an error popup and make the activity
unresponsive.
2024-01-03 00:48:26 +01:00
Jules Aguillon c524caa6f1 Remove unsupported API readAllBytes 2024-01-01 21:04:54 +01:00
Jules Aguillon 7caf60c93b README: Display the intro video 2023-12-31 20:19:58 +01:00
Jules Aguillon 49a6a30773 Add an introduction video in the launcher activity
A video is more intuitive than a written description and doesn't need
translations.
2023-12-31 13:18:15 +01:00
Jules Aguillon 4a5a125aea Bring the voice IME chooser with a long press 2023-12-30 01:24:21 +01:00
Jules Aguillon 51a41ec90a Voice IME chooser popup
Bring a popup for choosing the voice IME when the voice key is pressed
for the first time or the list of voice IMEs installed on the device
change.

A preference stores the last selected IME and the last seen list of
IMEs.
2023-12-30 00:56:55 +01:00
Jules Aguillon 7e7a5e4425 Separate arabic layouts with hindu or arabic numerals
This reverts the Tusinian layout (1af4e45) and instead introduce a new
arabic PC layout with arabic numbers.

Layouts are renamed:
- arab_pc => arab_pc_hindu
- arab_pc_tn => arab_pc
2023-12-26 17:16:29 +01:00
Jules Aguillon 9ff8179d49 Add layout attribute 'numpad_script'
This new attribute is now used instead of 'script' for modifying the
numpad according to the selected layout's script.
If not provided, it defaults to the value of 'script'.
2023-12-26 17:05:51 +01:00
Jules Aguillon 1af4e45117 Add Tunisian layout
It is a copy of the 'arab_pc' layout with arabic digits.
Also, fix the default layout for arabic.
2023-12-21 21:45:56 +01:00
Jules Aguillon 2db4ae3730 Fix the number row showing up on top of pinentry
This wasn't intended and was caused by the "current_layout_unmodified"
optimisation.
2023-12-21 20:59:30 +01:00
polyctena 2aecbca9ac Update strings.xml (#505) 2023-12-20 21:27:19 +01:00
Validbit dce7e2b9d9 Update strings.xml (cz_CS) (#506) 2023-12-20 21:26:46 +01:00
1 7c12aa610c Update Turkish translations (#501)
Turkish translate update
2023-12-18 19:38:06 +01:00
Chasm Solacer 294ebee6f1 Update Polish translations (#502) 2023-12-18 19:35:56 +01:00
Edgars bd1afd2c3c Update Latvian translations (#503) 2023-12-18 19:34:15 +01:00
Jules Aguillon 44f6908411 Update French translation 2023-12-17 20:25:43 +01:00
RetrogisusDEV df04eae85f Launcher activity: Add "Select keyboard" button 2023-12-17 20:10:39 +01:00
Jules Aguillon d7c230e173 prefs: Use QWERTY (US) as the default custom layout
This layout definition contains some documentation and is a better
default than no text.
2023-12-17 12:41:19 +01:00
Jules Aguillon 478d8082f4 Improve layout parsing errors
Add location information to all error and improve "expected tag" errors.
2023-12-17 12:12:23 +01:00
Jules Aguillon 7af6adcf11 prefs: Report errors while editing custom layouts
Errors are obtained by running the parser, validation is throttle to
when the user stops editing for a second.
2023-12-17 11:58:41 +01:00
Jules Aguillon dd327cc812 prefs: Render line numbers in custom layout input box
Line numbers will help reporting errors. Also, disable line breaking to
improve readability.
2023-12-10 19:44:50 +01:00
Jules Aguillon d073523125 shell.nix: Update dependencies and add Gradle
Update OpenJDK to version 17, Android build tools to 33.0.1 and platform to 33.
These are required to build with Gradle.

Add Gradle to the environment, which must be wrapped to fix a
permissions issue. Setting `GRADLE_OPTS` has no effect as it seems not
to be passed down to the daemon.
2023-11-25 20:13:24 +01:00
deftkHD 684d5c7b70 Use Gradle (#452) 2023-11-25 20:11:12 +01:00
deftk 851d22da6e Make check_layout.py independent from dir structure 2023-11-25 19:08:24 +01:00
Jules Aguillon 44adb55544 Separately persisted current layout in landscape mode
Remember the selected layout in portrait and landscape mode
independently.
This allows to define a layout specific to landscape without having to
switch manually.
2023-11-19 20:10:45 +01:00
Jules Aguillon 15de829138 Persist current selected layout 2023-11-19 19:07:54 +01:00
Jules Aguillon c57d896d8d Update translations
Was missing from the previous commit.
2023-11-19 12:03:39 +01:00
RetrogisusDEV 80c6f97767 Add Desert and Jungle themes 2023-11-19 11:33:39 +01:00
Diego Puma b0cf9a52b5 Update Spanish translations (#489) 2023-11-13 00:06:43 +01:00
Jules Aguillon f696452c59 method.xml: Add Armenian 2023-11-13 00:04:31 +01:00
Jules Aguillon 70500ba6f8 Update check_layout.output 2023-11-13 00:03:45 +01:00
Rafael Grigorian 474c693427 Add Armenian layout (#490) 2023-11-13 00:00:25 +01:00
RetrogisusDEV 73060bfc00 Adaptive launcher icon
Existing icons are kept for API < 26.
2023-11-06 20:52:35 +01:00
Reza Hosseinzadeh 60134effdc Remove extra paranthesis in persian layout (#485) 2023-11-01 16:30:01 +01:00
1 838fbc8ef8 Update Turkish translation (#486) 2023-10-31 20:57:42 +01:00
Jules Aguillon 148bed769a Add left/right slider to the emoji pane
This entirely changes the implementation of the bottom row in the emoji
pane.
2023-10-28 20:14:32 +02:00
deftk 3d36ecb34d Make special font glyphs pass linting 2023-10-28 18:48:25 +02:00
Jules Aguillon 2d164ca64f Add '₽' to Russian layout and to the Fn layer
Other currencies are moved on the Fn layer for consistency with the
compose key.
2023-10-21 11:56:56 +02:00
matthiakl d594242a53 Update the neo2 layout (#477) 2023-10-20 21:06:21 +02:00
Lyubomir Vasilev bd886a24eb Add Bulgarian BDS layout (#479) 2023-10-20 14:21:14 +02:00
Luke Videckis 7b7202ec1b Add * and @ to Hindi layout (#480) 2023-10-20 12:59:19 +02:00
Jules Aguillon 33653a94cb Add page_up, page_down, home, end to extra keys
The new keys are placed on the corner of the arrow keys. Key
descriptions are added.

They are removed from the Fn layer to avoid showing up twice.
2023-10-20 12:20:25 +02:00
Ojas Bhagavath 5b4345088d Use standard Greek layout in greekmath.xml (#474) 2023-09-24 16:59:47 +02:00
Jules Aguillon d5cbcb37e3 Preferred position for locale extra_keys
`method.xml` is now able to specify a preferred position for each extra
keys in term of an other key to which it should be placed nearby.

It's implemented for French as an example.
2023-09-24 16:35:24 +02:00
Jules Aguillon 66b1bdc9c9 Refactor: Preferred positions for extra keys
The new PreferredPos class represents where an extra key should be
placed
Currently used to place keys at the same positions they were placed
before.
2023-09-15 18:00:27 +02:00
Jules Aguillon d771e9d2c7 Refactor: Compute key positions in layouts
`KeyboardData.getKeys()` now returns a map of the keys present on the
layout to their position. Positions are the row, column and swipe
direction.

The computed map is cached in the KeyboardData object as it might be
accessed later by `findKeyWithValue`, which now do less work.
2023-09-10 11:43:56 +02:00
Jules Aguillon 44e2e86f19 Capitalize the first letter of custom keys
This is more useful than turning the entire string full caps.
2023-09-09 14:32:03 +02:00
Jules Aguillon 92a8db5e93 Update auto-capitalisation state when input starts
The initial capitalisation state given by the editor
(`info.initialCapsMode`) is always 0 in many editors.

For some text input types, update the state when typing starts,
disregarding the value given by `info.initialCapsMode`.
2023-09-09 14:15:44 +02:00
Jules Aguillon 687d88f4f7 Per-script numpad
The numeric layout and the optional right hand side numpad are modified
to show the digits belonging to the script used in the current layout.

The numpads are still defined as it was before. The digits are changed
in `modify_numpad` if needed.
2023-09-03 23:38:55 +02:00
Jules Aguillon b079e5cf43 Consistent layout for optional numpad
Modify the optional right hand numpad the same way as the numeric
layout.
2023-09-03 23:36:49 +02:00
Jules Aguillon 86038ef512 check_layout.py: Deterministic output order 2023-09-03 20:15:31 +02:00
Jules Aguillon 816269aed0 Remove unused editing keys from the settings
These keys don't seem to have a purpose, which is confusing.
2023-09-03 15:05:23 +02:00
Ben Slusky 234986817f Change Greek math koppa to lowercase (#457)
Uppercase koppa can still be entered as shift+koppa.
2023-08-30 09:33:36 +02:00
pharook f4a995e2bd Add Czech QWERTY layout (#455) 2023-08-28 19:16:39 +02:00
Jules Aguillon f07fbaff3b CONTRIBUTING: Fix typos 2023-08-27 17:44:13 +02:00
Jules Aguillon 3530263083 CONTRIBUTING: Improve translation guidelines 2023-08-27 17:39:04 +02: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 cf76118548 Add missing combining accents
Implement the combinations that were previously not possible and were
commented out.

Also remove `apply_dead_char` and `apply_combining` and make all
dead-keys definitions uniform.
2023-08-20 01:03:14 +02:00
Jules Aguillon 40498e7b4c Refactor: Allow combining diacritics modifiers
Change the API of `KeyModifier.Map_char` to allow returning a string
instead of a single 16 bits char.

This allows to return combining diacritics.

This also gets rid of `apply_map_or_dead_char`, maps can have their own
fallback.
2023-08-20 00:44:22 +02:00
588 changed files with 36556 additions and 7808 deletions
+1
View File
@@ -0,0 +1 @@
srcs/juloo.keyboard2/ComposeKeyData.java -diff
+3
View File
@@ -0,0 +1,3 @@
github: [ Julow ]
liberapay: Julow
custom: [ "https://paypal.me/JulesAguillon" ]
+39
View File
@@ -0,0 +1,39 @@
name: Check generated files
on:
workflow_dispatch:
push:
branches:
- master
pull_request:
jobs:
gen-layouts:
name: Layout list
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- run: python3 gen_layouts.py
- name: "Run 'python3 gen_layouts.py' to update the generated files."
run: git diff --exit-code
check-layouts:
name: Layout warnings
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- run: python3 check_layout.py
- name: "Fix your layout accordingly or run 'python3 check_layout.py' to promote the warnings"
run: git diff --exit-code
check-compose:
name: Compose key data
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- run: python3 srcs/compose/compile.py srcs/compose/{*.json,compose} > srcs/juloo.keyboard2/ComposeKeyData.java
- name: "Run 'gradle test' to update the generated files."
run: git diff --exit-code
-19
View File
@@ -1,19 +0,0 @@
name: Check layouts
# Runs 'gen_layouts.py' and checks that the generated file were uptodate.
# This doesn't run 'check_layout.py'.
on:
workflow_dispatch:
push:
pull_request:
jobs:
check-layouts:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- run: python3 gen_layouts.py
- name: Check that the generated layouts.xml is uptodate, run python3 gen_layouts.py otherwise
run: git diff --exit-code
-16
View File
@@ -1,16 +0,0 @@
name: Check translations
on:
workflow_dispatch:
push:
pull_request:
jobs:
check-translations:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- run: python3 sync_translations.py
- name: Check that strings files are uptodate, run python3 sync_translations.py otherwise
run: git diff --exit-code
+38 -18
View File
@@ -3,45 +3,65 @@ name: Make Apk CI
on:
workflow_dispatch:
push:
branches:
- master
pull_request:
jobs:
Build-Apk:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-java@v3
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '11'
- name: Checkout repo
uses: actions/checkout@v3
- name: Cache debug certificate
uses: actions/cache@v3
uses: actions/checkout@v6
with:
path: _build/debug.keystore
key: debug-keystore
- name: Restore debug keystore from github Secrets
submodules: true
- name: Restore debug keystore from GitHub Secrets
run: |
mkdir -p _build
cd "_build"
# Check if exist and use the secret named DEBUG_KEYSTORE
# The contents of the secret can be obtained -
# from the debug.keystore.asc from you local _build folder
# from the debug.keystore.asc from you local folder
# (refer to CONTRIBUTING.md Using the local debug.keystore on the Github CI actions)
if [[ ! "${{ secrets.DEBUG_KEYSTORE }}" = "" ]]; then
echo "${{ secrets.DEBUG_KEYSTORE }}" > "debug.keystore.asc"
if [[ -s "debug.keystore.asc" ]]; then
echo "Restoring debug keystore from GitHub secrets"
gpg -d --passphrase "debug0" --batch "debug.keystore.asc" > "debug.keystore"
fi
fi
- name: Build
run: make
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: 8.14.4
- name: Run tests
run: |
gradle test
# Warn about outdated generated files.
if ! git diff --name-only; then
echo "Warning: Generated files are not uptodate. Run 'gradle test'."
fi
- name: Build debug APK
run: ./gradlew assembleDebug
env:
DEBUG_KEYSTORE: "debug.keystore"
DEBUG_KEYSTORE_PASSWORD: debug0
DEBUG_KEY_ALIAS: debug
DEBUG_KEY_PASSWORD: debug0
- name: Artifact naming
run: |
artifact="${{github.repository_owner}} ${{github.ref_name}}"
artifact="${artifact//\//-}" # replace slashes
echo "artifact=${artifact}" >> $GITHUB_ENV
- name: Save debug apk
uses: actions/upload-artifact@v3
- name: Upload debug APK
uses: actions/upload-artifact@v4
with:
name: "${{env.artifact}} debug_apk"
path: _build/*.apk
path: build/outputs/apk/debug/*.apk
+11 -1
View File
@@ -1,4 +1,14 @@
*.keystore
*.keystore.asc
_build
/*-keystore.conf
*.iml
.gradle
/local.properties
/.idea
.DS_Store
/captures
/build
# Directory _build is not used anymore
/_build
/release
vendor/libswipetype/
+3
View File
@@ -0,0 +1,3 @@
[submodule "vendor/cdict"]
path = vendor/cdict
url = https://github.com/Julow/cdict
+46
View File
@@ -0,0 +1,46 @@
# Harley's Keyboard - agent notes
Fork of Julow/Unexpected-Keyboard (Unexpected Keyboard). Android IME, Java, Gradle Kotlin DSL.
## Build & test (exact)
```bash
./gradlew testDebugUnitTest assembleDebug # full verification: unit tests THEN the APK
./gradlew clean assembleDebug # when a generated file may be stale
```
- SDK: `local.properties` -> `sdk.dir=/home/nyra/android-sdk` (present, gitignored, do not commit).
- JDK 21, build-tools 34.0.0/36.0.0, AGP 8.8.2, compileSdk 36, minSdk 21.
- APK: `build/outputs/apk/debug/Unexpected-Keyboard-debug.apk`, package id `harley.keyboard`.
## Layout & generated code
- Layout rows live in `srcs/layouts/*.xml`. A layout edit needs a **full build**, not just compile:
`gen_layouts.py` regenerates `res/values/layouts.xml`, `res/raw/*.xml` and
`srcs/juloo.keyboard2/ComposeKeyData.java`. Unit tests run before regeneration report
stale-generated-state failures that are not real bugs.
- Never hand-edit generated files (`res/values/layouts.xml`, `res/raw/*`, `ComposeKeyData.java`,
`res/xml/method.xml`).
## Always do
- Run `./gradlew testDebugUnitTest assembleDebug` before reporting done.
- Keep user-visible text in `res/values/strings.xml`.
- Keep all network access off the UI thread.
## Ask first
- Adding any dependency (prefer the framework: `org.json`, `HttpURLConnection`).
- Changing the package id, signing config or versionCode.
## Never do
- Commit or print secrets/tokens; no credentials in code, XML, tests or logs.
- Touch `.git` internals, force-push, or edit CI workflows.
- Enable cleartext HTTP globally (only a per-host network security config).
- Change the space-bar peak-colour behaviour (a separate, deliberate feature).
## Definition of done
`./gradlew testDebugUnitTest assembleDebug` exits 0, new behaviour is covered by unit tests,
and the tree has no generated-file diffs beyond what a normal build produces.
+24 -7
View File
@@ -1,25 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="juloo.keyboard2" android:versionCode="36" android:versionName="1.24.0" android:hardwareAccelerated="false">
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="33"/>
<application android:label="@string/app_name" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:hardwareAccelerated="false">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:hardwareAccelerated="false">
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:label="@string/app_name" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:hardwareAccelerated="false" android:networkSecurityConfig="@xml/network_security_config">
<service android:name="juloo.keyboard2.Keyboard2" android:label="@string/app_name" android:permission="android.permission.BIND_INPUT_METHOD" android:exported="true" android:directBootAware="true">
<intent-filter>
<action android:name="android.view.InputMethod"/>
</intent-filter>
<meta-data android:name="android.view.im" android:resource="@xml/method"/>
</service>
<activity android:name="juloo.keyboard2.SettingsActivity" android:icon="@drawable/ic_launcher" android:label="@string/settings_activity_label" android:theme="@style/android:Theme.DeviceDefault" android:exported="true" android:directBootAware="true">
<activity android:name="juloo.keyboard2.SettingsActivity" android:icon="@mipmap/ic_launcher" android:theme="@style/settingsTheme" android:exported="true" android:directBootAware="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<activity android:name="juloo.keyboard2.LauncherActivity" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/android:Theme.DeviceDefault" android:exported="true" android:directBootAware="true">
<activity android:name="juloo.keyboard2.LauncherActivity" android:icon="@mipmap/ic_launcher" android:theme="@style/appTheme" android:exported="true" android:directBootAware="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="juloo.keyboard2.dict.DictionariesActivity" android:icon="@mipmap/ic_launcher" android:theme="@style/appTheme" android:exported="true" android:directBootAware="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- To query enabled input methods for voice IME detection -->
<queries>
<intent>
<action android:name="android.view.InputMethod" />
</intent>
</queries>
</manifest>
+130 -59
View File
@@ -4,52 +4,52 @@ Thanks for contributing :)
## Building the app
The application doesn't use Gradle and it might be hard to use some features of
Android Studio.
The application uses Gradle and can be used with Android Studio, but using
Android Studio is not required. The build dependencies are:
- OpenJDK 17
- Android SDK: build tools, platform `36`
Fortunately, there's not many dependencies:
- OpenJDK 8
- Android SDK: build tools (minimum `28.0.1`), platform `30`
- Make sure to have the `$ANDROID_HOME` environment variable set.
Python 3 is required to update generated files but not to build the app.
Make sure the Git submodules are initialized and point to the right revision:
```sh
git submodule update --init
```
For Android Studio users, no more setup is needed.
For Nix users, the right environment can be obtained with `nix-shell ./shell.nix`.
Instructions to install Nix are [here](https://nixos.wiki/wiki/Nix_Installation_Guide).
Instructions to install Nix are [here](https://wiki.nixos.org/wiki/Nix_Installation_Guide).
If you don't use Android Studio or Nix, you have to inform Gradle about the
location of your Android SDK by either:
- Setting the `ANDROID_HOME` environment variable to point to the android sdk or
- Creating the file `local.properties` and writing
`sdk.dir=<location_of_android_home>` into it.
Building the debug apk:
```sh
make
./gradlew assembleDebug
```
If the build succeed, the debug apk is located in `_build/juloo.keyboard2.debug.apk`.
Nix users can call gradle directly: `gradle assembleDebug`.
## Using the local debug.keystore on the Github CI actions
It's possible to save the local debug.keystore into a github secret, so the same keystore is utilized to build the debug apk in the CI github actions.
Doing this, they wil have the same signature, thus the debug apk can be updated without having to uninstall it first.
After you sucessfully run `make`, (thus a debug.keystore exists) you can use this second command to generate a base64 stringified version of it
```sh
cd _build
gpg -c --armor --pinentry-mode loopback --passphrase debug0 --yes "debug.keystore"
```
A file will be generated inside the local `_build/` folder, called `debug.keystore.asc`
You can copy the content of this file, and with that, paste it into a new github secret in your repo settings.
The secret must be named `DEBUG_KEYSTORE`
If the build succeeds, the debug apk is located in `build/outputs/apk/debug/app-debug.apk`.
## Debugging on your phone
First [Enable adb debugging on your device](https://developer.android.com/studio/command-line/adb#Enabling).
Then connect your phone to your computer using an USB cable or wireless
Then connect your phone to your computer using an USB cable or via wireless
debugging.
If you use Android Studio, this process will be automatic and you don't have to
follow this guide anymore.
And finally, install the application with:
```sh
make installd
./gradlew installDebug
```
The released version of the application won't be removed, both versions will
@@ -57,11 +57,13 @@ be installed at the same time.
## Debugging the application: INSTALL_FAILED_UPDATE_INCOMPATIBLE
`make installd` can fail with the following error message:
`./gradlew installDebug` can fail with the following error message:
```
adb: failed to install _build/juloo.keyboard2.debug.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package juloo.keyboard2.debug signatures do not match previously installed version; ignoring!]
make: *** [Makefile:20: installd] Error 1
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':installDebug'.
> java.util.concurrent.ExecutionException: com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package juloo.keyboard2.debug signatures do not match newer version; ignoring!
```
The application can't be "updated" because the temporary certificate has been
@@ -70,36 +72,57 @@ The application must be enabled again in the settings.
```sh
adb uninstall juloo.keyboard2.debug
make installd
./gradlew installDebug
```
## Specifying a debug signing certificate on Github Actions
It's possible to specify the signing certificate that the automated build
should use.
After you successfully run `./gradlew asssembleDebug`, (thus a debug.keystore
exists) you can use this second command to generate a base64 stringified
version of it:
```sh
gpg -c --armor --pinentry-mode loopback --passphrase debug0 --yes "debug.keystore"
```
This will create the file `debug.keystore.asc`, paste its content into a new
Github secret named `DEBUG_KEYSTORE`.
## Guidelines
### Adding a layout
Layouts are defined in XML, see `res/xml/latn_qwerty_us.xml`.
Layouts are defined in XML, see `srcs/layouts/latn_qwerty_us.xml`.
An online tool for editing layout files written by @Lixquid is available
[here](https://unexpected-keyboard-layout-editor.lixquid.com/).
Makes sure to specify the `name` attribute like in `latn_qwerty_us.xml`,
otherwise the layout won't be added to the app.
The layout file must be placed in the `res/xml/` directory and named according to:
The layout file must be placed in the `srcs/layouts` directory and named
according to:
- script (`latn` for latin, etc..)
- layout name (eg. the name of a standard)
- country code (or language code if more adequate)
Then, run `make gen_layouts` to add the layout to the app.
Then, run `./gradlew genLayoutsList` to add the layout to the app.
The last step will update the file `res/values/layouts.xml`, that you should
not edit directly.
Run `make check_layouts` to check some properties about your layout. This will
change the file `check_layout.output`, which you should commit.
Run `./gradlew checkKeyboardLayouts` to check some properties about your
layout. This will change the file `check_layout.output`, which you should
commit.
Layouts are CC0 licensed by default. If you do not want your layout to be
released into the public domain, add a copyright notice at the top of the file
and a mention in `srcs/layouts/LICENSE`.
#### Adding a programming layout
A programming layout must contains every ASCII characters.
A programming layout must contain all ASCII characters.
The current programming layouts are: QWERTY, Dvorak and Colemak.
See for example, Dvorak, added in https://github.com/Julow/Unexpected-Keyboard/pull/16
@@ -133,38 +156,86 @@ and other extra keys to show.
The list of language tags (generally two letters)
and locales (generally of the form `xx_XX`)
can be found in this stackoverflow answer: https://stackoverflow.com/a/7989085
can be found in this [stackoverflow answer](https://stackoverflow.com/a/7989085)
### Translations
### Updating translations
Translations are always welcome !
The text used in the app is written in `res/values-<language_tag>/strings.xml`.
See for example: 1723288 (Latvian), baf867a (French).
The app can be translated by writing `res/values-<language code>/strings.xml`
(for example `values-fr`, `values-lv`), based on the default:
`res/values/strings.xml` (English).
The list of language tags can be found in this
[stackoverflow answer](https://stackoverflow.com/a/7989085)
To check that `strings.xml` is formatted correctly, run
`python sync_translations.py`. This will modify your files.
The first part before the `_` is used, for example,
`res/values-fr/strings.xml` for French,
`res/values-lv/strings.xml` for Latvian.
The store description is found in `metadata/android/<locale>/`,
`short_description.txt` and `full_description.txt`.
The short description must not exceed 80 characters.
Commented-out lines indicate missing translations:
```xml
<!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
```
Remove the `<!--` and `-->` parts and change the text.
### Adding a translation
The preferred method for translating the app is to use Weblate:
https://hosted.weblate.org/engage/unexpected-keyboard/
The `res/values-<language_tag>/strings.xml` file must be created by copying the
default translation in `res/values/strings.xml`, which contain the structure of
the file and the English strings.
Store descriptions in `fastlane/metadata/android/` are updated automatically.
Translating changelogs is not useful.
The app name might be partially translated, the "unexpected" word should remain
untranslated.
The app name might be partially translated, the "Unexpected" word should remain
untranslated if possible.
As translations need to be updated regularly, you can subscribe to this issue
to receive a notification when an update is needed:
https://github.com/Julow/Unexpected-Keyboard/issues/373
### Adding key combinations
### Adding symbols to Shift, Fn, Compose and other modifiers
Key combinations are defined in `srcs/juloo.keyboard2/KeyModifier.java`.
For example, keys modified by the `Fn` key are defined in method
`apply_fn_char`.
New key combinations can be added to builtin modifiers in the following files:
Keys with special meaning are defined in `KeyValue.java` in method
`getKeyByName`. Their special action are defined in `KeyEventHandler.java` in
method `key_up`
- Shift in `srcs/compose/shift.json`.
- Fn in `srcs/compose/fn.json`.
- Compose in `srcs/compose/compose/extra.json`.
- Other modifiers are defined in the `accent_*.json` files in `srcs/compose`.
Generated code must then be updated by running:
```
./gradlew compileComposeSequences
```
These files describe each symbols that get transformed when a given modifier is
activated, in JSON format. For example:
Example from `fn.json`, when `Fn` is activated, `<` becomes `«`:
```json
{
"<": "«",
}
```
The result of a sequence can be a key name. See the list of key names in
[doc/Possible-key-values.md](doc/Possible-key-values.md). For example from
`fn.json`, when `Fn` is activated, space becomes `nbsp`:
```json
{
" ": "nbsp",
}
```
Compose sequences are made of several steps. For example, the sequence
`Compose V s = Š` is defined as:
```json
{
"V": {
"s": "Š"
}
}
```
-139
View File
@@ -1,139 +0,0 @@
# Configuration
PACKAGE_NAME = juloo.keyboard2
ANDROID_PLATFORM_VERSION = android-30
JAVA_VERSION = 1.7
SRC_DIR = srcs
RES_DIR = res
EXTRA_JARS =
# /
debug: _build/$(PACKAGE_NAME).debug.apk
release: _build/$(PACKAGE_NAME).apk
installd: _build/$(PACKAGE_NAME).debug.apk
adb install -r "$<"
clean:
rm -rf _build/*.dex _build/class _build/gen _build/*.apk _build/*.unsigned-apk \
_build/*.idsig _build/assets
rebuild_special_font: _build/special_font.ttf
cp "$<" srcs/special_font/result.ttf
sync_translations:
python sync_translations.py
check_layouts:
python check_layout.py $(wildcard res/xml/*.xml) > check_layout.output
gen_layouts:
python gen_layouts.py
# Will modify the source tree.
runtest: rebuild_special_font sync_translations check_layouts gen_layouts
.PHONY: release debug installd clean rebuild_special_font check_layouts \
sync_translations runtest gen_layouts
$(shell mkdir -p _build)
ifndef ANDROID_HOME
$(error ANDROID_HOME not set)
endif
ANDROID_BUILD_TOOLS = $(lastword $(sort $(wildcard $(ANDROID_HOME)/build-tools/*)))
ANDROID_PLATFORM = $(ANDROID_HOME)/platforms/$(ANDROID_PLATFORM_VERSION)
ifeq ($(shell [ -d "$(ANDROID_PLATFORM)" ] && echo ok),)
$(error Android platform not found. Want $(ANDROID_PLATFORM_VERSION), \
found $(notdir $(wildcard $(ANDROID_HOME)/platforms/*)))
endif
JAVAC_FLAGS = -source $(JAVA_VERSION) -target $(JAVA_VERSION) -encoding utf8
# Source files
MANIFEST_FILE = AndroidManifest.xml
JAVA_FILES = $(shell find $(SRC_DIR) -name '*.java')
RES_FILES = $(shell find $(RES_DIR) -type f)
# Debug signing
DEBUG_KEYSTORE = _build/debug.keystore
DEBUG_PASSWD = debug0
$(DEBUG_KEYSTORE):
echo y | keytool -genkeypair -dname "cn=d, ou=e, o=b, c=ug" \
-alias debug -keypass $(DEBUG_PASSWD) -keystore "$@" \
-keyalg rsa -storepass $(DEBUG_PASSWD) -validity 10000
_build/%.debug.apk: _build/%.debug.unsigned-apk $(DEBUG_KEYSTORE)
$(ANDROID_BUILD_TOOLS)/apksigner sign --in "$<" --out "$@" \
--ks $(DEBUG_KEYSTORE) --ks-key-alias debug --ks-pass "pass:$(DEBUG_PASSWD)"
# Debug apk
_build/$(PACKAGE_NAME).debug.unsigned-apk: AAPT_PACKAGE_FLAGS+=--rename-manifest-package $(PACKAGE_NAME).debug --product debug
# Release signing
# %-keystore.conf should declare KEYSTORE, KEYNAME and KEYSTOREPASS
# it is interpreted as a shell script
_build/%.apk: _build/%.unsigned-apk %-keystore.conf
eval `cat $(word 2,$^)` && \
$(ANDROID_BUILD_TOOLS)/apksigner sign --in "$<" --out "$@" \
--ks "$$KEYSTORE" --ks-key-alias "$$KEYNAME" --ks-pass "pass:$$KEYSTOREPASS"
# Package
_build/%.unsigned-apk: _build/%.unaligned-apk
$(ANDROID_BUILD_TOOLS)/zipalign -fp 4 "$<" "$@"
APK_EXTRA_FILES = classes.dex assets/special_font.ttf
_build/%.unaligned-apk: $(addprefix _build/,$(APK_EXTRA_FILES)) $(MANIFEST_FILE)
$(ANDROID_BUILD_TOOLS)/aapt package -f -M $(MANIFEST_FILE) -S $(RES_DIR) \
-I $(ANDROID_PLATFORM)/android.jar -F "$@" $(AAPT_PACKAGE_FLAGS)
cd $(@D) && $(ANDROID_BUILD_TOOLS)/aapt add $(@F) $(APK_EXTRA_FILES)
# Copy the special font file into _build because aapt requires relative paths
_build/assets/special_font.ttf: srcs/special_font/result.ttf
mkdir -p $(@D)
cp "$<" "$@"
# R.java
GEN_DIR = _build/gen
R_FILE = $(GEN_DIR)/$(subst .,/,$(PACKAGE_NAME))/R.java
$(R_FILE): $(RES_FILES) $(MANIFEST_FILE)
mkdir -p "$(@D)"
$(ANDROID_BUILD_TOOLS)/aapt package -f -m -S $(RES_DIR) -J $(GEN_DIR) \
-M $(MANIFEST_FILE) -I $(ANDROID_PLATFORM)/android.jar
# Compile java classes and build classes.dex
OBJ_DIR = _build/class
# A$B.class files are ignored
# CLASS_FILES = $(JAVA_FILES:$(SRC_DIR)/%.java=$(OBJ_DIR)/%.class) \
# $(R_FILE:$(GEN_DIR)/%.java=$(OBJ_DIR)/%.class)
_build/classes.dex: $(JAVA_FILES) $(R_FILE)
mkdir -p $(OBJ_DIR)
javac -d $(OBJ_DIR) $(JAVAC_FLAGS) \
-classpath $(ANDROID_PLATFORM)/android.jar:$(EXTRA_JARS) \
-sourcepath $(SRC_DIR):$(GEN_DIR) \
$^
$(ANDROID_BUILD_TOOLS)/d8 --output $(@D) $(OBJ_DIR)/*/*/* $(subst :, ,$(EXTRA_JARS))
# Font file
FONT_GLYPHS = $(wildcard srcs/special_font/*.svg)
_build/special_font.ttf: srcs/special_font/build.pe $(FONT_GLYPHS)
fontforge -lang=ff -script $< "$@" $(FONT_GLYPHS)
+26 -7
View File
@@ -1,4 +1,12 @@
# Unexpected Keyboard
# Unexpected Keyboard [<img src="https://hosted.weblate.org/widget/unexpected-keyboard/svg-badge.svg" alt="État de la traduction" />](https://hosted.weblate.org/engage/unexpected-keyboard/)
---
⚠️ Google wants to kill the open-source Android community.
See [keepandroidopen.org](https://keepandroidopen.org/) and the [F-Droid blog](https://f-droid.org/en/2025/09/29/google-developer-registration-decree.html).
---
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid"
@@ -9,21 +17,32 @@
Lightweight and privacy-conscious virtual keyboard for Android.
| <img src="/metadata/android/en-US/images/phoneScreenshots/1.png" alt="Screenshot-1" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/2.png" alt="Screenshot-2"/> | <img src="/metadata/android/en-US/images/phoneScreenshots/3.png" alt="Screenshot-3"/> |
| --- | --- | --- |
| <img src="/metadata/android/en-US/images/phoneScreenshots/4.png" alt="Screenshot-4" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/5.png" alt="Screenshot-5" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/6.png" alt="Screenshot-6" /> |
https://github.com/Julow/Unexpected-Keyboard/assets/2310568/28f8f6fe-ac13-46f3-8c5e-d62443e16d0d
The main feature is that you can type more characters by swiping the keys towards the corners.
This application was originally designed for programmers using Termux.
Now perfect for everyday use.
This application contains no ads, doesn't make any network requests and is Open Source.
This application contains no ads and is open source.
## Similar apps
* [Calculator++](https://github.com/Bubu/android-calculatorpp) - Calculator with a similar UX, swipe to corners for advanced math symbols and operators. Works up to Android 13 but maybe unmaintained.
Usage: to apply the symbols located in the corners of each key, slide your finger in the direction of the symbols. For example, the Settings are opened by sliding in the left down corner.
| <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png" alt="Screenshot-1" /> | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png" alt="Screenshot-2"/> | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png" alt="Screenshot-3"/> |
| --- | --- | --- |
| <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png" alt="Screenshot-4" /> | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png" alt="Screenshot-5" /> | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png" alt="Screenshot-6" /> |
## Help translate the application
Improve the application translations [using Weblate](https://hosted.weblate.org/engage/unexpected-keyboard/).
[<img src="https://hosted.weblate.org/widget/unexpected-keyboard/multi-auto.svg" alt="État de la traduction" />](https://hosted.weblate.org/engage/unexpected-keyboard/)
## Contributing
For instructions on building the application, see
[Contributing](CONTRIBUTING.md).
## Acknowledgement
The [NLnet foundation](https://nlnet.nl/) funded the work on the spell checking feature.
Binary file not shown.
+196
View File
@@ -0,0 +1,196 @@
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
import java.io.FileOutputStream
plugins {
id("com.android.application") version "8.13.2"
}
dependencies {
// Following versions of androidx.window require sdk version 23
implementation("androidx.window:window-java:1.4.0")
implementation("androidx.core:core:1.16.0") // Version 1.17.0 available with sdk 36
testImplementation("junit:junit:4.13.2")
}
android {
namespace = "juloo.keyboard2"
compileSdkVersion = "android-36"
defaultConfig {
applicationId = "harley.keyboard"
minSdk = 21
targetSdk { version = release(36) }
versionCode = 55
versionName = "2.0.4"
}
sourceSets {
named("main") {
manifest.srcFile("AndroidManifest.xml")
java.srcDirs("srcs/juloo.keyboard2", "vendor/cdict/java/juloo.cdict")
res.srcDirs("res", "build/generated-resources")
assets.srcDirs("assets")
}
named("test") {
java.srcDirs("test")
}
}
externalNativeBuild {
ndkBuild {
path = file("vendor/Android.mk")
}
}
signingConfigs {
// Debug builds will always be signed. If no environment variables are set, a default
// keystore will be initialized by the task initDebugKeystore and used. This keystore
// can be uploaded to GitHub secrets by following instructions in CONTRIBUTING.md
// in order to always receive correctly signed debug APKs from the CI.
named("debug") {
storeFile = file(System.getenv("DEBUG_KEYSTORE") ?: "debug.keystore")
storePassword = System.getenv("DEBUG_KEYSTORE_PASSWORD") ?: "debug0"
keyAlias = System.getenv("DEBUG_KEY_ALIAS") ?: "debug"
keyPassword = System.getenv("DEBUG_KEY_PASSWORD") ?: "debug0"
}
create("release") {
val ks = System.getenv("RELEASE_KEYSTORE")
if (ks != null) {
storeFile = file(ks)
storePassword = System.getenv("RELEASE_KEYSTORE_PASSWORD")
keyAlias = System.getenv("RELEASE_KEY_ALIAS")
keyPassword = System.getenv("RELEASE_KEY_PASSWORD")
}
}
}
buildTypes {
named("release") {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro")
isShrinkResources = true
isDebuggable = false
resValue("string", "app_name", "@string/app_name_release")
signingConfig = signingConfigs["release"]
}
named("debug") {
isMinifyEnabled = false
isShrinkResources = false
isDebuggable = true
resValue("string", "app_name", "@string/app_name_debug")
resValue("bool", "debug_logs", "true")
signingConfig = signingConfigs["debug"]
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
// This raises an error with an informative message instead of the confusing
// ndk-build errors that occur when submodules are not initialized.
gradle.projectsEvaluated {
if (!file("vendor/cdict/java").exists())
throw GradleException("Git submodules not initialized. Run 'git submodule update --init'")
}
val buildKeyboardFont by tasks.registering(Exec::class) {
val `in` = projectDir.resolve("srcs/special_font")
val out = layout.projectDirectory.file("assets/special_font.ttf")
inputs.dir(`in`)
outputs.file(out)
doFirst { println("\nBuilding assets/special_font.ttf") }
workingDir = `in`
val svgFiles = `in`.listFiles()!!.filter {
it.isFile && it.name.endsWith(".svg")
}.toTypedArray()
commandLine("fontforge", "-lang=ff", "-script", "build.pe", out.asFile.absolutePath, *svgFiles)
}
val genEmojis by tasks.registering(Exec::class) {
doFirst { println("\nGenerating res/raw/emojis.txt") }
workingDir = projectDir
commandLine("python", "gen_emoji.py")
}
val genLayoutsList by tasks.registering(Exec::class) {
inputs.dir(projectDir.resolve("srcs/layouts"))
outputs.file(projectDir.resolve("res/values/layouts.xml"))
doFirst { println("\nGenerating res/values/layouts.xml") }
workingDir = projectDir
commandLine("python", "gen_layouts.py")
}
val genMethodXml by tasks.registering(Exec::class) {
val out = projectDir.resolve("res/xml/method.xml")
inputs.file(projectDir.resolve("gen_method_xml.py"))
inputs.file(projectDir.resolve("res/values/dictionaries.xml"))
outputs.file(out)
doFirst { println("\nGenerating res/xml/method.xml") }
doFirst { standardOutput = FileOutputStream(out) }
workingDir = projectDir
commandLine("python", "gen_method_xml.py")
}
val checkKeyboardLayouts by tasks.registering(Exec::class) {
inputs.dir(projectDir.resolve("srcs/layouts"))
inputs.file(projectDir.resolve("srcs/juloo.keyboard2/KeyValue.java"))
outputs.file(projectDir.resolve("check_layout.output"))
doFirst { println("\nChecking layouts") }
workingDir = projectDir
commandLine("python", "check_layout.py")
}
val compileComposeSequences by tasks.registering(Exec::class) {
val `in` = projectDir.resolve("srcs/compose")
val out = projectDir.resolve("srcs/juloo.keyboard2/ComposeKeyData.java")
inputs.dir(`in`)
outputs.file(out)
doFirst { println("\nGenerating $out") }
val sequences = `in`.listFiles { it: File ->
!it.name.endsWith(".py") && !it.name.endsWith(".md")
}!!.map { it.absolutePath }.toTypedArray()
workingDir = projectDir
commandLine("python", `in`.resolve("compile.py").absolutePath, *sequences)
doFirst { standardOutput = FileOutputStream(out) }
}
tasks.withType(Test::class).configureEach {
dependsOn(genLayoutsList, checkKeyboardLayouts, compileComposeSequences, genMethodXml)
}
val initDebugKeystore by tasks.registering(Exec::class) {
doFirst { println("Initializing default debug keystore") }
isEnabled = !file("debug.keystore").exists()
// A shell script might be needed if this line requires input from the user
commandLine("keytool", "-genkeypair", "-dname", "cn=d, ou=e, o=b, c=ug", "-alias", "debug", "-keypass", "debug0", "-keystore", "debug.keystore", "-keyalg", "rsa", "-storepass", "debug0", "-validity", "10000")
}
// latn_qwerty_us is used as a raw resource by the custom layout option.
val copyRawQwertyUS by tasks.registering(Copy::class) {
from("srcs/layouts/latn_qwerty_us.xml")
into("build/generated-resources/raw")
}
val copyLayoutDefinitions by tasks.registering(Copy::class) {
from("srcs/layouts")
include("*.xml")
into("build/generated-resources/xml")
}
tasks.named("preBuild") {
dependsOn(initDebugKeystore, copyRawQwertyUS, copyLayoutDefinitions)
// 'mustRunAfter' defines ordering between tasks (which is required by
// Gradle) but doesn't create a dependency. These rules update files that are
// checked in the repository that don't need to be updated during regular
// builds.
mustRunAfter(genEmojis, genLayoutsList, compileComposeSequences, genMethodXml)
}
+32 -117
View File
@@ -1,117 +1,32 @@
# res/xml/arab_alt.xml
Layout includes some ASCII punctuation but not all, missing: !, ", ', +, -, /, :, ;, <, =, >, ?, [, \, ], _, |, ~
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
2 warnings
# res/xml/arab_pc_ckb.xml
Layout includes some ASCII punctuation but not all, missing: ", %, ', +, ,, ., :, ;, <, =, >, ?, `, |, ~
1 warnings
# res/xml/arab_pc_ir.xml
Duplicate keys: (, )
Layout includes some ASCII punctuation but not all, missing: ", %, ', ,, /, ;, <, =, >, ?, [, \, ], `, {, |, }
2 warnings
# res/xml/arab_pc.xml
Layout includes some ASCII punctuation but not all, missing: !, ', +, ;, ?, \, |
1 warnings
# res/xml/beng_national.xml
Layout includes some ASCII punctuation but not all, missing: $
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
Layout doesn't specify a script.
3 warnings
# res/xml/beng_provat.xml
Layout includes some ASCII punctuation but not all, missing: $, &, *, ., /, <, >, [, \, ], `, {, |, }
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
Layout doesn't specify a script.
3 warnings
# res/xml/cyrl_jcuken_ru.xml
0 warnings
# res/xml/cyrl_jcuken_uk.xml
0 warnings
# res/xml/cyrl_yaverti.xml
Layout includes some ASCII punctuation but not all, missing: ~
1 warnings
# res/xml/deva_alt.xml
Layout includes some ASCII punctuation but not all, missing: #, $, %, &, ', (, ), *, +, ., /, :, <, =, >, @, [, \, ], ^, _, `, {, |, }, ~
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
2 warnings
# res/xml/deva_inscript.xml
Duplicate keys: , ।
Layout includes some ASCII punctuation but not all, missing: ", $, ', ^, _, `, |
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
3 warnings
# res/xml/grek_qwerty.xml
Duplicate keys: ;
1 warnings
# res/xml/hang_dubeolsik_kr.xml
0 warnings
# res/xml/hebr_1_il.xml
Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, }
1 warnings
# res/xml/hebr_2_il.xml
Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, }
1 warnings
# res/xml/latn_azerty_fr.xml
0 warnings
# res/xml/latn_bepo_fr.xml
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
1 warnings
# res/xml/latn_bone.xml
Layout includes some ASCII punctuation but not all, missing: $
Layout redefines the bottom row but some important keys are missing, missing: switch_backward
2 warnings
# res/xml/latn_colemak.xml
0 warnings
# res/xml/latn_dvorak.xml
0 warnings
# res/xml/latn_neo2.xml
Duplicate keys: -
Layout redefines the bottom row but some important keys are missing, missing: switch_forward
2 warnings
# res/xml/latn_qwerty_br.xml
0 warnings
# res/xml/latn_qwerty_es.xml
0 warnings
# res/xml/latn_qwerty_hu.xml
0 warnings
# res/xml/latn_qwerty_lv.xml
0 warnings
# res/xml/latn_qwerty_no.xml
0 warnings
# res/xml/latn_qwerty_pl.xml
0 warnings
# res/xml/latn_qwerty_ro.xml
0 warnings
# res/xml/latn_qwerty_se.xml
Duplicate keys: !, ', ,, -, ., ?
1 warnings
# res/xml/latn_qwerty_tr.xml
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
1 warnings
# res/xml/latn_qwerty_us.xml
0 warnings
# res/xml/latn_qwerty_vi.xml
Layout includes some ASCII punctuation but not all, missing: \
1 warnings
# res/xml/latn_qwertz_cz_multifunctional.xml
Layout includes some ASCII punctuation but not all, missing: `
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
2 warnings
# res/xml/latn_qwertz_cz.xml
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
1 warnings
# res/xml/latn_qwertz_de.xml
0 warnings
# res/xml/latn_qwertz_fr_ch.xml
0 warnings
# res/xml/latn_qwertz_hu.xml
0 warnings
# res/xml/latn_qwertz_sk.xml
Layout includes some ASCII punctuation but not all, missing: \, `
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
2 warnings
# res/xml/latn_qwertz.xml
0 warnings
# res/xml/urdu_phonetic_ur.xml
Duplicate keys:
Layout includes some ASCII punctuation but not all, missing: <, >, ?, `, |, ~
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
3 warnings
arab_alt: Layout includes some ASCII punctuation but not all, missing: !, ", ', +, -, /, :, ;, <, =, >, ?, [, \, ], _, |, ~
arab_hamvaj_tly: Layout includes some ASCII punctuation but not all, missing: ", %, ', ,, /, ;, <, =, >, ?, [, \, ], _, `, {, |, }
arab_pc: Layout includes some ASCII punctuation but not all, missing: !, ', +, ;, ?, \, |
arab_pc_ckb: Layout includes some ASCII punctuation but not all, missing: ", %, ', +, ,, ;, <, =, >, ?, `, |, ~
arab_pc_ckb_fa: Layout includes some ASCII punctuation but not all, missing: ", #, $, %, &, ', ,, /, ;, ?, @, \, ^, `, |, ~
arab_pc_hindu: Layout includes some ASCII punctuation but not all, missing: !, ', +, ;, ?, \, |
arab_pc_ir: Layout includes some ASCII punctuation but not all, missing: ", %, ', ,, /, ;, <, =, >, ?, [, \, ], `, {, |, }
armn_cpbsmo: Layout includes some ASCII punctuation but not all, missing: !, ", #, $, %, &, ', *, +, <, =, >, ?, @, [, ], ^, `, {, }, ~
armn_kvertc: Layout includes some ASCII punctuation but not all, missing: !, ", #, $, %, &, ', *, +, <, =, >, ?, @, [, ], ^, `, {, }, ~
beng_assamese: Layout includes some ASCII punctuation but not all, missing: #, $, %, &, ', *, +, -, /, :, ;, <, =, >, ?, [, \, ], ^, _, `, {, |, }, ~
beng_national: Layout includes some ASCII punctuation but not all, missing: $
beng_provat: Layout includes some ASCII punctuation but not all, missing: $, &, *, ., /, <, >, [, \, ], `, {, |, }
cyrl_jiuken: Layout includes some ASCII punctuation but not all, missing: #, $, &, ', *, +, <, =, >, @, [, ], ^, _, `, {, }, ~
cyrl_lynyertdz_mk: Layout includes some ASCII punctuation but not all, missing: "
cyrl_yaverti: Layout includes some ASCII punctuation but not all, missing: ~
cyrl_yawerty: Layout includes some ASCII punctuation but not all, missing: #, $, &, ', *, <, >, @, [, ], ^, `, {, }, ~
cyrl_yxukeng_os: Layout includes some ASCII punctuation but not all, missing: ", #, $, &, ', @, [, ], ~
deva_alt: Layout includes some ASCII punctuation but not all, missing: #, $, %, &, ', (, ), *, +, ., /, :, <, =, >, [, \, ], ^, _, `, {, |, }, ~
deva_inscript: Layout includes some ASCII punctuation but not all, missing: ", $, ', ^, _, `, |
hebr_1_il: Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, }
hebr_2_il: Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, }
kann_kannada: Layout includes some ASCII punctuation but not all, missing: #, $, %, (, ), *, +, /, <, =, >, [, \, ], ^, `, {, |, }, ~
latin_kbdtuf_tr: Layout includes some ASCII punctuation but not all, missing: $
latin_kbdtuf_tr: These keys are now added automatically, unexpected: f11_placeholder, f12_placeholder
latin_kbdtuf_tr: Missing programming keys, missing: loc esc, loc tab
latn_colemak: Some keys contain whitespaces, unexpected: ́
latn_dvorak: Missing important key, missing: loc capslock
latn_neo2: Layout redefines the bottom row but some important keys are missing, missing: alt, loc switch_clipboard, meta, pgdn, pgup, switch_fn
latn_qwertz_cz_multifunctional: Layout includes some ASCII punctuation but not all, missing: `
latn_qwertz_sk: Layout includes some ASCII punctuation but not all, missing: `
latn_qzerty_it: Layout includes some ASCII punctuation but not all, missing: #, $, \, `, ~
urdu_phonetic_ur: Layout includes some ASCII punctuation but not all, missing: <, >, ?, `, |, ~
+95 -36
View File
@@ -1,17 +1,26 @@
import xml.etree.ElementTree as ET
import sys
import sys, os, glob, re
warning_count = 0
layout_file_name = 0
warnings = []
KNOWN_NOT_LAYOUT = set([
"res/xml/number_row.xml", "res/xml/numpad.xml", "res/xml/pin.xml",
"res/xml/bottom_row.xml", "res/xml/settings.xml", "res/xml/method.xml",
"res/xml/greekmath.xml", "res/xml/numeric.xml" ])
"number_row", "numpad", "pin",
"bottom_row", "settings", "method",
"greekmath", "numeric", "emoji_bottom_row",
"clipboard_bottom_row" ])
KEY_ATTRIBUTES = set([
"key0", "key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8",
"c", "nw", "ne", "sw", "se", "w", "e", "n", "s"
])
# Keys defined in KeyValue.java
known_keys = set()
def warn(msg):
global warning_count
print(msg)
warning_count += 1
global warnings
warnings.append("%s: %s" % (layout_file_name, msg))
def key_list_str(keys):
return ", ".join(sorted(list(keys)))
@@ -34,46 +43,72 @@ def unexpected_keys(keys, symbols, msg):
if len(unexpected) > 0:
warn("%s, unexpected: %s" % (msg, key_list_str(unexpected)))
def duplicates(keys):
dup = [ k for k, key_elts in keys.items() if len(key_elts) >= 2 ]
if len(dup) > 0:
warn("Duplicate keys: " + key_list_str(dup))
def should_have_role(keys_map, role, keys):
def is_center_key(key):
def center(key_elt): return key_elt.get("key0", key_elt.get("c"))
return any(( center(key_elt) == key for key_elt in keys_map.get(key, []) ))
def key_roles(key):
return ( key_elt.get("role", "normal") for key_elt in keys_map[key] )
for key in keys:
if is_center_key(key) and role not in key_roles(key):
warn("Key '%s' is not on a key with role=\"%s\"" % (key, role))
# Write to [keys], dict of keyvalue to the key elements they appear in
def parse_row_from_et(row, keys):
for key_elt in row:
for attr in key_elt.keys():
if attr in KEY_ATTRIBUTES:
k = key_elt.get(attr).removeprefix("\\")
keys.setdefault(k, []).append(key_elt)
def parse_layout(fname):
keys = set()
dup = set()
keys = {}
root = ET.parse(fname).getroot()
if root.tag != "keyboard":
return None
for row in root:
for key in row:
for attr in key.keys():
if attr.startswith("key"):
k = key.get(attr).removeprefix("\\")
if k in keys: dup.add(k)
keys.add(k)
return root, keys, dup
parse_row_from_et(row, keys)
return root, keys
def parse_row(fname):
keys = {}
root = ET.parse(fname).getroot()
if root.tag != "row":
return None
parse_row_from_et(root, keys)
return root, keys
def check_layout(layout):
root, keys, dup = layout
if len(dup) > 0: warn("Duplicate keys: " + key_list_str(dup))
root, keys_map = layout
keys = set(keys_map.keys())
duplicates(keys_map)
missing_some_of(keys, "~!@#$%^&*(){}`[]=\\-_;:/.,?<>'\"+|", "ASCII punctuation")
missing_some_of(keys, "0123456789", "digits")
missing_required(keys,
["esc", "tab", "backspace", "delete",
"f11_placeholder", "f12_placeholder"],
"Layout doesn't define some important keys")
missing_required(keys, ["backspace", "delete"], "Layout doesn't define some important keys")
unexpected_keys(keys,
["copy", "paste", "cut", "selectAll", "shareText",
"pasteAsPlainText", "undo", "redo", "replaceText",
"textAssist", "autofill" ],
"pasteAsPlainText", "undo", "redo" ],
"Layout contains editing keys")
unexpected_keys(keys,
[ "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
"f10", "f11", "f12" ],
"Layout contains function keys")
unexpected_keys(keys, [""], "Layout contains empty strings")
unexpected_keys(keys, ["loc"], "Special keyword cannot be a symbol")
unexpected_keys(keys, filter(lambda k: k.strip()!=k, keys), "Some keys contain whitespaces")
unexpected_keys(keys, ["f11_placeholder", "f12_placeholder"], "These keys are now added automatically")
bottom_row_keys = [
"ctrl", "fn", "switch_numeric", "change_method", "switch_emoji",
"config", "switch_forward", "switch_backward", "enter", "action",
"left", "up", "right", "down", "space"
]
if root.get("script", "latin") == "latin":
missing_required(keys, ["shift", "loc capslock"], "Missing important key")
missing_required(keys, ["loc esc", "loc tab"], "Missing programming keys")
_, bottom_row_keys_map = parse_row("res/xml/bottom_row.xml")
bottom_row_keys = set(bottom_row_keys_map.keys())
if root.get("bottom_row") == "false":
missing_required(keys, bottom_row_keys,
"Layout redefines the bottom row but some important keys are missing")
@@ -84,14 +119,38 @@ def check_layout(layout):
if root.get("script") == None:
warn("Layout doesn't specify a script.")
for fname in sys.argv[1:]:
if fname in KNOWN_NOT_LAYOUT:
should_have_role(keys_map, "action",
[ "shift", "ctrl", "fn", "backspace", "enter" ])
should_have_role(keys_map, "space_bar", [ "space" ])
keys_without_loc = set(( k.removeprefix("loc ") for k in keys ))
# Keys with a len under 3 are often composed characters
special_keys = set(( k for k in keys_without_loc if len(k) > 3 and ":" not in k ))
unknown = special_keys.difference(known_keys)
if len(unknown) > 0:
warn("Layout contains unknown keys: %s" % key_list_str(unknown))
# Fill 'known_keys', which is used for some checks
def parse_known_keys():
global known_keys
with open("srcs/juloo.keyboard2/KeyValue.java", "r", encoding="utf-8") as f:
known_keys = set(
( m.group(1) for m in re.finditer('case "([^"]+)":', f.read()) )
)
parse_known_keys()
for fname in sorted(glob.glob("srcs/layouts/*.xml")):
layout_id, _ = os.path.splitext(os.path.basename(fname))
if layout_id in KNOWN_NOT_LAYOUT:
continue
layout_file_name = layout_id
layout = parse_layout(fname)
if layout == None:
print("Not a layout file: %s" % fname)
warn("Not a layout file")
else:
print("# %s" % fname)
warning_count = 0
check_layout(layout)
print("%d warnings" % warning_count)
with open("check_layout.output", "w", encoding="utf-8") as out:
for w in warnings:
print(w, file=out)
+163
View File
@@ -0,0 +1,163 @@
# Custom layouts
You select a key layout for Unexpected Keyboard by calling up the Settings page (swipe the gear icon) and, at the top of the page, either tapping an existing layout or tapping _Add an alternate layout_. This displays a menu of available layouts. You can define your own layout by choosing _Custom layout_ at the bottom of this menu. Unexpected Keyboard now displays code in the XML format. You make changes by replacing this with different code and tapping OK.
We recommend you keep your work in a file outside Unexpected Keyboard (named something like `MyChanges.xml`). If you installed a new version of Unexpected from a different website (with a different signature), then the work you did solely by editing the XML inside Unexpected would be lost.
Put initial contents into your file in one of these ways:
* Copypaste the code Unexpected displays for _Custom layout_.
* Make a copy of one of the built-in layouts found in [`/srcs/layouts`](https://github.com/Julow/Unexpected-Keyboard/tree/master/srcs/layouts).
* Use the [web-based editor](https://domportera.github.io/app-unexpected-keyboard-layout-editor/). Interact with this web page to define keys and swipes and move keys to desired positions, and it will write the XML code for you. You can make the web page put the XML in a text file or copy it to the clipboard.
When you have prepared suitable XML code in one of these ways, copy it to the clipboard and paste it into Unexpected Keyboard.
## XML language overview
A layout XML file comprises tags that start with `<` and end with `>`.
* Every layout file starts with this declaration:
`<?xml version="1.0" encoding="utf-8"?>`
* Certain tags come in pairs—an opening tag and a closing tag—and apply to everything between them.
* The `<keyboard>`...`</keyboard>` pair says that the material between them is the definition of your keyboard. There can be only one of these.
* The `<row>`...`</row>` pair encloses the definition of a single row.
* An optional `<modmap>`...`</modmap>` pair contains instructions if you want to change the behavior of a modifier key such as Shift.
* Stand-alone tags include `<key`...`/>`, which defines a single key.
A tag can have properties, defined using an equals sign and a pair of ASCII double quotes. For example, `<key c="a" />` defines the "a" key. The `c` property of the `key` tag says which key you are defining, and the tag's location inside `<row>`...`</row>` specifies where it will go in the row.
### Example
Here is a complete keyboard file with a single row containing an "a" key on the left and a "b" key on the right:
<?xml version="1.0" encoding="utf-8"?>
<keyboard name="Simple example" script="latin">
<row>
<key c="a" />
<key c="b" />
</row>
</keyboard>
## Keyboard metadata
The `<keyboard>`...`</keyboard>` pair follows the declaration tag and encloses the whole keyboard. The following properties may be used (The first two appear in the example above):
* `name`: The name of the keyboard. The name you specify will appear in the Settings menu. If not present, the layout will just appear as “Custom layout”.
* `script`: The (main) writing system that the keyboard supports. The possible values are `arabic`, `armenian`, `bengali`, `cyrillic`, `devanagari`, `gujarati`, `hangul`, `hebrew`, `latin`, `persian`, `shavian`, and `urdu`. It defaults to `latin`.
* `numpad_script`: The script to use for the numpad. This is useful for scripts where a different, non-ASCII set of numerals is used, like Devanagari and Arabic. It defaults to the same as `script`.
* `bottom_row`: Whether or not to show the built-in bottom row. It accepts `true` or `false`, and defaults to `true`. If your custom layout defines the bottom row, then specify `bottom_row="false"` to disable the built-in bottom row.
+ We recommend your layout use the built-in bottom row, because it is still evolving and your layout will incorporate innovations in future versions. However, to define your own, the current definition of the bottom row is in [bottom_row.xml](https://github.com/Julow/Unexpected-Keyboard/blob/master/res/xml/bottom_row.xml). You can copypaste this XML into your custom layout as a starting point.
+ Likewise, the current definition of the top (number) row is in [number_row.xml](https://github.com/Julow/Unexpected-Keyboard/blob/master/res/xml/number_row.xml).
* `embedded_number_row`: Whether the layout has an embedded number row, and thus the "Show number row" setting shouldn't add another one. It accepts `true` or `false`, and defaults to `false`.
* `locale_extra_keys`: Whether Unexpected should add language-dependent extra keys from [method.xml](../res/xml/method.xml) to this layout. It accepts `true` or `false`, and defaults to `true`. To disable these automatic additions, specify `locale_extra_keys="false"`.
## Row
The `<row>`...`</row>` pair encloses one row on the keyboard. It has the following optional property:
* `height`: The height of the row: a positive floating-point value.
* `scale`: A positive floating-point value. If present, scale the width of each key so that the total is equal to the specified value, in key width unit.
A row's default height is 1.0 (one quarter of the keyboard height specified on the Settings menu). The `height` property makes the row taller or shorter than this. For example, if you define a 5-row keyboard but one row has `height="0.7"`, then the keyboard's total height is 4.7 units. If the total is different from 4.0, the keyboard will be taller or shorter than that specified in Settings.
(A row of keys is drawn with a minimum height of 0.5 even if you specify a smaller value for `height`. There is no such minimum for a row without keys, such as a spacer row.)
## Key
The `<key />` tag defines a key on the keyboard. Its position in the sequence of keys inside `<row>`...`</row>` indicates its position in the row from left to right. What the key does is defined by optional properties.
### Taps
What the key does when tapped is defined by the optional `c` property. For example, `<key c="a" />` defines the "a" key. Unexpected Keyboard provides a legend in the middle of the key.
When the Shift modifier is tapped, the "a" key becomes the "A" key and the legend temporarily changes. The Fn modifier makes a different change. You can override this behavior with a modmap (see below).
### Swipes
The following optional properties define the effects of swipes:
* `n`, `ne`, `e`, `se`, `s`, `sw`, `w`, `nw`: What the key should do when it is swiped in the direction of that compass point. ("North" means upward and "East" is to the right.)
<TABLE ALIGN=CENTER>
<TR>
<TD STYLE="width: 6em;">nw</TD><TD>n</TD><TD>ne</TD>
</TR>
<TR ALIGN=CENTER>
<TD>w</TD><TD>c</TD><TD>e</TD>
</TR>
<TR>
<TD>sw</TD><TD>s</TD><TD>se</TD>
</TR>
</TABLE>
* `key1` through `key8` is an older way to achieve the same effects. The directions are ordered as follows:
<TABLE ALIGN=CENTER>
<TR>
<TD>key1</TD><TD>key7</TD><TD>key2</TD>
</TR>
<TR>
<TD>key5</TD><TD>key0</TD><TD>key6</TD>
</TR>
<TR>
<TD>key3</TD><TD>key8</TD><TD>key4</TD>
</TR>
</TABLE>
You can define a swipe only once with either compass-point or numeric notation. Unexpected Keyboard automatically puts a small legend in that direction from the center of the key.
* `anticircle`: The key value to send when doing an anti-clockwise gesture on the key.
### Layout
A key may have the following properties to control the row's layout:
* `width`: The width of the key, a positive floating-point value. It defaults to 1.0
* `shift`: How much empty space to add to the left of this key, a non-negative floating-point value. It defaults to 0.0
Normally, a key's width is 1.0 unit. Unexpected Keyboard occupies the full width of the screen, and the row defining the highest number of units (in widths plus shifts) is as wide as the screen. A row whose width is a smaller number of units has empty space on the right.
### Extra legend
* `indication`: An optional extra legend to show under the main label. For example, `<key c="2" indication="ABC" />` displays ABC at the bottom of the 2 key, as on a pinpad or some telephones. If the key also defines a downward swipe with `s` or `key8`, the legends overlap.
### Possible key values
Built-in strings that assign a special function to a key are described in [this page](Possible-key-values.md). For example, `se="copy"` means a southeasterly swipe produces the Copy key. If a key value does not match any of the built-in strings, it outputs that text _verbatim_. For example, `c="a"` simply outputs the letter a.
In a layout, a key value can also start with the `loc` prefix. These are place-holders; the tap or swipe does nothing unless enabled through the "Add keys to keyboard" option in the Settings menu, or implicitly enabled by the language the device is set to use. For example, `ne="loc accent_aigu"` says that a northeast swipe produces the acute accent combinatorial key—if enabled.
## Modmap
The `<modmap>`...`</modmap>` pair encloses custom mappings for modifier keys. The modmap is placed inside the `<keyboard>`...`</keyboard>` pair, but outside any row. A layout can have at most one modmap. It can contain any number of mappings. Each mapping has an `a` property and a `b` property and maps the `a` key to the `b` key. Valid values are listed in [Possible key values](Possible-key-values.md).
The following mappings are supported:
```xml
<shift a="before" b="after" />
```
This means that when the Shift modifier is on, the key `before` is changed into `after`.
```xml
<fn a="before" b="after" />
```
This means that when the Fn modifier is on, the key `before` is changed into `after`.
```xml
<ctrl a="before" b="after" />
```
This means that when the Ctrl modifier is on, the key `before` is changed into `after`. The `<ctrl />` mapping is special in that the Ctrl modifier is applied to `after` after the mapping.
The clockwise circle and the round-trip gestures are affected by the `<fn />` mappings. Otherwise, they are defined by the Shift mappings (including the `<shift />` mappings), then, if that did not modify the key, the builtin Fn mappings are used instead.
### Examples
① Turkish keyboards use the Latin alphabet, but when "i" is shifted, it should produce "İ". This is achieved with the following mapping:
```xml
<shift a="i" b="İ" />
```
② Cyrillic layouts have no V key. A layout can define Ctrl-V with the following mapping:
```xml
<ctrl a="в" b="v" />
```
This maps Ctrl+в to Ctrl+V—not to v.
### Default mappings
Unexpected Keyboard's built-in mappings are not expressed as a modmap but by a series of .json files in `https://github.com/Julow/Unexpected-Keyboard/tree/master/srcs/compose`. For example, the mappings for `fn` are in [`fn.json`](https://github.com/Julow/Unexpected-Keyboard/blob/master/srcs/compose/fn.json). These built-in mappings are common to every language.
## Portrait vs. landscape
Unexpected Keyboard remembers *separately* which layout has last been used in portrait and landscape orientation. So you may have one custom layout for portrait orientation, but another custom layout for landscape orientation, and Unexpected Keyboard will switch between them without your intervention.
## Contributing your layout
The Unexpected Keyboard project enthusiastically accepts user contributions, including custom layouts. (See the guidance for layouts at [CONTRIBUTING.md](https://github.com/Julow/Unexpected-Keyboard/blob/master/CONTRIBUTING.md#Adding-a-layout)).
* Submit a layout that has innovations of possible interest to other users at [Unexpected-Keyboard-layouts](https://github.com/Julow/Unexpected-Keyboard-layouts).
* Propose that your layout be included in the set of built-in layouts by making a Pull Request for an addition to [srcs/layouts](https://github.com/Julow/Unexpected-Keyboard/tree/master/srcs/layouts). Please show that such a layout is standard in your locale or has a substantial number of users.
+213
View File
@@ -0,0 +1,213 @@
# Key values
A key value defines what a key on the keyboard does when pressed or swiped.
Key values appear in the following places:
- In custom layouts, they are the value of: the `c` attribute, the compass-point attributes `nw` ... `se`, and the old-style `key0` ... `key8` attributes.
- Internally, they are used in the definition of the "Add keys to the keyboard" setting.
Key values can be any of the following:
- The name of a special key. A complete list of valid special keys follows.
- An arbitrary sequence of characters not containing `:`.
This results in a key that writes the specified characters.
- The syntax `legend:key_def`.
`legend` is the visible legend on the keyboard. It cannot contain `:`.
`key_def` can be:
+ The name of a special key, as listed below.
+ `'string'` An arbitrary string that can contain `:`. `'` can be added to the string as `` \' ``.
+ `keyevent:keycode` An Android keycode. They are listed as `KEYCODE_...` in [KeyEvent](https://developer.android.com/reference/android/view/KeyEvent#summary).
Examples:
+ `⏯:keyevent:85` A play/pause key (which has no effect in most apps).
+ `my@:'my.email@domain.com'` A key that sends an arbitrary string
- A macro, `legend:key_def1,key_def2,...`.
This results in a key with legend `legend` that behaves as if the sequence of `key_def` had been pressed in order.
Examples:
+ `CA:ctrl,a,ctrl,c` A key with legend CA that sends the sequence `ctrl+a`, `ctrl+c`.
+ `Cd:ctrl,backspace` A key with legend Cd that sends the shortcut `ctrl+backspace`.
### Escape codes
When defining a key value, several characters have special effects. If you want a character not to have its usual effect but to be taken literally, you should "escape" it in the usual way for XML:
To get this character... | ...you can type
:---- | :------
A literal newline character, which is different from `enter` and `action` in certain apps. | `\n`
A literal tab character, which is different from `tab` in certain apps. | `\t`
`&` | `&amp;`
`<` | `&lt;`
`>` | `&gt;`
`"` | `&quot;`
The characters `\` (unless followed by n or t), `?`, `#`, and `@` do not need to be escaped when writing custom layouts. When writing a layout to be included in the app (in [srcs/layouts](https://github.com/Julow/Unexpected-Keyboard/tree/master/srcs/layouts)), they are represented by typing `\\`, `\?`, `\#`, and `\@`.
The characters `,` and `:` can be escaped in a key value, using single quotes. For example, this macro defines a key with legend `http` that sends a string containing `:`: `<key c="http:home,'https://'" />` For simplicity, `,` and `:` cannot be escaped in the key legend.
## Modifiers
System modifiers are sent to the app, which can take app-specific action.
Value | Meaning
:---------- | :------
`shift` | System modifier.
`ctrl` | System modifier.
`alt` | System modifier.
`meta` | System modifier. Equivalent to the Windows key.
The other modifiers take effect only within the keyboard.
Value | Meaning
:---------- | :------
`fn` | Activates Fn mode, which assigns letters and symbols to special characters. Example: `fn` `!` = `¡`
`compose` | Compose key. Enables composing characters using Linux-like shortcuts. Example: `Compose` `A` `'` types `Á` (A with acute accent).
`capslock` | Activates and locks Shift.
## App function keys
These keys are sent to apps, which are free to ignore them. The keyboard does not perform editing in response to these keys.
`esc`, `enter`,
`up`, `right`,
`down`, `left`,
`page_up`, `page_down`,
`home`, `end`,
`backspace`, `delete`,
`insert`, `scroll_lock`,
`f1`-`f12`,
`tab`, `copy`,
`paste`, `cut`,
`selectAll`, `pasteAsPlainText`,
`undo`, `redo`
## Keyboard editing actions
In contrast, these keys perform editing on the text without sending anything to the app.
Value | Meaning
:-------------------- | :------
`cursor_left` | Moves the cursor to the left with the slider gesture.
`cursor_right` | Moves the cursor to the right with the slider gesture.
`cursor_up` | Moves the cursor up with the slider gesture. Warning: this might make the cursor leave the text box.
`cursor_down` | Moves the cursor down with the slider gesture. Warning: this might make the cursor leave the text box.
`delete_word` | Delete the word to the left of the cursor.
`forward_delete_word` | Delete the word to the right of the cursor.
The values with `cursor_` are new in v1.31.0. Previous custom layouts specified the slider with `slider="true"`, which should be removed.
## Whitespace
Value | Meaning
:------ | :------
`space` | Space bar.
`nbsp` | Non-breaking space.
`nnbsp` | Narrow non-breaking space.
`zwj` | Zero-width joiner.
`zwnj` | Zero-width non-joiner.
## Other modifiers and diacritics
Value | Meaning
:------------------- | :------
`accent_aigu` | Acute accent. `á`
`accent_caron` | Háček. `č`
`accent_cedille` | Cedilla. `ç`
`accent_circonflexe` | Circumflex. `â`
`accent_grave` | Grave accent. `à`
`accent_macron` | Macron. `ā`
`accent_ring` | Ring accent. `å`
`accent_tilde` | Tilde. `ã`
`accent_trema` | Dieresis/umlaut. `ä`
`accent_ogonek` | Ogonek. `ą`
`accent_dot_above` | Dot accent. `ż` If applied to the lowercase `i`, removes the dot instead for Turkish. `ı`
`accent_double_aigu` | Double acute accent. `ő`
`accent_slash` | Slash through. `ø`
`accent_arrow_right` | Right arrow above, used to denote a vector. `a⃗`
`accent_breve` | Breve. `ă`
`accent_bar` | Bar/strikethrough. `ɨ`
`accent_dot_below` | Dot below. `ạ`
`accent_horn` | Horn accent. `ơ`
`accent_hook_above` | Hook accent. `ả`
`accent_double_grave` | Double grave accent. `ȁ`
`accent_small_caps` | Small capital letters. `ᴀ`
`superscript` | Superscript. `ᵃ`
`subscript` | Subscript. `ₐ`
`ordinal` | Turns `a` and `o` into `ª` and `º`.
`arrows` | Turns `1`-`4` and `6`-`9` into arrows.
`box` | Turns `1`-`9`, `0`, and `.` into single-line, thin box-drawing characters.
## Bidirectional
Value | Meaning
:------ | :------
`lrm` | Left-to-right mark.
`rlm` | Right-to-left mark.
`b(`, `b)`, `b[`, `b]`, `b{`, `b}`, `blt`, `bgt` | Sends the bracket characters, but with mirrored key legends for right-to-left languages. (`blt` and `bgt` print `<` and `>` respectively.)
## Arabic
These are the diacritics for Arabic
Value | Meaning
:------ | :------
`combining_fatha` | َ
`combining_dammah` | ُ
`combining_kasra` | ِ
`combining_sukun` | ْ
`combining_shaddah` | ّ
`combining_hamza_above` | ٔ
`combining_hamza_below` | ٕ
## Hebrew
Keys ending in `_placeholder` are normally hidden unless the Fn key is pressed.
`qamats`, `patah`,
`sheva`, `dagesh`,
`hiriq`, `segol`,
`tsere`, `holam`,
`qubuts`, `hataf_patah`,
`hataf_qamats`, `hataf_segol`,
`shindot`, `shindot_placeholder`,
`sindot`, `sindot_placeholder`,
`geresh`, `gershayim`,
`maqaf`, `rafe`,
`ole`, `ole_placeholder`,
`meteg`, `meteg_placeholder`
## Keyboard behavior keys
Value | Meaning
:--------------------- | :------
`config` | Gear icon; opens Unexpected Keyboard settings.
`switch_text` | Switch to the text layer (main layer).
`switch_numeric` | Switch to the numeric layer.
`switch_emoji` | Switch to the emoji layer.
`switch_back_emoji` | Switch to the text layer from the emoji layer.
`switch_forward` | Change the keyboard layout, as long as Unexpected Keyboard has multiple keyboard layouts enabled in the settings.
`switch_backward` | Change the keyboard layout to the previous one in the list.
`switch_greekmath` | Switch to the Greek & Math Symbols layer.
`switch_clipboard` | Switch to the clipboard pane.
`change_method` | Open the input method picker dialog.
`change_method_prev` | Switch to the previously used input method.
`action` | Performs a special context-sensitive operation related to the Enter key. For example, in the Twitter (X) app, `enter` adds a new line, while `action` posts.
`voice_typing` | Begin voice typing.
`voice_typing_chooser` | Shows a menu where you can choose which voice typing provider to use, then begins voice typing when you make a selection.
`shareText` | Emit a share Intent for the selected text. **Oddity:** This is in CamelCase.
`hide_self` | Hide the keyboard.
## Suggestions
Value | Meaning
:---- | :------
`complete_first` | Enter the best suggestion (the one in the middle)
`complete_second` | Enter the second best suggestion (the right one)
`complete_third` | Enter the third best suggestion (the left one)
`complete_emoji` | Enter the emoji suggestion
## Unused
These keys are known to do nothing.
`replaceText`, `textAssist`,
`autofill`, `removed`
## Placeholders
These keys are normally hidden unless the Fn modifier is activated.
`f11_placeholder` | `f12_placeholder`
@@ -0,0 +1,5 @@
الميزة الرئيسة هي إمكانية كتابة المزيد من الأحرف عن طريق تمرير المفاتيح نحو الزوايا.
صُمم هذا التطبيق في الأصل للمبرمجين الذين يستخدمون Termux.
أصبح الآن مثاليًا للاستخدام اليومي.
@@ -0,0 +1 @@
لوحة مفاتيح افتراضية خفيفة الوزن ومراعية للخصوصية لنظام أندرويد.
@@ -0,0 +1,6 @@
La característica principal és que pots escriure més caràcters arrossegant les tecles cap a les cantonades.
Aquesta aplicació va ser dissenyada originalment per als programadors que usen Termux.
Ara és perfecta per a un ús quotidià.
Aquesta aplicació no conté anuncis i és de codi obert.
@@ -0,0 +1 @@
Un teclat virtual lleuger per a Android que és conscient de la teva privacitat.
@@ -0,0 +1,6 @@
Hlavní funkcí je možnost psát více znaků posunutím kláves směrem k rohům.
Tato aplikace byla původně navržena pro programátory používající Termux.
Nyní je ideální pro každodenní použití.
Tato aplikace neobsahuje žádné reklamy a je Open Source.
@@ -3,4 +3,4 @@ Diese Tastatur zeichnet sich dadurch aus, dass man zusätzliche Zeichen durch Wi
Die Anwendung wurde ursprünglich für das Programmieren in Termux entwickelt.
Mittlerweile ist sie auch für den täglichen Gebrauch perfekt geeignet.
Diese App enthält keine Werbung, benötigt keinen Netzwerkzugriff und ist quelloffen.
Diese App enthält keine Werbung und ist quelloffen.
@@ -0,0 +1,8 @@
Improved custom layout option.
Allow selecting voice typing app with a long press.
The numpad can work with other numeral systems.
New and updated layouts.
New themes.
Many small improvements.
Thanks to the contributors: @pharook, @syskill, @ojas-bhagavath, @lrvideckis, @lyubomirv, @matthiakl, @deftkHD, @V6lhost, @RZHSSNZDH, @RetrogisusDEV, @rafasaurus, @krtsgnr7230, @eandersons, @ChasmSolacer, @Validbit, @polyctena
@@ -0,0 +1,7 @@
The custom vibration setting is back.
Allow to hide the keyboard switching key.
Fixed modifier keys in some development apps.
Updated translations.
Bug fixes and general improvements.
Many thanks to the contributors: @abb128, @marciozomb13, @RetrogisusDEV, @Sestowner, @vedamanavi, @krtsgnr7230
@@ -0,0 +1,6 @@
New layouts: QWERTY (Slovak), Gujarati phonetic
Add Linux Compose key to type a variety of characters using known combinations.
Fixed localized numpad and number row.
Many improvements and bug fixes.
Huge thanks to the contributors: @Yogesh-B, @ChasmSolacer, @matthiakl, @Sestowner, @RyanGibb, @BogdanLata, @RetrogisusDEV, @V6lhost, @ErrrorMaxx, @sdrapha, @vedamanavi
@@ -0,0 +1,11 @@
MessagEase and Thumb-Key inspired gestures with the anti-clockwise circle being
completely configurable.
Updated emojis.
Improved Hangul (Korean) support.
Added Danish support.
Improved spacebar slider.
Updated translations.
Various improvements and fixes to the app and layouts.
Many thanks to the contributors: @alotbsol555 @bkmgit @Cheesebaron @CloneWith @eandersons @JapanYoshi @Julow @la-ninpre @m15a @marciozomb13 @polyctena @solokot @Spike-from-NH @tmqCypher @Validbit
@@ -0,0 +1,8 @@
Clipboard pane
New Monet theme
Improvements to custom layouts
Options to disable key repeat and the circle gesture
Options to disable the Tab and Esc keys
Many thanks to the contributors: @alotbsol555 @ChasmSolacer @eandersons @polyctena @Sestowner @solokot @Spike-from-NH @TadaCZE @V6lhost @Validbit
@@ -0,0 +1,6 @@
Fix crash on Android 6.
Fix scaling issues for layouts with few columns.
Added Serbian layouts.
Layout and compose key tweaks. Improvements to custom layouts. Added Menu key.
Many thanks to the contributors: @adrian4096 @asivery @bokidori @dingodoppelt @RZHSSNZDH
@@ -0,0 +1,14 @@
New supported languages: Albanian, Belgian, Estonian, Georgian, Hawaiian,
Irish, Kannada, Kazakh, Old Church Slavonic, Serbian, Tajiki, Tamil, Welsh
Added WORKMAN (US) layout.
Improved layouts for modern Hindi and Sanskrit, Greek, Kurdish, Persian, Czech.
New compose sequences and added combining diacritic keys.
New and improved themes.
Many bug fixes and improvements.
Many thanks to the contributors: @anaskaejdar @bokidori @cknight828 @cuhsy
@Danger-Mkh @DocJr90 @IYO-OYI @kalankaboom @Kxeo @marciozomb13 @ms-jagadeeshan
@npnpatidar @ptitgnu @quantenzitrone @Sestowner @solokot @Spike-from-NH
@tenextractor
@@ -0,0 +1 @@
Bug fixes
@@ -0,0 +1 @@
Bug fixes
@@ -0,0 +1 @@
Bug fixes
@@ -0,0 +1,8 @@
Delete a word with a circle gesture on the delete key.
Compose key can be unselected.
Improved space bar slider and added selection mode.
Lock shift with a circle gesture.
Improvements to layouts.
Various bug fixes and improvements to themes.
Huge thanks to the contributors: @0skar2 @chuckwagoncomputing @dzaima @eandersons Lokesh Kumar @lrvideckis @ms-jagadeeshan @quantenzitrone @Sestowner @solokot @Spike-from-NH @srikanban @tenextractor
@@ -0,0 +1,9 @@
Bug fixes
Delete a word with a circle gesture on the delete key.
Compose key can be unselected.
Improved space bar slider and added selection mode.
Lock shift with a circle gesture.
Various bug fixes and improvements to themes and layouts.
Many thanks to the contributors: @HaleyHalcyon @Jaoheah @Spike-from-NH
@@ -0,0 +1,6 @@
Better support for foldable devices
Added layouts
Improved selection mode
Bug fixes and many other improvements
Huge thanks to the contributors: @alotbsol555, @bergentroll, @dacc9, @HaleyHalcyon, @Jaoheah, @jorexdeveloper, @malbajun, @matejdro, @Spike-from-NH, @tenextractor
@@ -0,0 +1 @@
Bug fixes
@@ -0,0 +1,6 @@
Spell checking and autocorrect are here !
This releases comes with a very large number of improvements,
support for more languages and new themes!
Huge thanks to the contributors: @10Develops @anaskaejdar @andyca111100 @Autissima @bqv @cillyvms @domportera @dzaima @exzombie @Harry-Ais0 @Houfalafel @JeelsBoobz @JFronny @Julow @lan700ng @malbajun @matejdro @n-ce @skynetcat @sperareine @Spike-from-NH @xxcavemanxx
@@ -0,0 +1,6 @@
Spell checking and autocorrect are here !
This releases comes with a very large number of improvements,
support for many languages and new themes!
Huge thanks to the contributors: @10Develops @anaskaejdar @andyca111100 @Autissima @bqv @cillyvms @domportera @dzaima @exzombie @Harry-Ais0 @Houfalafel @JeelsBoobz @JFronny @Julow @lan700ng @malbajun @matejdro @n-ce @skynetcat @sperareine @Spike-from-NH @xxcavemanxx
@@ -0,0 +1,3 @@
Bug fixes
Huge thanks to the contributors: @alotbsol555 @FlippingBinary
@@ -0,0 +1,6 @@
Spell checking and autocorrect are here !
This releases comes with a very large number of improvements,
support for many languages and new themes!
Huge thanks to the contributors: @10Develops @alotbsol555 @anaskaejdar @andyca111100 @Autissima @bqv @cillyvms @domportera @dzaima @exzombie @FlippingBinary @Harry-Ais0 @Houfalafel @JeelsBoobz @JFronny @Julow @lan700ng @malbajun @matejdro @n-ce @skynetcat @sperareine @Spike-from-NH @xxcavemanxx
@@ -0,0 +1 @@
Bug fixes
@@ -3,4 +3,4 @@ The main feature is that you can type more characters by swiping the keys toward
This application was originally designed for programmers using Termux.
Now perfect for everyday use.
This application contains no ads, doesn't make any network requests and is Open Source.
This application contains no ads and is Open Source.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

@@ -0,0 +1 @@
https://www.youtube.com/watch?v=rwGvWesPFX8
@@ -3,4 +3,4 @@ La característica principal es que hay acceso a más caractéres deslizando hac
Esta aplicación fue originalmente diseñada para programadores que usaran Termux.
Ahora es perfecta para uso cotidiano.
La misma no contiene ningún anuncio/publicidad, no realiza peticiones de red y es de Fuente Abierta.
La misma no contiene ningún anuncio/publicidad y es de Fuente Abierta.
@@ -0,0 +1,6 @@
Peamine omadus on see, et saad sisestada rohkem märke, viibates klahve nurkade suunas.
See rakendus loodi algselt Termuxit kasutavatele programmeerijatele.
Nüüd sobib see ideaalselt igapäevaseks kasutamiseks.
Rakendus ei sisalda reklaame ja on avatud lähtekoodiga.
@@ -0,0 +1 @@
Väike ja privaatsusteadlik klahvistik Androidile.
+1
View File
@@ -0,0 +1 @@
Ootamatu klahvistik
@@ -0,0 +1,6 @@
Ang pangunahing feature ay maaari kang mag-type ng mas marami pang karakter sa pag-swipe sa gilid ng mga key.
Noong simula, ginawa itong application para sa mga programmer sa na nagte-Termux.
Ngayo'y perpekto na sa pang-araw-araw.
Walang ads at Open Source ang application na ito.
@@ -0,0 +1 @@
Magaan at privacy-conscious na virtual keyboard sa Android.
@@ -3,4 +3,4 @@ La fonctionnalité principale est l'accès rapide à plus de caractères en bala
Cette application a été conçue à l'origine pour les programmeurs utilisant Termux.
Elle est maintenant parfaite pour une utilisation quotidienne.
Cette application ne contient pas de publicité, n'accède pas au réseau et est Open Source.
Cette application ne contient pas de publicité et est Open Source.

Some files were not shown because too many files have changed in this diff Show More