From 84b43f30dc5251a45e716f2a2856cd8086ceab63 Mon Sep 17 00:00:00 2001 From: Diamond White Date: Thu, 12 Mar 2026 03:06:27 +0000 Subject: [PATCH] use new prediction engine, move swipe type related logic to its own module --- Cargo.lock | 641 ++++++++++++++++++---- wayvr/Cargo.toml | 3 +- wayvr/src/overlays/keyboard/builder.rs | 25 +- wayvr/src/overlays/keyboard/layout.rs | 1 - wayvr/src/overlays/keyboard/mod.rs | 103 ++-- wayvr/src/overlays/keyboard/swipe_type.rs | 160 ++++-- wgui/src/event.rs | 4 + 7 files changed, 709 insertions(+), 228 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c134c9c4..ad97adda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -216,9 +216,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "appendlist" @@ -719,26 +719,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f09c37bc0e9f0924b7dae9988265ef3c76c88538f41a3b06caf4bed07cee5226" -[[package]] -name = "bincode" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" -dependencies = [ - "bincode_derive", - "serde", - "unty", -] - -[[package]] -name = "bincode_derive" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" -dependencies = [ - "virtue", -] - [[package]] name = "bindgen" version = "0.69.5" @@ -883,43 +863,32 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "bzip2" -version = "0.4.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" -dependencies = [ - "cc", - "pkg-config", + "libbz2-rs-sys", ] [[package]] name = "cached-path" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56aaf5c3daef0c2cc113b07a624b17317754fc2144821df7cb755c0a5494be3e" +checksum = "a9e79c94134331f0107c9f5b7caaf15f118ec91de67dcd3fa1145921e9fc27fa" dependencies = [ "flate2", "fs2", "glob", "infer", "log", - "rand 0.8.5", + "rand 0.10.0", "reqwest", "serde", "serde_json", "sha2", "tar", "tempfile", - "thiserror 1.0.69", + "thiserror 2.0.17", "zip", ] @@ -1044,6 +1013,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.0", +] + [[package]] name = "chrono" version = "0.4.42" @@ -1286,9 +1266,9 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.1.5" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "convert_case" @@ -1445,6 +1425,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -1699,6 +1688,22 @@ dependencies = [ "num-traits", ] +[[package]] +name = "deflate64" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2" + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.5.5" @@ -2119,6 +2124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", + "libz-rs-sys", "miniz_oxide", ] @@ -2239,6 +2245,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fst" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" + [[package]] name = "futures" version = "0.3.31" @@ -2391,10 +2403,26 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.0", + "wasip2", + "wasip3", + "wasm-bindgen", +] + [[package]] name = "gif" version = "0.14.1" @@ -2436,8 +2464,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.13", + "regex-syntax 0.8.8", ] [[package]] @@ -2584,6 +2612,12 @@ dependencies = [ "digest", ] +[[package]] +name = "hmac-sha256" +version = "1.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec9d92d097f4749b64e8cc33d924d9f40a2d4eb91402b458014b781f5733d60f" + [[package]] name = "hound" version = "3.5.1" @@ -2810,6 +2844,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -2880,7 +2920,7 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata", + "regex-automata 0.4.13", "same-file", "walkdir", "winapi-util", @@ -2962,6 +3002,8 @@ checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -3036,9 +3078,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" @@ -3231,12 +3273,24 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "lebe" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" +[[package]] +name = "libbz2-rs-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" + [[package]] name = "libc" version = "0.2.179" @@ -3341,6 +3395,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "libz-rs-sys" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" +dependencies = [ + "zlib-rs", +] + [[package]] name = "linebender_resource_handle" version = "0.1.1" @@ -3417,6 +3480,21 @@ dependencies = [ "hashbrown 0.16.1", ] +[[package]] +name = "lzma-rust2" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1670343e58806300d87950e3401e820b519b9384281bbabfb15e3636689ffd69" + +[[package]] +name = "lzma-rust2" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47bb1e988e6fb779cf720ad431242d3f03167c1b3f2b1aae7f1a94b2495b36ae" +dependencies = [ + "sha2", +] + [[package]] name = "mach2" version = "0.4.3" @@ -3432,7 +3510,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata", + "regex-automata 0.4.13", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" +dependencies = [ + "autocfg", + "rawpointer", ] [[package]] @@ -3451,6 +3539,16 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "memmap2" version = "0.9.9" @@ -3561,6 +3659,21 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ndarray" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "portable-atomic", + "portable-atomic-util", + "rawpointer", +] + [[package]] name = "ndk" version = "0.9.0" @@ -3695,6 +3808,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.2.0" @@ -4221,6 +4343,30 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "ort" +version = "2.0.0-rc.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7de3af33d24a745ffb8fab904b13478438d1cd52868e6f17735ef6e1f8bf133" +dependencies = [ + "ndarray", + "ort-sys", + "smallvec", + "tracing", + "ureq", +] + +[[package]] +name = "ort-sys" +version = "2.0.0-rc.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b497d21a8b6fbb4b5a544f8fadb77e801a09ae0add9e411d31c6f89e3c1e90" +dependencies = [ + "hmac-sha256", + "lzma-rust2 0.15.7", + "ureq", +] + [[package]] name = "os_pipe" version = "1.2.3" @@ -4329,17 +4475,6 @@ dependencies = [ "regex", ] -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "paste" version = "1.0.15" @@ -4360,14 +4495,21 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest", "hmac", - "password-hash", - "sha2", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", ] [[package]] @@ -4637,6 +4779,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppmd-rust" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efca4c95a19a79d1c98f791f10aebd5c1363b473244630bb7dbde1dc98455a24" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -4778,6 +4926,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" version = "0.7.3" @@ -4813,6 +4967,17 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +dependencies = [ + "chacha20", + "getrandom 0.4.2", + "rand_core 0.10.0", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -4870,6 +5035,12 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" + [[package]] name = "rand_hc" version = "0.2.0" @@ -4971,6 +5142,12 @@ dependencies = [ "objc2-quartz-core 0.3.2", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.11.0" @@ -5037,14 +5214,24 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.13", + "regex-syntax 0.8.8", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "fst", + "regex-syntax 0.6.29", ] [[package]] @@ -5055,9 +5242,15 @@ checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.8", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.8" @@ -5525,7 +5718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -5536,7 +5729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -5834,6 +6027,17 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "socks" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" +dependencies = [ + "byteorder", + "libc", + "winapi", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -5889,14 +6093,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] -name = "super-swipe-engine" -version = "0.1.11" -source = "git+https://github.com/oneshinyboi/swipeType?tag=v0.1.11#5f9ac506f97ffa60186cc74ab723340fd0362dd9" +name = "super-swipe-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32fd40ad969f38b55f6d1541d7c1a16226821b51a38362de7aa800f976632336" dependencies = [ - "bincode", + "anyhow", "cached-path", - "codes-iso-639", - "swipe-types", + "fst", + "memmap", + "ort", + "regex", + "regex-automata 0.1.10", + "vector2", ] [[package]] @@ -5926,16 +6135,6 @@ dependencies = [ "zeno", ] -[[package]] -name = "swipe-types" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebfd0c6e0e4aaf949ad93dedb75da61a531ce94a46fdd87c11830cfb7c32c8f" -dependencies = [ - "bincode", - "serde", -] - [[package]] name = "symphonia" version = "0.5.5" @@ -6207,6 +6406,7 @@ checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", + "js-sys", "num-conv", "powerfmt", "serde_core", @@ -6514,7 +6714,7 @@ dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex-automata", + "regex-automata 0.4.13", "sharded-slab", "smallvec", "thread_local", @@ -6549,6 +6749,12 @@ dependencies = [ "core_maths", ] +[[package]] +name = "typed-path" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" + [[package]] name = "typeid" version = "1.0.3" @@ -6637,6 +6843,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -6644,10 +6856,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] -name = "unty" -version = "0.0.4" +name = "ureq" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" +checksum = "fdc97a28575b85cfedf2a7e7d3cc64b3e11bd8ac766666318003abbacc7a21fc" +dependencies = [ + "base64", + "der", + "log", + "native-tls", + "percent-encoding", + "rustls-pki-types", + "socks", + "ureq-proto", + "utf-8", + "webpki-root-certs", +] + +[[package]] +name = "ureq-proto" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f" +dependencies = [ + "base64", + "http", + "httparse", + "log", +] [[package]] name = "url" @@ -6683,6 +6919,12 @@ dependencies = [ "xmlwriter", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -6731,6 +6973,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vector2" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f562f8d4f41867568374e1a63bd12914795f558319f9bf9b0582c4d96a8de04" + [[package]] name = "version-compare" version = "0.2.1" @@ -6743,12 +6991,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "virtue" -version = "0.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" - [[package]] name = "vk-parse" version = "0.15.0" @@ -6850,7 +7092,16 @@ version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.46.0", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", ] [[package]] @@ -6911,6 +7162,40 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.12.1", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.10.0", + "hashbrown 0.15.5", + "indexmap 2.12.1", + "semver", +] + [[package]] name = "wayland-backend" version = "0.3.12" @@ -7105,8 +7390,7 @@ dependencies = [ "smallvec", "smithay", "strum", - "super-swipe-engine", - "swipe-types", + "super-swipe-type", "sysinfo", "thiserror 2.0.17", "tracing", @@ -7175,6 +7459,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "weezl" version = "0.1.12" @@ -7720,6 +8013,94 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.12.1", + "prettyplease", + "syn 2.0.113", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.113", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.10.0", + "indexmap 2.12.1", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.12.1", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + [[package]] name = "wl-clipboard-rs" version = "0.9.3" @@ -8082,6 +8463,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] [[package]] name = "zerotrie" @@ -8118,24 +8513,37 @@ dependencies = [ [[package]] name = "zip" -version = "0.6.6" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "b680f2a0cd479b4cff6e1233c483fdead418106eae419dc60200ae9850f6d004" dependencies = [ "aes", - "byteorder", "bzip2", "constant_time_eq", "crc32fast", - "crossbeam-utils", + "deflate64", "flate2", + "getrandom 0.4.2", "hmac", + "indexmap 2.12.1", + "lzma-rust2 0.16.2", + "memchr", "pbkdf2", + "ppmd-rust", "sha1", "time", + "typed-path", + "zeroize", + "zopfli", "zstd", ] +[[package]] +name = "zlib-rs" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" + [[package]] name = "zmij" version = "1.0.10" @@ -8143,21 +8551,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30e0d8dffbae3d840f64bda38e28391faef673a7b5a6017840f2a106c8145868" [[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" +name = "zopfli" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ - "libc", "zstd-sys", ] diff --git a/wayvr/Cargo.toml b/wayvr/Cargo.toml index 1f4bbdf8..b225972d 100644 --- a/wayvr/Cargo.toml +++ b/wayvr/Cargo.toml @@ -87,10 +87,9 @@ xcb = { version = "1.6.0", optional = true, features = [ "as-raw-xcb-connection", ] } xkbcommon = { version = "0.8.0" } # 0.9.0 breaks keymap import on some distros -super-swipe-engine = {git="https://github.com/oneshinyboi/swipeType", tag="v0.1.11"} codes-iso-639 = "0.1.5" -swipe-types = "0.1.6" arboard = { version="3.6.1", features = ["wayland-data-control", "wl-clipboard-rs"] } +super-swipe-type = "0.1.2" [build-dependencies] diff --git a/wayvr/src/overlays/keyboard/builder.rs b/wayvr/src/overlays/keyboard/builder.rs index 18783ca8..2094836c 100644 --- a/wayvr/src/overlays/keyboard/builder.rs +++ b/wayvr/src/overlays/keyboard/builder.rs @@ -27,7 +27,7 @@ use wgui::{ widget::{EventResult, div::WidgetDiv, rectangle::WidgetRectangle}, }; use crate::overlays::keyboard::layout::KeyData; -use super::{KeyButtonData, KeyState, KeyboardState, handle_press, handle_release, layout::{self, KeyCapType}, handle_enter}; +use super::{KeyButtonData, KeyState, KeyboardState, handle_press, handle_release, layout::{self, KeyCapType}, handle_mouse_motion}; const PIXELS_PER_UNIT: f32 = 60.; @@ -179,8 +179,6 @@ pub(super) fn create_keyboard_panel( EventListenerKind::MouseEnter, Box::new({ let k = key_state.clone(); - let k_label = key_label.clone(); - let k_cap_type = key_cap_type.clone(); move |common, data, _app, state| { common.alterables.trigger_haptics(); on_enter_anim( @@ -192,7 +190,7 @@ pub(super) fn create_keyboard_panel( width_mul, ); - handle_enter(&k, &k_label, &k_cap_type, state); + Ok(EventResult::Pass) } }), @@ -228,19 +226,34 @@ pub(super) fn create_keyboard_panel( let CallbackMetadata::MouseButton(button) = data.metadata else { panic!("CallbackMetadata should contain MouseButton!"); }; + let within_key_pos = data.metadata.get_mouse_pos_normalized(&common.alterables.transform_stack); - handle_press(app, &k, &k_cap_type, &k_label, state, button); + handle_press(app, &k, &k_label, &k_cap_type, &within_key_pos, state, button); on_press_anim(k.clone(), common, data); Ok(EventResult::Pass) } }), ); + panel.add_event_listener( + widget_id, + EventListenerKind::MouseMotion, + Box::new({ + let k = key_state.clone(); + let k_label = key_label.clone(); + let k_cap_type = key_cap_type.clone(); + move |common, data, app, state| { + let within_key_pos = data.metadata.get_mouse_pos_normalized(&common.alterables.transform_stack); + + handle_mouse_motion(&k, &k_label, &k_cap_type, state, &within_key_pos); + Ok(EventResult::Pass) + } + }), + ); panel.add_event_listener( widget_id, EventListenerKind::MouseRelease, Box::new({ let k = key_state.clone(); - let k_label = key_label.clone(); let k_cap_type = key_cap_type.clone(); move |common, data, app, state| { if handle_release(app, &k, &k_cap_type, state) { diff --git a/wayvr/src/overlays/keyboard/layout.rs b/wayvr/src/overlays/keyboard/layout.rs index b53d7b65..f65e3bd0 100644 --- a/wayvr/src/overlays/keyboard/layout.rs +++ b/wayvr/src/overlays/keyboard/layout.rs @@ -3,7 +3,6 @@ use std::{collections::HashMap, str::FromStr, sync::LazyLock}; use regex::Regex; use serde::{Deserialize, Serialize}; use smithay::reexports::wayland_protocols::wp::pointer_gestures::zv1::server::zwp_pointer_gesture_swipe_v1::ZwpPointerGestureSwipeV1; -use swipe_types::types::Point; use crate::{ config::{ConfigType, load_known_yaml}, subsystem::hid::{ diff --git a/wayvr/src/overlays/keyboard/mod.rs b/wayvr/src/overlays/keyboard/mod.rs index ff359c97..9ab63a11 100644 --- a/wayvr/src/overlays/keyboard/mod.rs +++ b/wayvr/src/overlays/keyboard/mod.rs @@ -28,10 +28,9 @@ use crate::{ }; use anyhow::Context; use arboard::Clipboard; -use glam::{Affine3A, Quat, Vec3, vec3}; +use glam::{Affine3A, Quat, Vec3, vec3, Vec2}; use regex::Regex; use slotmap::{SlotMap, new_key_type}; -use super_swipe_engine::SwipeEngine; use wgui::{ drawing, event::{InternalStateChangeEvent, MouseButtonEvent, MouseButtonIndex}, @@ -43,7 +42,7 @@ use wlx_common::{ }; use codes_iso_639::part_1::LanguageCode; use crate::overlays::keyboard::layout::KeyCapType; -use crate::overlays::keyboard::swipe_type::{copy_text_to_primary_clipboard, create_new_swipe_engine}; +use crate::overlays::keyboard::swipe_type::SwipeTypingManager; pub mod builder; mod layout; @@ -62,12 +61,7 @@ pub fn create_keyboard(app: &mut AppState, wayland: bool) -> anyhow::Result anyhow::Result { let mut state = self.default_state.take(); - state.swipe_engine = match create_new_swipe_engine(&keymap, &self.wlx_layout) { + state.swipe_typing_manager = match SwipeTypingManager::new() { Ok(engine) => Some(engine), Err(e) => { log::error!("Error occured while trying to load swipe engine: {:?}", e); @@ -217,7 +211,7 @@ impl KeyboardBackend { .state .take(); - state_from.swipe_engine = match create_new_swipe_engine(&Some(keymap), &self.wlx_layout) { + state_from.swipe_typing_manager = match SwipeTypingManager::new() { Ok(engine) => Some(engine), Err(e) => { log::error!("Error occured while trying to load swipe engine: {:?}", e); @@ -357,15 +351,7 @@ struct KeyboardState { overlay_list: OverlayList, set_list: SetList, clock_12h: bool, - - // todo move all this swipe stuff into its own class - swipe_engine: Option, - current_swipe_input: String, - last_pressed_key_label: String, - is_swiping: bool, - clipboard: Clipboard, - last_swiped_word: Option - + swipe_typing_manager: Option, } macro_rules! take_and_leave_default { @@ -385,12 +371,7 @@ impl KeyboardState { overlay_list: OverlayList::default(), set_list: SetList::default(), clock_12h: self.clock_12h, - swipe_engine: None, - current_swipe_input: String::new(), - is_swiping: false, - last_pressed_key_label: String::new(), - clipboard: Clipboard::new().unwrap(), - last_swiped_word: None + swipe_typing_manager: None, } } } @@ -431,37 +412,44 @@ enum KeyButtonData { }, } -fn handle_enter(key: &KeyState, key_label: &Vec, key_cap_type: &KeyCapType, keyboard: &mut KeyboardState) { - if let Some(_) = keyboard.swipe_engine.as_ref() && *key_cap_type == KeyCapType::Letter { - if *key_label.iter().next().unwrap() != keyboard.last_pressed_key_label { - keyboard.is_swiping = true; - } - if keyboard.is_swiping { +fn handle_mouse_motion(key: &KeyState, key_label: &Vec, key_cap_type: &KeyCapType, keyboard: &mut KeyboardState, within_key_pos: &Option) { + if let Some(swipe_manager) = keyboard.swipe_typing_manager.as_mut() && *key_cap_type == KeyCapType::Letter { + if !swipe_manager.is_current_swipe_empty() { match &key.button_state { KeyButtonData::Key { vk, pressed } => { - keyboard.current_swipe_input.push_str(&*key_label.iter().next().unwrap().to_ascii_lowercase()) + if let Some(pos) = within_key_pos { + // check because mouse motion can trigger despite hover being false + if pos.x >= 0.0 && pos.x <= 1.0 && pos.y >= 0.0 && pos.y <= 1.0 { + + if let Some(label) = key_label.first() { + swipe_manager.add_swipe(pos, label.chars().next().unwrap_or_default()); + } + } + } } _ => {} } } } + } fn handle_press( app: &mut AppState, key: &KeyState, - key_cap_type: &KeyCapType, key_label: &Vec, + key_cap_type: &KeyCapType, + within_key_pos: &Option, keyboard: &mut KeyboardState, button: MouseButtonEvent, ) { - keyboard.is_swiping = false; match &key.button_state { KeyButtonData::Key { vk, pressed } => { - if let Some(_) = keyboard.swipe_engine.as_ref() && *key_cap_type == KeyCapType::Letter { - let actual_label = key_label.iter().next().unwrap(); - keyboard.last_pressed_key_label = actual_label.clone(); - keyboard.current_swipe_input.clear(); - keyboard.current_swipe_input.push_str(&*actual_label.to_ascii_lowercase()) + if let Some(swipe_manager) = keyboard.swipe_typing_manager.as_mut() && *key_cap_type == KeyCapType::Letter { + if let Some(pos) = within_key_pos { + if let Some(label) = key_label.first() { + swipe_manager.add_swipe(pos, label.chars().next().unwrap_or_default()); + } + } } else { keyboard.modifiers |= match button.index { @@ -508,29 +496,23 @@ fn handle_press( fn handle_release(app: &mut AppState, key: &KeyState, k_cap_type: &KeyCapType, keyboard: &mut KeyboardState) -> bool { match &key.button_state { KeyButtonData::Key { vk, pressed } => { - if let Some(engine) = keyboard.swipe_engine.as_ref() && *k_cap_type == KeyCapType::Letter { - if keyboard.is_swiping { - if !keyboard.current_swipe_input.is_empty() { - let prediction = engine.predict(&*keyboard.current_swipe_input, keyboard.last_swiped_word.as_ref().map(|x| x.as_str()), 5); - keyboard.current_swipe_input.clear(); - println!("swipe path: {}", keyboard.current_swipe_input); - println!("{:?}", prediction); - - let best_prediction = prediction.first().unwrap().word.as_ref(); - - copy_text_to_primary_clipboard(best_prediction, &mut keyboard.clipboard); - app.hid_provider - .set_modifiers_routed(app.wvr_server.as_mut(), SHIFT); - app.hid_provider - .send_key_routed(app.wvr_server.as_mut(), VirtualKey::Insert, true); - app.hid_provider - .send_key_routed(app.wvr_server.as_mut(), VirtualKey::Insert, false); - app.hid_provider - .set_modifiers_routed(app.wvr_server.as_mut(), keyboard.modifiers); - keyboard.last_swiped_word = Some(best_prediction.parse().unwrap()) + if let Some(swipe_manager) = keyboard.swipe_typing_manager.as_mut() && *k_cap_type == KeyCapType::Letter { + if swipe_manager.swipe_left_first_key() { + match swipe_manager.predict() { + Ok(predictions) => { + let best_prediction = predictions.first().unwrap(); + println!("best prediction for swipe: {best_prediction}"); + + swipe_manager.select_word(&best_prediction, app, keyboard.modifiers); + }, + Err(e) => { + log::error!("{}", e) + } } } else { // pointer must have been released on the same key it was pressed on + swipe_manager.reset(); // drop swipe tracking that was started on press + app.hid_provider .send_key_routed(app.wvr_server.as_mut(), *vk, true); pressed.set(true); @@ -538,7 +520,6 @@ fn handle_release(app: &mut AppState, key: &KeyState, k_cap_type: &KeyCapType, k .send_key_routed(app.wvr_server.as_mut(), *vk, false); play_key_click(app); } - } else { pressed.set(false); diff --git a/wayvr/src/overlays/keyboard/swipe_type.rs b/wayvr/src/overlays/keyboard/swipe_type.rs index 0ab7816b..ca25c945 100644 --- a/wayvr/src/overlays/keyboard/swipe_type.rs +++ b/wayvr/src/overlays/keyboard/swipe_type.rs @@ -1,53 +1,119 @@ -use std::collections::HashMap; -use arboard::{Clipboard, LinuxClipboardKind, SetExtLinux}; -use codes_iso_639::part_1::LanguageCode; -use futures::TryFutureExt; -use strum::IntoEnumIterator; -use super_swipe_engine::{EngineLoadError, SwipeEngine}; -use swipe_types::types::Point; -use crate::overlays::keyboard::layout; -use crate::overlays::keyboard::layout::KeyCapType; -use crate::subsystem::hid::{get_key_type, KeyType, VirtualKey, XkbKeymap}; +use crate::state::AppState; +use crate::subsystem::hid::{KeyModifier, VirtualKey, CTRL}; +use anyhow::bail; +use arboard::Clipboard; +use glam::Vec2; +use std::mem; +use std::time::Instant; +use super_swipe_type::keyboard_manager::QwertyKeyboardGrid; +use super_swipe_type::swipe_orchestrator::SwipeOrchestrator; +use super_swipe_type::{SwipeCandidate, SwipePoint}; -pub fn copy_text_to_primary_clipboard(text: &str, clip: &mut Clipboard) { - - println!("{}", std::env::var("WAYLAND_DISPLAY").unwrap()); - clip.set_text(format!("{text} ")).unwrap(); +pub struct SwipeTypingManager { + swipe_engine: SwipeOrchestrator, + keyboard_gird: QwertyKeyboardGrid, + current_swipe: Vec, + swipe_start_time: Option, + clipboard: Clipboard, + swipe_left_first_key: bool, + first_swipe_char: char, + last_swiped_word: Option } -pub fn create_new_swipe_engine(keymap: &Option<&XkbKeymap>, layout: &layout::Layout) -> Result { - let layout_name = keymap.and_then(|k| k.get_name()).unwrap_or("us"); - let point_map = build_key_to_char_point_map(*keymap, layout); +impl SwipeTypingManager { - // todo: use the layout_name to choose a sensible language for the swipe engine - SwipeEngine::new(LanguageCode::En, Some(point_map)) -} -fn build_key_to_char_point_map(keymap: Option<&XkbKeymap>, layout: &layout::Layout) -> HashMap { - let mut map = HashMap::new(); - - let has_altgr = keymap.as_ref().is_some_and(|m| XkbKeymap::has_altgr(m)); - let mut pos_x: f32 = 0.0; - let mut pos_y: f32 = 0.0; - - for (row_idx, row) in layout.main_layout.iter().enumerate() { - for (col_idx, col) in row.iter().enumerate() { - - let label = layout.get_key_data(keymap, has_altgr, col_idx, row_idx); - if let Some(label) = label { - match label.cap_type { - KeyCapType::Letter => { - if let Some(char) = label.label.iter().next() { - let point = Point {x: pos_x as f64, y: pos_y as f64}; - println!("char: {} \n point: {:?}\n",char, point); - map.insert(char.to_ascii_lowercase().chars().next().unwrap(), point); - } - } - _ => {} - } - } - pos_x += layout.key_sizes[row_idx][col_idx]; + /// Attempts to "type" the word by copying to clipboard and pasting + pub fn select_word(&mut self, word: &String, app: &mut AppState, original_keyboard_mods: KeyModifier) { + self.last_swiped_word = Some(word.clone()); + if let Ok(_) =self.copy_text_to_primary_clipboard(word.as_ref()) { + Self::paste(app, original_keyboard_mods); } - pos_y += 1.0; - pos_x = 0.0; } - map + fn paste(app: &mut AppState, original_keyboard_mods: KeyModifier) { + app.hid_provider + .set_modifiers_routed(app.wvr_server.as_mut(), CTRL); + app.hid_provider + .send_key_routed(app.wvr_server.as_mut(), VirtualKey::V, true); + app.hid_provider + .send_key_routed(app.wvr_server.as_mut(), VirtualKey::V, false); + app.hid_provider + .set_modifiers_routed(app.wvr_server.as_mut(), original_keyboard_mods); + } + fn copy_text_to_primary_clipboard(&mut self, text: &str) -> Result<(), arboard::Error> { + println!("{}", std::env::var("WAYLAND_DISPLAY").unwrap()); + self.clipboard.set_text(format!("{text} ")) + } + pub fn new() -> anyhow::Result { + // todo: use the layout_name to choose a sensible language for the swipe engine + + Ok(Self { + swipe_engine: SwipeOrchestrator::new()?, + keyboard_gird: QwertyKeyboardGrid::new(), // contains a hashmap where the vector2 is the center pos of each key in querty + current_swipe: Vec::new(), + swipe_start_time: None, + clipboard: Clipboard::new()?, + swipe_left_first_key: false, + first_swipe_char: char::default(), + last_swiped_word: None + }) + } + pub fn predict(&mut self) -> anyhow::Result>{ + if self.is_current_swipe_empty() { + bail!("nothing to predict"); + } else { + let current_swipe = mem::take(&mut self.current_swipe); + self.reset(); + + let candidates: Vec = self.swipe_engine.predict(current_swipe, &self.last_swiped_word)?; + Ok(candidates.iter().map(|c| c.word.clone()).collect()) + } + } + pub fn reset(&mut self) { + self.last_swiped_word = None; + self.swipe_start_time = None; + self.current_swipe = Vec::new(); + self.first_swipe_char = char::default(); + self.swipe_left_first_key = false; + } + pub fn swipe_left_first_key(&self) -> bool { + self.swipe_left_first_key + } + pub fn is_current_swipe_empty(&self) -> bool { + self.current_swipe.is_empty() + } + pub fn add_swipe(&mut self, within_key_pos_normalized: &Vec2, key_label: char) { + if let Some(pos) = self.keyboard_gird.key_positions.get(&key_label.to_ascii_lowercase()) { + if self.first_swipe_char != char::default() && self.first_swipe_char != key_label.to_ascii_lowercase() { + self.swipe_left_first_key = true; + } + let key_pos = Vec2{x: pos.x as f32, y: pos.y as f32 }; + println!("char : {key_label} at pos: {key_pos}"); + let start_time = match self.swipe_start_time { + Some(time) => time, + None => { + // this is the first swipe entry + let now = Instant::now(); + self.swipe_start_time = Some(now); + self.first_swipe_char = key_label.to_ascii_lowercase(); + now + } + }; + + let within_key_pos_from_center = Vec2 { + x: within_key_pos_normalized.x - 0.5, + y: 0.5 - within_key_pos_normalized.y, + }; + let key_dimensions = Vec2 { + x: QwertyKeyboardGrid::get_key_width() as f32, + y: QwertyKeyboardGrid::get_key_width() as f32, + }; + + let point = within_key_pos_from_center*key_dimensions + key_pos; + let duration = Instant::now().duration_since(start_time); + self.current_swipe.push(SwipePoint::new(point.x.into(), point.y.into(), duration)) + } + + } + + + } diff --git a/wgui/src/event.rs b/wgui/src/event.rs index 57417808..244471c8 100644 --- a/wgui/src/event.rs +++ b/wgui/src/event.rs @@ -219,6 +219,10 @@ impl CallbackMetadata { let mouse_pos_abs = self.get_mouse_pos_absolute()?; Some(mouse_pos_abs - transform_stack.get().abs_pos) } + pub fn get_mouse_pos_normalized(&self, transform_stack: &TransformStack) -> Option { + let pos_relative = self.get_mouse_pos_relative(transform_stack)?; + Some(pos_relative/transform_stack.parent().raw_dim) + } } #[derive(Debug, Clone, Copy, PartialEq, Eq)]