i18n support

This commit is contained in:
Victoria Brekenfeld 2023-06-27 17:40:14 +02:00
parent bdcb803efa
commit 7338ac8c57
5 changed files with 359 additions and 0 deletions

320
Cargo.lock generated
View file

@ -148,6 +148,12 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "arc-swap"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
[[package]] [[package]]
name = "arrayref" name = "arrayref"
version = "0.3.7" version = "0.3.7"
@ -480,6 +486,8 @@ dependencies = [
"edid-rs", "edid-rs",
"egui", "egui",
"glow 0.11.2", "glow 0.11.2",
"i18n-embed",
"i18n-embed-fl",
"iced_tiny_skia", "iced_tiny_skia",
"id_tree", "id_tree",
"indexmap 1.9.3", "indexmap 1.9.3",
@ -495,6 +503,7 @@ dependencies = [
"regex", "regex",
"renderdoc", "renderdoc",
"ron 0.7.1", "ron 0.7.1",
"rust-embed",
"sendfd", "sendfd",
"serde", "serde",
"serde_json", "serde_json",
@ -722,6 +731,19 @@ dependencies = [
"syn 2.0.22", "syn 2.0.22",
] ]
[[package]]
name = "dashmap"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
dependencies = [
"cfg-if",
"hashbrown 0.12.3",
"lock_api",
"once_cell",
"parking_lot_core 0.9.8",
]
[[package]] [[package]]
name = "data-url" name = "data-url"
version = "0.2.0" version = "0.2.0"
@ -807,6 +829,17 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
[[package]]
name = "displaydoc"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
]
[[package]] [[package]]
name = "dlib" name = "dlib"
version = "0.5.2" version = "0.5.2"
@ -1124,6 +1157,15 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "find-crate"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2"
dependencies = [
"toml 0.5.11",
]
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.26" version = "1.0.26"
@ -1149,6 +1191,50 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
[[package]]
name = "fluent"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61f69378194459db76abd2ce3952b790db103ceb003008d3d50d97c41ff847a7"
dependencies = [
"fluent-bundle",
"unic-langid",
]
[[package]]
name = "fluent-bundle"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd"
dependencies = [
"fluent-langneg",
"fluent-syntax",
"intl-memoizer",
"intl_pluralrules",
"rustc-hash",
"self_cell",
"smallvec",
"unic-langid",
]
[[package]]
name = "fluent-langneg"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94"
dependencies = [
"unic-langid",
]
[[package]]
name = "fluent-syntax"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78"
dependencies = [
"thiserror",
]
[[package]] [[package]]
name = "flume" name = "flume"
version = "0.10.14" version = "0.10.14"
@ -1602,6 +1688,76 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "i18n-config"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b987084cadad6e2f2b1e6ea62c44123591a3c044793a1beabf71a8356ea768d5"
dependencies = [
"log",
"serde",
"serde_derive",
"thiserror",
"toml 0.7.5",
"unic-langid",
]
[[package]]
name = "i18n-embed"
version = "0.13.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92a86226a7a16632de6723449ee5fe70bac5af718bc642ee9ca2f0f6e14fa1fa"
dependencies = [
"arc-swap",
"fluent",
"fluent-langneg",
"fluent-syntax",
"i18n-embed-impl",
"intl-memoizer",
"lazy_static",
"locale_config",
"log",
"parking_lot 0.12.1",
"rust-embed",
"thiserror",
"unic-langid",
"walkdir",
]
[[package]]
name = "i18n-embed-fl"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26a3d3569737dfaac7fc1c4078e6af07471c3060b8e570bcd83cdd5f4685395"
dependencies = [
"dashmap",
"find-crate",
"fluent",
"fluent-syntax",
"i18n-config",
"i18n-embed",
"lazy_static",
"proc-macro-error",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.22",
"unic-langid",
]
[[package]]
name = "i18n-embed-impl"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9a95d065e6be4499e50159172395559a388d20cf13c84c77e4a1e341786f219"
dependencies = [
"find-crate",
"i18n-config",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "iced" name = "iced"
version = "0.9.0" version = "0.9.0"
@ -1863,6 +2019,25 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "intl-memoizer"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f"
dependencies = [
"type-map",
"unic-langid",
]
[[package]]
name = "intl_pluralrules"
version = "7.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
dependencies = [
"unic-langid",
]
[[package]] [[package]]
name = "io-lifetimes" name = "io-lifetimes"
version = "1.0.11" version = "1.0.11"
@ -2101,6 +2276,19 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "locale_config"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934"
dependencies = [
"lazy_static",
"objc",
"objc-foundation",
"regex",
"winapi",
]
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.10" version = "0.4.10"
@ -2539,6 +2727,17 @@ dependencies = [
"objc_exception", "objc_exception",
] ]
[[package]]
name = "objc-foundation"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
dependencies = [
"block",
"objc",
"objc_id",
]
[[package]] [[package]]
name = "objc-sys" name = "objc-sys"
version = "0.2.0-beta.2" version = "0.2.0-beta.2"
@ -2574,6 +2773,15 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "objc_id"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
dependencies = [
"objc",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.30.4" version = "0.30.4"
@ -3246,6 +3454,40 @@ dependencies = [
"xmlparser", "xmlparser",
] ]
[[package]]
name = "rust-embed"
version = "6.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b73e721f488c353141288f223b599b4ae9303ecf3e62923f40a492f0634a4dc3"
dependencies = [
"rust-embed-impl",
"rust-embed-utils",
"walkdir",
]
[[package]]
name = "rust-embed-impl"
version = "6.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e22ce362f5561923889196595504317a4372b84210e6e335da529a65ea5452b5"
dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn 2.0.22",
"walkdir",
]
[[package]]
name = "rust-embed-utils"
version = "7.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731"
dependencies = [
"sha2",
"walkdir",
]
[[package]] [[package]]
name = "rust-ini" name = "rust-ini"
version = "0.18.0" version = "0.18.0"
@ -3343,6 +3585,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "self_cell"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"
[[package]] [[package]]
name = "sendfd" name = "sendfd"
version = "0.4.3" version = "0.4.3"
@ -3383,6 +3631,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_spanned"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.7" version = "0.10.7"
@ -3840,6 +4097,15 @@ dependencies = [
"strict-num", "strict-num",
] ]
[[package]]
name = "tinystr"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ac3f5b6856e931e15e07b478e98c8045239829a65f9156d4fa7e7788197a5ef"
dependencies = [
"displaydoc",
]
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.28.2" version = "1.28.2"
@ -3852,11 +4118,35 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "toml"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
dependencies = [
"serde",
]
[[package]]
name = "toml"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.3" version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
@ -3865,6 +4155,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7"
dependencies = [ dependencies = [
"indexmap 2.0.0", "indexmap 2.0.0",
"serde",
"serde_spanned",
"toml_datetime", "toml_datetime",
"winnow", "winnow",
] ]
@ -3965,6 +4257,15 @@ dependencies = [
"static_assertions", "static_assertions",
] ]
[[package]]
name = "type-map"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46"
dependencies = [
"rustc-hash",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.16.0" version = "1.16.0"
@ -3982,6 +4283,25 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "unic-langid"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f"
dependencies = [
"unic-langid-impl",
]
[[package]]
name = "unic-langid-impl"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff"
dependencies = [
"serde",
"tinystr",
]
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.13" version = "0.3.13"

View file

@ -43,6 +43,9 @@ puffin = { version = "0.14.3", optional = true }
puffin_egui = { version = "0.21.0", optional = true } puffin_egui = { version = "0.21.0", optional = true }
cosmic-time = { git = "https://github.com/pop-os/cosmic-time", rev = "39c96ac", default-features = false, features = ["libcosmic"] } cosmic-time = { git = "https://github.com/pop-os/cosmic-time", rev = "39c96ac", default-features = false, features = ["libcosmic"] }
once_cell = "1.18.0" once_cell = "1.18.0"
i18n-embed = { version = "0.13", features = ["fluent-system", "desktop-requester"] }
i18n-embed-fl = "0.6"
rust-embed = "6.6"
[dependencies.id_tree] [dependencies.id_tree]
git = "https://github.com/Drakulix/id-tree.git" git = "https://github.com/Drakulix/id-tree.git"

4
i18n.toml Normal file
View file

@ -0,0 +1,4 @@
fallback_language = "en"
[fluent]
assets_dir = "resources/i18n"

View file

@ -0,0 +1,3 @@
grow-window = Grow
shrink-window = Shrink
unknown-keybinding = <unset>

View file

@ -17,7 +17,14 @@ use crate::{
}, },
xwayland::XWaylandState, xwayland::XWaylandState,
}; };
use anyhow::Context;
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_manager_v1::CursorMode; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_manager_v1::CursorMode;
use i18n_embed::{
fluent::{fluent_language_loader, FluentLanguageLoader},
DesktopLanguageRequester,
};
use once_cell::sync::Lazy;
use rust_embed::RustEmbed;
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
use smithay::utils::Rectangle; use smithay::utils::Rectangle;
use smithay::{ use smithay::{
@ -69,6 +76,23 @@ use tracing::error;
use std::{cell::RefCell, ffi::OsString, time::Duration}; use std::{cell::RefCell, ffi::OsString, time::Duration};
use std::{collections::VecDeque, time::Instant}; use std::{collections::VecDeque, time::Instant};
#[derive(RustEmbed)]
#[folder = "resources/i18n"]
struct Localizations;
pub static LANG_LOADER: Lazy<FluentLanguageLoader> = Lazy::new(|| fluent_language_loader!());
#[macro_export]
macro_rules! fl {
($message_id:literal) => {{
i18n_embed_fl::fl!($crate::state::LANG_LOADER, $message_id)
}};
($message_id:literal, $($args:expr),*) => {{
i18n_embed_fl::fl!($crate::state::LANG_LOADER, $message_id, $($args), *)
}};
}
pub struct ClientState { pub struct ClientState {
pub compositor_client_state: CompositorClientState, pub compositor_client_state: CompositorClientState,
pub workspace_client_state: WorkspaceClientState, pub workspace_client_state: WorkspaceClientState,
@ -241,6 +265,11 @@ impl State {
handle: LoopHandle<'static, Data>, handle: LoopHandle<'static, Data>,
signal: LoopSignal, signal: LoopSignal,
) -> State { ) -> State {
let requested_languages = DesktopLanguageRequester::requested_languages();
i18n_embed::select(&*LANG_LOADER, &Localizations, &requested_languages)
.with_context(|| "Failed to load languages")
.unwrap();
let clock = Clock::new().expect("Failed to initialize clock"); let clock = Clock::new().expect("Failed to initialize clock");
let config = Config::load(); let config = Config::load();
let compositor_state = CompositorState::new::<Self>(dh); let compositor_state = CompositorState::new::<Self>(dh);