/,
- 'typeless translation should occupy its own layout row between the rail and capsule',
+ capsuleLayoutTs,
+ /value === 'typeless'\) return 'classic'/,
+ 'legacy Typeless preferences and events must resolve to the OpenLess default',
);
assertMatch(
capsuleStylesCss,
diff --git a/openless-all/app/src-tauri/Cargo.lock b/openless-all/app/src-tauri/Cargo.lock
index d6c9d307d..a07716e7d 100644
--- a/openless-all/app/src-tauri/Cargo.lock
+++ b/openless-all/app/src-tauri/Cargo.lock
@@ -437,29 +437,6 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
-[[package]]
-name = "aws-lc-rs"
-version = "1.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "faac5829c2b74c28f830747e7818ccfb684261b5f48a1118b1e2a13d36dfab13"
-dependencies = [
- "aws-lc-sys",
- "zeroize",
-]
-
-[[package]]
-name = "aws-lc-sys"
-version = "0.46.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1622d8446a2d4b2ce0c7eefc73dd43a99779028d5ee5c2dd8073a658ba8a2bc"
-dependencies = [
- "cc",
- "cmake",
- "dunce",
- "fs_extra",
- "pkg-config",
-]
-
[[package]]
name = "axum"
version = "0.7.9"
@@ -988,15 +965,6 @@ dependencies = [
"error-code",
]
-[[package]]
-name = "cmake"
-version = "0.1.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
-dependencies = [
- "cc",
-]
-
[[package]]
name = "cmov"
version = "0.5.4"
@@ -2172,12 +2140,6 @@ dependencies = [
"zip 2.6.1",
]
-[[package]]
-name = "fs_extra"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
-
[[package]]
name = "fst"
version = "0.4.7"
@@ -3893,16 +3855,6 @@ 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",
- "serde",
-]
-
[[package]]
name = "num-bigint-dig"
version = "0.8.6"
@@ -3919,6 +3871,16 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "num-complex"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
+dependencies = [
+ "num-traits",
+ "serde",
+]
+
[[package]]
name = "num-conv"
version = "0.2.2"
@@ -4531,7 +4493,7 @@ dependencies = [
"once_cell",
"parking_lot",
"regex",
- "reqwest 0.13.5",
+ "reqwest 0.12.28",
"serde",
"serde_json",
"sha1 0.11.0",
@@ -5147,7 +5109,6 @@ version = "0.11.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e750cca55fe4f0439a15d0bb529da9651e79993e8e72c61a899a36d462befbe"
dependencies = [
- "aws-lc-rs",
"bytes",
"getrandom 0.4.3",
"lru-slab",
@@ -5436,16 +5397,13 @@ dependencies = [
"hyper-util",
"js-sys",
"log",
- "mime_guess",
"percent-encoding",
"pin-project-lite",
- "quinn",
"rustls",
"rustls-pki-types",
"rustls-platform-verifier",
"serde",
"serde_json",
- "serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-rustls",
@@ -5615,7 +5573,6 @@ version = "0.23.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e13bd8c0e9365c43cfa5c9e8f9ad49d3c8444926c9aac819e0e4dc503c8fdf"
dependencies = [
- "aws-lc-rs",
"log",
"once_cell",
"ring",
@@ -5680,7 +5637,6 @@ version = "0.103.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
dependencies = [
- "aws-lc-rs",
"ring",
"rustls-pki-types",
"untrusted",
diff --git a/openless-all/app/src-tauri/Cargo.toml b/openless-all/app/src-tauri/Cargo.toml
index b631ed04c..d95d78684 100644
--- a/openless-all/app/src-tauri/Cargo.toml
+++ b/openless-all/app/src-tauri/Cargo.toml
@@ -61,6 +61,7 @@ tokio = { version = "1", features = ["full"] }
tokio-tungstenite = { version = "0.24", features = ["rustls-tls-webpki-roots"] }
futures-util = "0.3"
reqwest = { version = "0.12", default-features = false, features = ["json", "multipart", "rustls-tls", "stream", "system-proxy"] }
+rustls = { version = "^0.23", default-features = false, features = ["ring", "std", "tls12", "logging"] }
zip = "2"
thiserror = "1"
anyhow = "1"
@@ -97,7 +98,6 @@ x509-parser = { version = "0.16", features = ["verify"] }
time = "0.3"
tempfile = "3"
local-ip-address = "^0.6"
-rustls = { version = "^0.23", default-features = false, features = ["ring", "std", "tls12", "logging"] }
tokio-rustls = { version = "^0.26", default-features = false, features = ["ring", "tls12", "logging"] }
axum = { version = "^0.7", default-features = false, features = ["ws", "http1", "tokio", "query"] }
hyper = { version = "^1", features = ["server", "http1"] }
diff --git a/openless-all/app/src-tauri/backend-tests/Cargo.lock b/openless-all/app/src-tauri/backend-tests/Cargo.lock
index 8b9df454f..13773b023 100644
--- a/openless-all/app/src-tauri/backend-tests/Cargo.lock
+++ b/openless-all/app/src-tauri/backend-tests/Cargo.lock
@@ -145,29 +145,6 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
-[[package]]
-name = "aws-lc-rs"
-version = "1.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "faac5829c2b74c28f830747e7818ccfb684261b5f48a1118b1e2a13d36dfab13"
-dependencies = [
- "aws-lc-sys",
- "zeroize",
-]
-
-[[package]]
-name = "aws-lc-sys"
-version = "0.46.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1622d8446a2d4b2ce0c7eefc73dd43a99779028d5ee5c2dd8073a658ba8a2bc"
-dependencies = [
- "cc",
- "cmake",
- "dunce",
- "fs_extra",
- "pkg-config",
-]
-
[[package]]
name = "base16ct"
version = "0.2.0"
@@ -399,15 +376,6 @@ dependencies = [
"libloading",
]
-[[package]]
-name = "cmake"
-version = "0.1.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
-dependencies = [
- "cc",
-]
-
[[package]]
name = "cmov"
version = "0.5.4"
@@ -455,16 +423,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "core-foundation"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
@@ -501,7 +459,7 @@ dependencies = [
"core-foundation-sys",
"coreaudio-rs",
"dasp_sample",
- "jni 0.21.1",
+ "jni",
"js-sys",
"libc",
"mach2",
@@ -589,12 +547,6 @@ dependencies = [
"cmov",
]
-[[package]]
-name = "dasp_sample"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
-
[[package]]
name = "curve25519-dalek"
version = "4.1.3"
@@ -622,6 +574,12 @@ dependencies = [
"syn 2.0.119",
]
+[[package]]
+name = "dasp_sample"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
+
[[package]]
name = "data-encoding"
version = "2.11.1"
@@ -701,12 +659,6 @@ dependencies = [
"syn 3.0.9",
]
-[[package]]
-name = "dunce"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
-
[[package]]
name = "easyfft"
version = "0.4.2"
@@ -720,12 +672,6 @@ dependencies = [
"rustfft",
]
-[[package]]
-name = "either"
-version = "1.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be"
-
[[package]]
name = "ecdsa"
version = "0.16.9"
@@ -764,6 +710,12 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "either"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be"
+
[[package]]
name = "elliptic-curve"
version = "0.13.8"
@@ -886,12 +838,6 @@ dependencies = [
"percent-encoding",
]
-[[package]]
-name = "fs_extra"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
-
[[package]]
name = "fst"
version = "0.4.7"
@@ -1142,6 +1088,7 @@ dependencies = [
"tokio",
"tokio-rustls",
"tower-service",
+ "webpki-roots 1.0.9",
]
[[package]]
@@ -1354,36 +1301,6 @@ dependencies = [
"windows-sys 0.45.0",
]
-[[package]]
-name = "jni"
-version = "0.22.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
-dependencies = [
- "cfg-if",
- "combine",
- "jni-macros",
- "jni-sys 0.4.1",
- "log",
- "simd_cesu8",
- "thiserror 2.0.21",
- "walkdir",
- "windows-link",
-]
-
-[[package]]
-name = "jni-macros"
-version = "0.22.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
-dependencies = [
- "proc-macro2",
- "quote",
- "rustc_version",
- "simd_cesu8",
- "syn 2.0.119",
-]
-
[[package]]
name = "jni-sys"
version = "0.3.1"
@@ -1698,16 +1615,6 @@ 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",
- "serde",
-]
-
[[package]]
name = "num-bigint-dig"
version = "0.8.6"
@@ -1724,6 +1631,16 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "num-complex"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
+dependencies = [
+ "num-traits",
+ "serde",
+]
+
[[package]]
name = "num-conv"
version = "0.2.2"
@@ -1823,7 +1740,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb"
dependencies = [
- "jni 0.21.1",
+ "jni",
"ndk",
"ndk-context",
"num-derive",
@@ -1921,12 +1838,6 @@ dependencies = [
"zip",
]
-[[package]]
-name = "openssl-probe"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
-
[[package]]
name = "p256"
version = "0.13.2"
@@ -2148,39 +2059,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "494b4379484fc92217cc7d9e3a532375b1d01a61889ec8333025dc3b0377af56"
[[package]]
-name = "primal-check"
-version = "0.3.4"
+name = "ppv-lite86"
+version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc0d895b311e3af9902528fbb8f928688abbd95872819320517cc24ca6b2bd08"
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
- "num-integer",
+ "zerocopy",
]
[[package]]
-name = "proc-macro-crate"
-version = "3.5.0"
+name = "primal-check"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
+checksum = "dc0d895b311e3af9902528fbb8f928688abbd95872819320517cc24ca6b2bd08"
dependencies = [
- "toml_edit",
+ "num-integer",
]
[[package]]
-name = "ppv-lite86"
-version = "0.2.21"
+name = "primeorder"
+version = "0.13.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
+checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
dependencies = [
- "zerocopy",
+ "elliptic-curve",
]
[[package]]
-name = "primeorder"
-version = "0.13.6"
+name = "proc-macro-crate"
+version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
+checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
dependencies = [
- "elliptic-curve",
+ "toml_edit",
]
[[package]]
@@ -2238,7 +2149,6 @@ version = "0.11.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e750cca55fe4f0439a15d0bb529da9651e79993e8e72c61a899a36d462befbe"
dependencies = [
- "aws-lc-rs",
"bytes",
"getrandom 0.4.3",
"lru-slab",
@@ -2421,11 +2331,11 @@ dependencies = [
[[package]]
name = "reqwest"
-version = "0.13.5"
+version = "0.12.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16a1cfa75cc186dd73d5818e510e042e40927bccc9c236b061cea97e1eb08029"
+checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [
- "base64 0.23.1",
+ "base64 0.22.1",
"bytes",
"futures-core",
"futures-util",
@@ -2443,7 +2353,6 @@ dependencies = [
"quinn",
"rustls",
"rustls-pki-types",
- "rustls-platform-verifier",
"serde",
"serde_json",
"serde_urlencoded",
@@ -2459,6 +2368,7 @@ dependencies = [
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
+ "webpki-roots 1.0.9",
]
[[package]]
@@ -2592,7 +2502,6 @@ version = "0.23.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e13bd8c0e9365c43cfa5c9e8f9ad49d3c8444926c9aac819e0e4dc503c8fdf"
dependencies = [
- "aws-lc-rs",
"once_cell",
"ring",
"rustls-pki-types",
@@ -2601,18 +2510,6 @@ dependencies = [
"zeroize",
]
-[[package]]
-name = "rustls-native-certs"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a073f5dc7469f984c52ad2752b63b0807745133b6de880b7b64c1ac4c48aec4"
-dependencies = [
- "openssl-probe",
- "rustls-pki-types",
- "schannel",
- "security-framework",
-]
-
[[package]]
name = "rustls-pki-types"
version = "1.15.1"
@@ -2623,40 +2520,12 @@ dependencies = [
"zeroize",
]
-[[package]]
-name = "rustls-platform-verifier"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1167586491e2b18b8bfbb293e8180ec17c201c4f076d7cb3070ca964e7598f98"
-dependencies = [
- "core-foundation 0.10.1",
- "core-foundation-sys",
- "jni 0.22.4",
- "log",
- "once_cell",
- "rustls",
- "rustls-native-certs",
- "rustls-platform-verifier-android",
- "rustls-webpki",
- "security-framework",
- "security-framework-sys",
- "webpki-root-certs",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "rustls-platform-verifier-android"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eec689c0bc40ff2458a5977b6619cb718087084a18e02a131c599b62d05e1a5f"
-
[[package]]
name = "rustls-webpki"
version = "0.103.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
dependencies = [
- "aws-lc-rs",
"ring",
"rustls-pki-types",
"untrusted",
@@ -2683,15 +2552,6 @@ dependencies = [
"winapi-util",
]
-[[package]]
-name = "schannel"
-version = "0.1.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cb23c424d8ee841bb4d813677ca237e2a610067d594fec130f87d6093495ab5"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -2712,29 +2572,6 @@ dependencies = [
"zeroize",
]
-[[package]]
-name = "security-framework"
-version = "3.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
-dependencies = [
- "bitflags 2.13.2",
- "core-foundation 0.10.1",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
[[package]]
name = "semver"
version = "1.0.28"
@@ -2857,16 +2694,6 @@ version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
-[[package]]
-name = "simd_cesu8"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520"
-dependencies = [
- "rustc_version",
- "simdutf8",
-]
-
[[package]]
name = "simdutf8"
version = "0.1.5"
@@ -2995,7 +2822,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
dependencies = [
"bitflags 2.13.2",
- "core-foundation 0.9.4",
+ "core-foundation",
"system-configuration-sys",
]
@@ -3482,9 +3309,9 @@ dependencies = [
[[package]]
name = "wasm-streams"
-version = "0.5.0"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
+checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
dependencies = [
"futures-util",
"js-sys",
@@ -3513,15 +3340,6 @@ dependencies = [
"wasm-bindgen",
]
-[[package]]
-name = "webpki-root-certs"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b"
-dependencies = [
- "rustls-pki-types",
-]
-
[[package]]
name = "webpki-roots"
version = "0.26.11"
diff --git a/openless-all/app/src-tauri/backend-tests/tests/mouse_dictation.rs b/openless-all/app/src-tauri/backend-tests/tests/mouse_dictation.rs
index c316910c6..338143c57 100644
--- a/openless-all/app/src-tauri/backend-tests/tests/mouse_dictation.rs
+++ b/openless-all/app/src-tauri/backend-tests/tests/mouse_dictation.rs
@@ -12,6 +12,10 @@ mod shortcut_binding {
#[path = "../../src/mobile_stubs/combo_hotkey.rs"]
mod combo_hotkey;
+#[allow(dead_code)]
+#[path = "../../src/recording_companion.rs"]
+mod recording_companion;
+
#[allow(dead_code)]
#[path = "../../src/mouse_dictation.rs"]
mod mouse_dictation;
diff --git a/openless-all/app/src-tauri/backend-tests/tests/tls_crypto.rs b/openless-all/app/src-tauri/backend-tests/tests/tls_crypto.rs
new file mode 100644
index 000000000..f58fa4043
--- /dev/null
+++ b/openless-all/app/src-tauri/backend-tests/tests/tls_crypto.rs
@@ -0,0 +1,3 @@
+//! Exercise the production TLS startup without loading Tauri's native runtimes.
+#[path = "../../src/tls_crypto.rs"]
+mod tls_crypto;
diff --git a/openless-all/app/src-tauri/capabilities/macos-native-theme.json b/openless-all/app/src-tauri/capabilities/macos-native-theme.json
new file mode 100644
index 000000000..6284026e8
--- /dev/null
+++ b/openless-all/app/src-tauri/capabilities/macos-native-theme.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "../gen/schemas/desktop-schema.json",
+ "identifier": "macos-native-theme",
+ "description": "Let the main window synchronize native appearance with the user's theme preference",
+ "platforms": ["macOS"],
+ "windows": ["main"],
+ "permissions": ["core:app:allow-set-app-theme"]
+}
diff --git a/openless-all/app/src-tauri/src/android/native_bridge.rs b/openless-all/app/src-tauri/src/android/native_bridge.rs
index 83eb45647..268185d36 100644
--- a/openless-all/app/src-tauri/src/android/native_bridge.rs
+++ b/openless-all/app/src-tauri/src/android/native_bridge.rs
@@ -22,6 +22,18 @@ static OVERLAY_VISIBLE: std::sync::atomic::AtomicBool = std::sync::atomic::Atomi
#[cfg(target_os = "android")]
static APP_HANDLE: OnceLock
= OnceLock::new();
+// A panic from a synchronously polled future must not cross an extern JNI
+// boundary. Return an ordinary error so each caller keeps its wire envelope.
+fn catch_jni_panic(
+ operation: &str,
+ action: impl FnOnce() -> Result,
+) -> Result {
+ std::panic::catch_unwind(std::panic::AssertUnwindSafe(action)).unwrap_or_else(|_| {
+ log::error!("[android-native] {operation} panicked");
+ Err(format!("{operation} failed unexpectedly"))
+ })
+}
+
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
struct AndroidBackendSnapshotResponse {
@@ -89,7 +101,7 @@ fn export_provider_settings_json(include_credentials: bool) -> String {
fn import_provider_settings_json(json: &str, selection: bool, credentials: bool) -> String {
let mut applied = Vec::new();
let mut errors = serde_json::Map::new();
- let result = (|| -> Result<(), String> {
+ let result = catch_jni_panic("import provider settings", || {
let root: serde_json::Value =
serde_json::from_str(json).map_err(|_| "invalid settings file")?;
let version = root["openlessSettingsExportVersion"]
@@ -174,7 +186,7 @@ fn import_provider_settings_json(json: &str, selection: bool, credentials: bool)
}
}
Ok(())
- })();
+ });
if let Err(error) = result {
for (selected, key) in [
(selection, "providerSelection"),
@@ -197,7 +209,7 @@ fn export_local_migration_bundle_json(
include_credentials: bool,
password: &str,
) -> String {
- let result = (|| -> Result {
+ let result = catch_jni_panic("export migration bundle", || {
let backend = CORE_BACKEND.get().ok_or("backend unavailable")?;
let mode = match mode {
"share_redacted" => openless_core::local_migration_bundle::BundleMode::ShareRedacted,
@@ -233,7 +245,7 @@ fn export_local_migration_bundle_json(
"inspection": artifact.inspection,
"bundleBase64": base64::engine::general_purpose::STANDARD.encode(&artifact.bytes),
}))
- })();
+ });
match result {
Ok(payload) => serde_json::json!({"ok": true, "payload": payload}).to_string(),
Err(error) => local_bundle_error(error),
@@ -258,7 +270,7 @@ fn inspect_local_migration_bundle_json(bundle_base64: &str) -> String {
}
fn preview_local_migration_bundle_json(bundle_base64: &str, password: &str, mode: &str) -> String {
- let result = (|| -> Result {
+ let result = catch_jni_panic("preview migration bundle", || {
let backend = CORE_BACKEND.get().ok_or("backend unavailable")?;
let bytes = base64::engine::general_purpose::STANDARD
.decode(bundle_base64)
@@ -281,7 +293,7 @@ fn preview_local_migration_bundle_json(bundle_base64: &str, password: &str, mode
)
.map_err(|error| error.message)?;
serde_json::to_value(preview).map_err(|_| "invalid bundle preview".into())
- })();
+ });
match result {
Ok(payload) => serde_json::json!({"ok": true, "payload": payload}).to_string(),
Err(error) => local_bundle_error(error),
@@ -296,7 +308,7 @@ fn import_local_migration_bundle_json(
expected_generation: &str,
android_revision: &str,
) -> String {
- let result = (|| -> Result {
+ let result = catch_jni_panic("import migration bundle", || {
let backend = CORE_BACKEND.get().ok_or("backend unavailable")?;
let bytes = base64::engine::general_purpose::STANDARD
.decode(bundle_base64)
@@ -344,7 +356,7 @@ fn import_local_migration_bundle_json(
tauri::async_runtime::block_on(backend.refresh_and_publish_credentials())
.map_err(|error| error.message)?;
serde_json::to_value(inspection).map_err(|_| "invalid bundle inspection".into())
- })();
+ });
match result {
Ok(payload) => serde_json::json!({"ok": true, "payload": payload}).to_string(),
Err(error) => local_bundle_error(error),
@@ -1252,7 +1264,7 @@ mod jni_exports {
let Ok(mut env) = JniEnv::from_raw(env) else {
return std::ptr::null_mut();
};
- let result = (|| -> Result {
+ let result = catch_jni_panic("public dictionary", || {
let base = env
.get_string(&JString::from_raw(base))
.map(String::from)
@@ -1276,7 +1288,7 @@ mod jni_exports {
_ => return Err("unsupported dictionary action".into()),
};
serde_json::to_value(status).map_err(|_| "encode dictionary status".into())
- })();
+ });
crate::android::jni::android::export_jstring(
&mut env,
&match result {
@@ -1295,10 +1307,15 @@ mod jni_exports {
let Ok(mut env) = JniEnv::from_raw(env) else {
return std::ptr::null_mut();
};
- let input = env.get_string(&JString::from_raw(pinyin)).map(String::from);
- let result = input
- .map(|query| tauri::async_runtime::block_on(openless_core::ime_cloud::query(&query)))
- .unwrap_or_default();
+ let result = catch_jni_panic("cloud pinyin", || {
+ let input = env.get_string(&JString::from_raw(pinyin)).map(String::from);
+ Ok(input
+ .map(|query| {
+ tauri::async_runtime::block_on(openless_core::ime_cloud::query(&query))
+ })
+ .unwrap_or_default())
+ })
+ .unwrap_or_default();
crate::android::jni::android::export_jstring(
&mut env,
&serde_json::json!(result).to_string(),
@@ -1502,15 +1519,18 @@ mod jni_exports {
env: *mut JNIEnv,
_class: JClass,
) -> jstring {
- let route = match CORE_BACKEND.get() {
- Some(backend) => match tauri::async_runtime::block_on(backend.asr_route()) {
- openless_core::AsrRoute::Local => "local",
- openless_core::AsrRoute::LocalRaw => "localRaw",
- openless_core::AsrRoute::Cloud => "cloud",
- openless_core::AsrRoute::Unavailable => "unavailable",
- },
- None => "unavailable",
- };
+ let route = catch_jni_panic("ASR route", || {
+ Ok(match CORE_BACKEND.get() {
+ Some(backend) => match tauri::async_runtime::block_on(backend.asr_route()) {
+ openless_core::AsrRoute::Local => "local",
+ openless_core::AsrRoute::LocalRaw => "localRaw",
+ openless_core::AsrRoute::Cloud => "cloud",
+ openless_core::AsrRoute::Unavailable => "unavailable",
+ },
+ None => "unavailable",
+ })
+ })
+ .unwrap_or("unavailable");
match JniEnv::from_raw(env) {
Ok(mut env) => crate::android::jni::android::export_jstring(&mut env, route),
Err(_) => std::ptr::null_mut(),
@@ -1834,6 +1854,19 @@ mod tests {
InMemoryCredentialStore, InsertOutcome, TokioTaskSpawner,
};
+ #[test]
+ fn jni_panic_guard_returns_an_error_for_a_panicking_future() {
+ let result: Result<(), String> = catch_jni_panic("test operation", || {
+ tauri::async_runtime::block_on(async { panic!("simulated TLS panic") })
+ });
+ assert_eq!(result.unwrap_err(), "test operation failed unexpectedly");
+ assert_eq!(catch_jni_panic("test operation", || Ok(42)), Ok(42));
+ assert_eq!(
+ catch_jni_panic::<()>("test operation", || Err("network error".into())),
+ Err("network error".into())
+ );
+ }
+
#[test]
fn android_snapshot_envelope_always_carries_contract_version() {
let value: serde_json::Value =
diff --git a/openless-all/app/src-tauri/src/commands/dictation.rs b/openless-all/app/src-tauri/src/commands/dictation.rs
index 5e8cc54ef..2d224ba44 100644
--- a/openless-all/app/src-tauri/src/commands/dictation.rs
+++ b/openless-all/app/src-tauri/src/commands/dictation.rs
@@ -119,3 +119,56 @@ pub async fn repolish(
.await
.map_err(|error| error.to_string())
}
+
+#[cfg(not(mobile))]
+#[tauri::command]
+pub async fn get_dictation_translation_target(
+ core: CoreState<'_>,
+) -> Result