mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-08-17 16:34:54 -05:00
feat: initial localization support (#669)
* feat: WIP localization support * feat: add strings for software and thermals pages * feat: oc page localization strings * feat: some header strings
This commit is contained in:
Generated
+394
-1
@@ -131,6 +131,12 @@ version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||
|
||||
[[package]]
|
||||
name = "async-broadcast"
|
||||
version = "0.7.2"
|
||||
@@ -192,6 +198,15 @@ version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "basic-toml"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.71.1"
|
||||
@@ -224,6 +239,15 @@ version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
@@ -425,6 +449,15 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.5.0"
|
||||
@@ -440,6 +473,16 @@ version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.11"
|
||||
@@ -496,6 +539,27 @@ version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "divan"
|
||||
version = "0.1.21"
|
||||
@@ -673,6 +737,60 @@ dependencies = [
|
||||
"windows-sys 0.59.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]]
|
||||
name = "fluent"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8137a6d5a2c50d6b0ebfcb9aaa91a28154e0a70605f112d30cb0cd4a78670477"
|
||||
dependencies = [
|
||||
"fluent-bundle",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent-bundle"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4"
|
||||
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.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"thiserror 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.11.1"
|
||||
@@ -872,6 +990,16 @@ dependencies = [
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.16"
|
||||
@@ -1134,6 +1262,73 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "i18n-config"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e06b90c8a0d252e203c94344b21e35a30f3a3a85dc7db5af8f8df9f3e0c63ef"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"thiserror 1.0.69",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "i18n-embed"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a217bbb075dcaefb292efa78897fc0678245ca67f265d12c351e42268fcb0305"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"fluent",
|
||||
"fluent-langneg",
|
||||
"fluent-syntax",
|
||||
"i18n-embed-impl",
|
||||
"intl-memoizer",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"rust-embed",
|
||||
"sys-locale",
|
||||
"thiserror 1.0.69",
|
||||
"unic-langid",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "i18n-embed-fl"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e598ed73b67db92f61e04672e599eef2991a262a40e1666735b8a86d2e7e9f30"
|
||||
dependencies = [
|
||||
"find-crate",
|
||||
"fluent",
|
||||
"fluent-syntax",
|
||||
"i18n-config",
|
||||
"i18n-embed",
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "i18n-embed-impl"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f2cc0e0523d1fe6fc2c6f66e5038624ea8091b3e7748b5e8e0c84b1698db6c2"
|
||||
dependencies = [
|
||||
"find-crate",
|
||||
"i18n-config",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.63"
|
||||
@@ -1207,6 +1402,25 @@ dependencies = [
|
||||
"similar",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "intl-memoizer"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f"
|
||||
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]]
|
||||
name = "io-uring"
|
||||
version = "0.7.8"
|
||||
@@ -1354,6 +1568,8 @@ dependencies = [
|
||||
"chrono",
|
||||
"divan",
|
||||
"gtk4",
|
||||
"i18n-embed",
|
||||
"i18n-embed-fl",
|
||||
"indexmap",
|
||||
"lact-client",
|
||||
"lact-daemon",
|
||||
@@ -1364,6 +1580,7 @@ dependencies = [
|
||||
"pretty_assertions",
|
||||
"relm4",
|
||||
"relm4-components",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yml",
|
||||
@@ -1379,7 +1596,10 @@ dependencies = [
|
||||
"amdgpu-sysfs",
|
||||
"anyhow",
|
||||
"clap",
|
||||
"i18n-embed",
|
||||
"i18n-embed-fl",
|
||||
"indexmap",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde-error",
|
||||
"serde_json",
|
||||
@@ -1808,6 +2028,29 @@ version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pciid-parser"
|
||||
version = "0.8.0"
|
||||
@@ -1898,6 +2141,28 @@ dependencies = [
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
@@ -2033,6 +2298,40 @@ version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"syn",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594"
|
||||
dependencies = [
|
||||
"sha2",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.25"
|
||||
@@ -2094,6 +2393,12 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
@@ -2204,6 +2509,17 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
@@ -2288,6 +2604,15 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys-locale"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "7.0.5"
|
||||
@@ -2297,7 +2622,7 @@ dependencies = [
|
||||
"cfg-expr",
|
||||
"heck",
|
||||
"pkg-config",
|
||||
"toml",
|
||||
"toml 0.8.23",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
@@ -2446,6 +2771,16 @@ dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.46.1"
|
||||
@@ -2477,6 +2812,15 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[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.8.23"
|
||||
@@ -2592,6 +2936,21 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "type-map"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90"
|
||||
dependencies = [
|
||||
"rustc-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||
|
||||
[[package]]
|
||||
name = "uds_windows"
|
||||
version = "1.1.0"
|
||||
@@ -2603,6 +2962,25 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-langid"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05"
|
||||
dependencies = [
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-langid-impl"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"tinystr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
@@ -3104,6 +3482,21 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
|
||||
|
||||
[[package]]
|
||||
name = "zerovec"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
|
||||
dependencies = [
|
||||
"zerofrom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "5.6.0"
|
||||
|
||||
@@ -28,6 +28,12 @@ indexmap = { version = "2.5.0", features = ["serde"] }
|
||||
pretty_assertions = "1.4.0"
|
||||
divan = "0.1"
|
||||
serde_yml = "0.0.12"
|
||||
i18n-embed = { version = "0.16.0", features = [
|
||||
"fluent-system",
|
||||
"desktop-requester",
|
||||
] }
|
||||
i18n-embed-fl = "0.10.0"
|
||||
rust-embed = { version = "8.7.2", features = ["debug-embed"] }
|
||||
|
||||
[profile.release]
|
||||
strip = "symbols"
|
||||
|
||||
@@ -206,6 +206,19 @@
|
||||
"dest": "cargo/vendor/anyhow-1.0.98",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/arc-swap/arc-swap-1.7.1.crate",
|
||||
"sha256": "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457",
|
||||
"dest": "cargo/vendor/arc-swap-1.7.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/arc-swap-1.7.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -284,6 +297,19 @@
|
||||
"dest": "cargo/vendor/base64-0.22.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/basic-toml/basic-toml-0.1.10.crate",
|
||||
"sha256": "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a",
|
||||
"dest": "cargo/vendor/basic-toml-0.1.10"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/basic-toml-0.1.10",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -323,6 +349,19 @@
|
||||
"dest": "cargo/vendor/bitflags-2.9.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/block-buffer/block-buffer-0.10.4.crate",
|
||||
"sha256": "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71",
|
||||
"dest": "cargo/vendor/block-buffer-0.10.4"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/block-buffer-0.10.4",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -614,6 +653,19 @@
|
||||
"dest": "cargo/vendor/core2-0.4.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/cpufeatures/cpufeatures-0.2.17.crate",
|
||||
"sha256": "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280",
|
||||
"dest": "cargo/vendor/cpufeatures-0.2.17"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/cpufeatures-0.2.17",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -640,6 +692,19 @@
|
||||
"dest": "cargo/vendor/crossbeam-utils-0.8.21",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/crypto-common/crypto-common-0.1.6.crate",
|
||||
"sha256": "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3",
|
||||
"dest": "cargo/vendor/crypto-common-0.1.6"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/crypto-common-0.1.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -718,6 +783,32 @@
|
||||
"dest": "cargo/vendor/diff-0.1.13",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/digest/digest-0.10.7.crate",
|
||||
"sha256": "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292",
|
||||
"dest": "cargo/vendor/digest-0.10.7"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/digest-0.10.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/displaydoc/displaydoc-0.2.5.crate",
|
||||
"sha256": "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0",
|
||||
"dest": "cargo/vendor/displaydoc-0.2.5"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/displaydoc-0.2.5",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -952,6 +1043,71 @@
|
||||
"dest": "cargo/vendor/filetime-0.2.25",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/find-crate/find-crate-0.6.3.crate",
|
||||
"sha256": "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2",
|
||||
"dest": "cargo/vendor/find-crate-0.6.3"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/find-crate-0.6.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/fluent/fluent-0.17.0.crate",
|
||||
"sha256": "8137a6d5a2c50d6b0ebfcb9aaa91a28154e0a70605f112d30cb0cd4a78670477",
|
||||
"dest": "cargo/vendor/fluent-0.17.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"8137a6d5a2c50d6b0ebfcb9aaa91a28154e0a70605f112d30cb0cd4a78670477\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/fluent-0.17.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/fluent-bundle/fluent-bundle-0.16.0.crate",
|
||||
"sha256": "01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4",
|
||||
"dest": "cargo/vendor/fluent-bundle-0.16.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/fluent-bundle-0.16.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/fluent-langneg/fluent-langneg-0.13.0.crate",
|
||||
"sha256": "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94",
|
||||
"dest": "cargo/vendor/fluent-langneg-0.13.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/fluent-langneg-0.13.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/fluent-syntax/fluent-syntax-0.12.0.crate",
|
||||
"sha256": "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198",
|
||||
"dest": "cargo/vendor/fluent-syntax-0.12.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/fluent-syntax-0.12.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1186,6 +1342,19 @@
|
||||
"dest": "cargo/vendor/gdk4-sys-0.9.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/generic-array/generic-array-0.14.7.crate",
|
||||
"sha256": "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a",
|
||||
"dest": "cargo/vendor/generic-array-0.14.7"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/generic-array-0.14.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1472,6 +1641,58 @@
|
||||
"dest": "cargo/vendor/hex-0.4.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/i18n-config/i18n-config-0.4.8.crate",
|
||||
"sha256": "3e06b90c8a0d252e203c94344b21e35a30f3a3a85dc7db5af8f8df9f3e0c63ef",
|
||||
"dest": "cargo/vendor/i18n-config-0.4.8"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"3e06b90c8a0d252e203c94344b21e35a30f3a3a85dc7db5af8f8df9f3e0c63ef\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/i18n-config-0.4.8",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/i18n-embed/i18n-embed-0.16.0.crate",
|
||||
"sha256": "a217bbb075dcaefb292efa78897fc0678245ca67f265d12c351e42268fcb0305",
|
||||
"dest": "cargo/vendor/i18n-embed-0.16.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"a217bbb075dcaefb292efa78897fc0678245ca67f265d12c351e42268fcb0305\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/i18n-embed-0.16.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/i18n-embed-fl/i18n-embed-fl-0.10.0.crate",
|
||||
"sha256": "e598ed73b67db92f61e04672e599eef2991a262a40e1666735b8a86d2e7e9f30",
|
||||
"dest": "cargo/vendor/i18n-embed-fl-0.10.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"e598ed73b67db92f61e04672e599eef2991a262a40e1666735b8a86d2e7e9f30\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/i18n-embed-fl-0.10.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/i18n-embed-impl/i18n-embed-impl-0.8.4.crate",
|
||||
"sha256": "0f2cc0e0523d1fe6fc2c6f66e5038624ea8091b3e7748b5e8e0c84b1698db6c2",
|
||||
"dest": "cargo/vendor/i18n-embed-impl-0.8.4"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"0f2cc0e0523d1fe6fc2c6f66e5038624ea8091b3e7748b5e8e0c84b1698db6c2\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/i18n-embed-impl-0.8.4",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1563,6 +1784,32 @@
|
||||
"dest": "cargo/vendor/insta-1.43.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/intl-memoizer/intl-memoizer-0.5.3.crate",
|
||||
"sha256": "310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f",
|
||||
"dest": "cargo/vendor/intl-memoizer-0.5.3"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/intl-memoizer-0.5.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/intl_pluralrules/intl_pluralrules-7.0.2.crate",
|
||||
"sha256": "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972",
|
||||
"dest": "cargo/vendor/intl_pluralrules-7.0.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/intl_pluralrules-7.0.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2231,6 +2478,32 @@
|
||||
"dest": "cargo/vendor/parking-2.2.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/parking_lot/parking_lot-0.12.4.crate",
|
||||
"sha256": "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13",
|
||||
"dest": "cargo/vendor/parking_lot-0.12.4"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/parking_lot-0.12.4",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/parking_lot_core/parking_lot_core-0.9.11.crate",
|
||||
"sha256": "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5",
|
||||
"dest": "cargo/vendor/parking_lot_core-0.9.11"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/parking_lot_core-0.9.11",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2374,6 +2647,32 @@
|
||||
"dest": "cargo/vendor/proc-macro-crate-3.3.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/proc-macro-error-attr2/proc-macro-error-attr2-2.0.0.crate",
|
||||
"sha256": "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5",
|
||||
"dest": "cargo/vendor/proc-macro-error-attr2-2.0.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/proc-macro-error-attr2-2.0.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/proc-macro-error2/proc-macro-error2-2.0.1.crate",
|
||||
"sha256": "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802",
|
||||
"dest": "cargo/vendor/proc-macro-error2-2.0.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/proc-macro-error2-2.0.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2569,6 +2868,45 @@
|
||||
"dest": "cargo/vendor/rle-decode-fast-1.0.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/rust-embed/rust-embed-8.7.2.crate",
|
||||
"sha256": "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a",
|
||||
"dest": "cargo/vendor/rust-embed-8.7.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/rust-embed-8.7.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/rust-embed-impl/rust-embed-impl-8.7.2.crate",
|
||||
"sha256": "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c",
|
||||
"dest": "cargo/vendor/rust-embed-impl-8.7.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/rust-embed-impl-8.7.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/rust-embed-utils/rust-embed-utils-8.7.2.crate",
|
||||
"sha256": "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594",
|
||||
"dest": "cargo/vendor/rust-embed-utils-8.7.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/rust-embed-utils-8.7.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2673,6 +3011,19 @@
|
||||
"dest": "cargo/vendor/scopeguard-1.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/self_cell/self_cell-1.2.0.crate",
|
||||
"sha256": "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749",
|
||||
"dest": "cargo/vendor/self_cell-1.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/self_cell-1.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2803,6 +3154,19 @@
|
||||
"dest": "cargo/vendor/serde_yml-0.0.12",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/sha2/sha2-0.10.9.crate",
|
||||
"sha256": "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283",
|
||||
"dest": "cargo/vendor/sha2-0.10.9"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/sha2-0.10.9",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -2946,6 +3310,19 @@
|
||||
"dest": "cargo/vendor/syn-2.0.104",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/sys-locale/sys-locale-0.3.2.crate",
|
||||
"sha256": "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4",
|
||||
"dest": "cargo/vendor/sys-locale-0.3.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/sys-locale-0.3.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3141,6 +3518,19 @@
|
||||
"dest": "cargo/vendor/time-macros-0.2.22",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/tinystr/tinystr-0.8.1.crate",
|
||||
"sha256": "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b",
|
||||
"dest": "cargo/vendor/tinystr-0.8.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/tinystr-0.8.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3167,6 +3557,19 @@
|
||||
"dest": "cargo/vendor/tokio-macros-2.5.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/toml/toml-0.5.11.crate",
|
||||
"sha256": "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234",
|
||||
"dest": "cargo/vendor/toml-0.5.11"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml-0.5.11",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3297,6 +3700,32 @@
|
||||
"dest": "cargo/vendor/tracker-macros-0.2.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/type-map/type-map-0.5.1.crate",
|
||||
"sha256": "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90",
|
||||
"dest": "cargo/vendor/type-map-0.5.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/type-map-0.5.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/typenum/typenum-1.18.0.crate",
|
||||
"sha256": "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f",
|
||||
"dest": "cargo/vendor/typenum-1.18.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/typenum-1.18.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -3310,6 +3739,32 @@
|
||||
"dest": "cargo/vendor/uds_windows-1.1.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/unic-langid/unic-langid-0.9.6.crate",
|
||||
"sha256": "a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05",
|
||||
"dest": "cargo/vendor/unic-langid-0.9.6"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/unic-langid-0.9.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/unic-langid-impl/unic-langid-impl-0.9.6.crate",
|
||||
"sha256": "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658",
|
||||
"dest": "cargo/vendor/unic-langid-impl-0.9.6"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/unic-langid-impl-0.9.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -4038,6 +4493,32 @@
|
||||
"dest": "cargo/vendor/zerocopy-derive-0.8.26",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerofrom/zerofrom-0.1.6.crate",
|
||||
"sha256": "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5",
|
||||
"dest": "cargo/vendor/zerofrom-0.1.6"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerofrom-0.1.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerovec/zerovec-0.11.2.crate",
|
||||
"sha256": "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428",
|
||||
"dest": "cargo/vendor/zerovec-0.11.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerovec-0.11.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
|
||||
@@ -32,6 +32,10 @@ adw = { package = "libadwaita", version = "0.7.1", features = [
|
||||
relm4 = { version = "0.9.0", default-features = false }
|
||||
relm4-components = "0.9.0"
|
||||
|
||||
i18n-embed = { workspace = true }
|
||||
i18n-embed-fl = { workspace = true }
|
||||
rust-embed = { workspace = true }
|
||||
|
||||
plotters = { version = "0.3.5", default-features = false, features = [
|
||||
"line_series",
|
||||
"full_palette",
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
fallback_language = "en"
|
||||
|
||||
[fluent]
|
||||
assets_dir = "i18n"
|
||||
@@ -0,0 +1,137 @@
|
||||
info-page = Information
|
||||
oc-page = OC
|
||||
thermals-page = Thermals
|
||||
software-page = Software
|
||||
|
||||
hardware-info = Hardware Information
|
||||
|
||||
system-section = System
|
||||
lact-daemon = LACT Daemon
|
||||
lact-gui = LACT GUI
|
||||
kernel-version = Kernel Version
|
||||
|
||||
instance = Instance
|
||||
device-name = Device Name
|
||||
platform-name = Platform Name
|
||||
api-version = API Version
|
||||
version = Version
|
||||
driver-name = Driver Name
|
||||
driver-version = Driver Version
|
||||
compute-units = Compute Units
|
||||
cl-c-version = OpenCL C Version
|
||||
workgroup-size = Workgroup Size
|
||||
global-memory = Global Memory
|
||||
local-memory = Local Memory
|
||||
features = Features
|
||||
extensions = Extensions
|
||||
show-button = Show
|
||||
device-not-found = {$kind} device not found
|
||||
|
||||
monitoring-section = Monitoring
|
||||
fan-control-section = Fan Control
|
||||
temperatures = Temperatures
|
||||
oc-missing-fan-control-warning = Warning: Overclocking support is disabled, fan control functionality is not available.
|
||||
fan-speed = Fan Speed
|
||||
throttling = Throttling
|
||||
auto-page = Automatic
|
||||
curve-page = Curve
|
||||
static-page = Static
|
||||
target-temp = Target temperature (°C)
|
||||
acoustic-limit = Acoustic Limit (RPM)
|
||||
acoustic-target = Acoustic Target (RPM)
|
||||
min-fan-speed = Minimum Fan Speed (%)
|
||||
zero-rpm = Zero RPM
|
||||
zero-rpm-stop-temp = Zero RPM stop temperature (°C)
|
||||
static-speed = Static Speed (%)
|
||||
reset-button = Reset
|
||||
pmfw-reset-warning = Warning: this resets the fan firmware settings!
|
||||
|
||||
amd-oc-disabled =
|
||||
AMD Overclocking support is not enabled!
|
||||
You can still change basic settings, but the more advanced clocks and voltage control will not be available.
|
||||
enable-amd-oc = Enable AMD Overclocking
|
||||
enable-amd-oc-description = This will enable the overdrive feature of the amdgpu driver by creating a file at <b>{$path}</b> and updating the initramfs. Are you sure you want to do this?
|
||||
disable-amd-oc = Disable AMD Overclocking
|
||||
disable-amd-oc-description = This will disable AMD overclocking support (overdrive) on next reboot.
|
||||
|
||||
reset-config = Reset Configuration
|
||||
reset-config-description = Are you sure you want to reset all GPU configuration?
|
||||
|
||||
power-cap = Power Usage Limit
|
||||
|
||||
watt = W
|
||||
ghz = GHz
|
||||
mhz = MHz
|
||||
mebibyte = MiB
|
||||
|
||||
stats-section = Statistics
|
||||
gpu-clock = GPU Core Clock
|
||||
gpu-clock-avg = GPU Core Clock (Average)
|
||||
gpu-clock-target = GPU Core Clock (Target)
|
||||
gpu-voltage = GPU Voltage
|
||||
gpu-temp = GPU Temperature
|
||||
gpu-usage = GPU Usage
|
||||
vram-clock = VRAM Clock
|
||||
power-usage = Power Usage
|
||||
no-throttling = No
|
||||
unknown-throttling = Unknown
|
||||
missing-stat = N/A
|
||||
|
||||
performance-level-auto = Automatic
|
||||
performance-level-high = Highest Clocks
|
||||
performance-level-low = Lowest Clocks
|
||||
performance-level-manual = Manual
|
||||
performance-level-auto-description = Automatically adjust GPU and VRAM clocks. (Default)
|
||||
performance-level-high-description = Always use the highest clockspeeds for GPU and VRAM.
|
||||
performance-level-low-description = Always use the lowest clockspeeds for GPU and VRAM.
|
||||
performance-level-manual-description = Manual performance control.
|
||||
|
||||
power-profile-mode = Power Profile Mode:
|
||||
manual-level-needed = Performance level has to be set to "manual" to use power states and modes
|
||||
|
||||
overclock-section = Clockspeed and Voltage
|
||||
nvidia-oc-info = Nvidia Overclocking Information
|
||||
nvidia-oc-description =
|
||||
Overclocking functionality on Nvidia includes setting offsets for GPU/VRAM clockspeeds and limiting the potential range of clockspeeds using the "locked clocks" feature.
|
||||
|
||||
On many cards, the VRAM clockpeed offset will only affect the actual memory clockspeed by half of the offset value.
|
||||
For example, a +1000MHz VRAM offset may only increase the measured VRAM speed by 500MHz.
|
||||
This is normal, and is how Nvidia handles GDDR data rates. Adjust your overclock accordingly.
|
||||
|
||||
Direct voltage control is not supported, as it does not exist in the Nvidia Linux driver.
|
||||
|
||||
It is possible to achieve a pseudo-undervolt by combining the locked clocks option with a positive clockspeed offset.
|
||||
This will force the GPU to run at a voltage that's constrained by the locked clocks, while achieving a higher clockspeed due to the offset.
|
||||
This can cause system instability if pushed too high.
|
||||
oc-warning = Warning: changing these values may lead to system instability and can potentially damage your hardware!
|
||||
show-all-pstates = Show all P-States
|
||||
enable-gpu-locked-clocks = Enable GPU Locked Clocks
|
||||
enable-vram-locked-clocks = Enable VRAM Locked Clocks
|
||||
pstate-list-description = <b>The following values are clock offsets for each P-State, going from highest to lowest.</b>
|
||||
no-clocks-data = No clocks data available
|
||||
reset-oc-tooltip = Warning: this resets all clock settings to defaults!
|
||||
|
||||
gpu-clock-offset = GPU Clock Offset (MHz)
|
||||
max-gpu-clock = Maximum GPU Clock (MHz)
|
||||
max-vram-clock = Maximum VRAM Clock (MHz)
|
||||
max-gpu-voltage = Maximum GPU Voltage (mV)
|
||||
min-gpu-clock = Minimum GPU Clock (MHz)
|
||||
min-vram-clock = Minimum VRAM Clock (MHz)
|
||||
min-gpu-voltage = Minimum GPU Voltage (mV)
|
||||
gpu-voltage-offset = GPU voltage offset (mV)
|
||||
gpu-pstate-clock-offset = GPU P-State {$pstate} Clock Offset (MHz)
|
||||
vram-pstate-clock-offset = VRAM P-State {$pstate} Clock Offset (MHz)
|
||||
|
||||
pstates = Power States
|
||||
gpu-pstates = GPU Power States
|
||||
vram-pstates = VRAM Power States
|
||||
pstates-manual-needed = Note: performance level must be set to 'manual' to toggle power states
|
||||
enable-pstate-config = Enable power state configuration
|
||||
|
||||
show-historical-charts = Show historical charts
|
||||
show-process-montor = Show process monitor
|
||||
|
||||
settings-profile = Settings Profile
|
||||
auto-switch-profiles = Switch automatically
|
||||
add-profile = Add new profile
|
||||
import-profile = Import profile from file
|
||||
@@ -0,0 +1,8 @@
|
||||
info-page = Інформація
|
||||
oc-page = Розгін
|
||||
thermals-page = Температура
|
||||
software-page = Програми
|
||||
|
||||
hardware-info = Інформація про обладнання
|
||||
|
||||
watt = Вт
|
||||
+10
-9
@@ -11,7 +11,7 @@ mod process_monitor;
|
||||
|
||||
use crate::{
|
||||
app::process_monitor::{ProcessMonitorWindow, ProcessMonitorWindowMsg},
|
||||
APP_ID, GUI_VERSION,
|
||||
APP_ID, GUI_VERSION, I18N,
|
||||
};
|
||||
use anyhow::{anyhow, Context};
|
||||
use apply_revealer::{ApplyRevealer, ApplyRevealerMsg};
|
||||
@@ -31,6 +31,7 @@ use header::{
|
||||
profile_rule_window::{profile_row::ProfileRuleRowMsg, ProfileRuleWindowMsg},
|
||||
Header, HeaderMsg,
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_client::{ConnectionStatusMsg, DaemonClient};
|
||||
use lact_schema::{
|
||||
args::GuiArgs,
|
||||
@@ -130,10 +131,10 @@ impl AsyncComponent for AppModel {
|
||||
|
||||
add_binding: (&model.ui_sensitive, "sensitive"),
|
||||
|
||||
add_titled[Some("info_page"), "Information"] = model.info_page.widget(),
|
||||
add_titled[Some("oc_page"), "OC"] = model.oc_page.widget(),
|
||||
add_titled[Some("thermals_page"), "Thermals"] = model.thermals_page.widget(),
|
||||
add_titled[Some("software_page"), "Software"] = model.software_page.widget(),
|
||||
add_titled[Some("info_page"), &fl!(I18N, "info-page")] = model.info_page.widget(),
|
||||
add_titled[Some("oc_page"), &fl!(I18N, "oc-page")] = model.oc_page.widget(),
|
||||
add_titled[Some("thermals_page"), &fl!(I18N, "thermals-page")] = model.thermals_page.widget(),
|
||||
add_titled[Some("software_page"), &fl!(I18N, "software-page")] = model.software_page.widget(),
|
||||
},
|
||||
|
||||
model.apply_revealer.widget(),
|
||||
@@ -1197,8 +1198,8 @@ fn register_actions(sender: &AsyncComponentSender<AppModel>) {
|
||||
DisableOverdrive,
|
||||
AppMsg::ask_confirmation(
|
||||
AppMsg::DisableOverdrive,
|
||||
"Disable Overclocking",
|
||||
"This will disable AMD overclocking support (overdrive) on next reboot.",
|
||||
fl!(I18N, "disable-amd-oc"),
|
||||
fl!(I18N, "disable-amd-oc-description"),
|
||||
gtk::ButtonsType::OkCancel,
|
||||
)
|
||||
),
|
||||
@@ -1206,8 +1207,8 @@ fn register_actions(sender: &AsyncComponentSender<AppModel>) {
|
||||
ResetConfig,
|
||||
AppMsg::ask_confirmation(
|
||||
AppMsg::ResetConfig,
|
||||
"Reset configuration",
|
||||
"Are you sure you want to reset all GPU configuration?",
|
||||
fl!(I18N, "reset-config"),
|
||||
fl!(I18N, "reset-config-description"),
|
||||
gtk::ButtonsType::YesNo,
|
||||
)
|
||||
),
|
||||
|
||||
@@ -3,7 +3,7 @@ use relm4::{ComponentParts, ComponentSender, SimpleComponent};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ConfirmationOptions {
|
||||
pub title: &'static str,
|
||||
pub title: String,
|
||||
pub message: String,
|
||||
pub buttons_type: gtk::ButtonsType,
|
||||
}
|
||||
@@ -19,7 +19,7 @@ impl SimpleComponent for ConfirmationDialog {
|
||||
view! {
|
||||
gtk::MessageDialog {
|
||||
set_transient_for: Some(&parent),
|
||||
set_title: Some(options.title),
|
||||
set_title: Some(&options.title),
|
||||
set_use_markup: true,
|
||||
|
||||
connect_response[sender] => move |diag, response| {
|
||||
|
||||
@@ -5,13 +5,14 @@ pub mod profile_rule_window;
|
||||
|
||||
use crate::{
|
||||
app::{header::profile_rule_window::ProfileEditParams, ShowProcessMonitor, APP_BROKER},
|
||||
CONFIG,
|
||||
CONFIG, I18N,
|
||||
};
|
||||
|
||||
use super::{AppMsg, DebugSnapshot, DisableOverdrive, DumpVBios, ResetConfig, ShowGraphsWindow};
|
||||
use glib::clone;
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_client::schema::DeviceListEntry;
|
||||
use lact_schema::ProfilesInfo;
|
||||
use new_profile_dialog::NewProfileDialog;
|
||||
@@ -89,7 +90,7 @@ impl Component for Header {
|
||||
},
|
||||
|
||||
gtk::Frame {
|
||||
set_label: Some("Settings Profile"),
|
||||
set_label: Some(&fl!(I18N, "settings-profile")),
|
||||
set_label_align: 0.05,
|
||||
set_margin_all: 5,
|
||||
|
||||
@@ -98,7 +99,7 @@ impl Component for Header {
|
||||
set_spacing: 5,
|
||||
|
||||
gtk::CheckButton {
|
||||
set_label: Some("Switch automatically"),
|
||||
set_label: Some(&fl!(I18N, "auto-switch-profiles")),
|
||||
set_margin_horizontal: 5,
|
||||
#[watch]
|
||||
#[block_signal(toggle_auto_profile_handler)]
|
||||
@@ -125,13 +126,13 @@ impl Component for Header {
|
||||
gtk::Button {
|
||||
set_expand: true,
|
||||
set_icon_name: "list-add",
|
||||
set_tooltip: "Add new profile",
|
||||
set_tooltip: &fl!(I18N, "add-profile"),
|
||||
connect_clicked => HeaderMsg::CreateProfile,
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_icon_name: "document-import-symbolic",
|
||||
set_tooltip: "Import profile from file",
|
||||
set_tooltip: &fl!(I18N, "import-profile"),
|
||||
set_expand: true,
|
||||
connect_clicked => HeaderMsg::ImportProfile,
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ mod imp {
|
||||
}
|
||||
|
||||
obj.bind_property("name", &name_label, "label")
|
||||
.transform_to(|_, value: &str| Some(format!("{value}:")))
|
||||
.sync_create()
|
||||
.build();
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ pub enum AppMsg {
|
||||
impl AppMsg {
|
||||
pub fn ask_confirmation(
|
||||
inner: AppMsg,
|
||||
title: &'static str,
|
||||
title: String,
|
||||
message: impl Into<String>,
|
||||
buttons_type: gtk::ButtonsType,
|
||||
) -> Self {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use super::PageUpdate;
|
||||
use crate::app::{info_row::InfoRow, page_section::PageSection};
|
||||
use crate::app::info_row::InfoRowItem;
|
||||
use crate::app::page_section::PageSection;
|
||||
use crate::I18N;
|
||||
use gtk::prelude::*;
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_schema::{DeviceInfo, DeviceStats};
|
||||
use relm4::{prelude::FactoryVecDeque, ComponentParts, ComponentSender, RelmWidgetExt};
|
||||
use std::sync::Arc;
|
||||
@@ -26,7 +29,7 @@ impl relm4::SimpleComponent for InformationPage {
|
||||
set_spacing: 15,
|
||||
set_margin_horizontal: 20,
|
||||
|
||||
PageSection::new("Hardware Information") {
|
||||
PageSection::new(&fl!(I18N, "hardware-info")) {
|
||||
append = &model.values_list.widget().clone() -> gtk::Box {
|
||||
set_spacing: 10,
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
@@ -79,45 +82,9 @@ impl InformationPage {
|
||||
None
|
||||
};
|
||||
|
||||
values_list.push_back(InfoRowItem {
|
||||
name: format!("{name}:"),
|
||||
value,
|
||||
note,
|
||||
});
|
||||
values_list.push_back(InfoRowItem { name, value, note });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InfoRowItem {
|
||||
name: String,
|
||||
value: String,
|
||||
note: Option<&'static str>,
|
||||
}
|
||||
|
||||
#[relm4::factory]
|
||||
impl relm4::factory::FactoryComponent for InfoRowItem {
|
||||
type Init = Self;
|
||||
type ParentWidget = gtk::Box;
|
||||
type CommandOutput = ();
|
||||
type Input = ();
|
||||
type Output = ();
|
||||
|
||||
fn init_model(
|
||||
init: Self::Init,
|
||||
_index: &Self::Index,
|
||||
_sender: relm4::FactorySender<Self>,
|
||||
) -> Self {
|
||||
init
|
||||
}
|
||||
|
||||
view! {
|
||||
InfoRow {
|
||||
set_selectable: true,
|
||||
set_name: self.name.clone(),
|
||||
set_value: self.value.clone(),
|
||||
set_info_text: self.note.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ mod power_cap_section;
|
||||
mod power_states;
|
||||
|
||||
use super::PageUpdate;
|
||||
use crate::app::{ext::RelmDefaultLauchable, msg::AppMsg};
|
||||
use crate::{
|
||||
app::{ext::RelmDefaultLauchable, msg::AppMsg},
|
||||
I18N,
|
||||
};
|
||||
use amdgpu_sysfs::gpu_handle::{
|
||||
power_profile_mode::PowerProfileModesTable, PerformanceLevel, PowerLevelKind,
|
||||
};
|
||||
@@ -15,6 +18,7 @@ use gtk::{
|
||||
pango,
|
||||
prelude::{BoxExt, ButtonExt, FrameExt, OrientableExt, WidgetExt},
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
use indexmap::IndexMap;
|
||||
use lact_daemon::BASE_MODULE_CONF_PATH;
|
||||
use lact_schema::{request::SetClocksCommand, ClocksTable, DeviceInfo, PowerStates, SystemInfo};
|
||||
@@ -24,9 +28,6 @@ use power_states::power_states_frame::{PowerStatesFrame, PowerStatesFrameMsg};
|
||||
use relm4::{ComponentController, ComponentParts, ComponentSender, RelmWidgetExt};
|
||||
use std::sync::Arc;
|
||||
|
||||
const OVERCLOCKING_DISABLED_TEXT: &str = "AMD Overclocking support is not enabled! \
|
||||
You can still change basic settings, but the more advanced clocks and voltage control will not be available.";
|
||||
|
||||
pub struct OcPage {
|
||||
stats_section: relm4::Controller<GpuStatsSection>,
|
||||
system_info: SystemInfo,
|
||||
@@ -80,20 +81,20 @@ impl relm4::Component for OcPage {
|
||||
set_margin_all: 10,
|
||||
|
||||
gtk::Label {
|
||||
set_markup: OVERCLOCKING_DISABLED_TEXT,
|
||||
set_markup: &fl!(I18N, "amd-oc-disabled"),
|
||||
set_wrap: true,
|
||||
set_wrap_mode: pango::WrapMode::Word,
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label: "Enable AMD Overclocking",
|
||||
set_label: &fl!(I18N, "enable-amd-oc"),
|
||||
set_halign: gtk::Align::End,
|
||||
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.output(AppMsg::ask_confirmation(
|
||||
AppMsg::EnableOverdrive,
|
||||
"Enable AMD Overclocking",
|
||||
format!("This will enable the overdrive feature of the amdgpu driver by creating a file at <b>{BASE_MODULE_CONF_PATH}</b> and updating the initramfs. Are you sure you want to do this?"),
|
||||
fl!(I18N, "enable-amd-oc"),
|
||||
fl!(I18N, "enable-amd-oc-description", path = BASE_MODULE_CONF_PATH),
|
||||
gtk::ButtonsType::OkCancel,
|
||||
)).expect("Channel closed");
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ mod adjustment_row;
|
||||
|
||||
use crate::{
|
||||
app::{msg::AppMsg, page_section::PageSection},
|
||||
APP_BROKER,
|
||||
APP_BROKER, I18N,
|
||||
};
|
||||
use adjustment_row::{ClockAdjustmentRow, ClockAdjustmentRowMsg, ClocksData};
|
||||
use amdgpu_sysfs::gpu_handle::overdrive::{ClocksTable as _, ClocksTableGen as AmdClocksTable};
|
||||
@@ -11,6 +11,7 @@ use gtk::{
|
||||
pango,
|
||||
prelude::{BoxExt, ButtonExt, CheckButtonExt, OrientableExt, WidgetExt},
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_schema::{
|
||||
request::{ClockspeedType, SetClocksCommand},
|
||||
ClocksTable, IntelClocksTable, NvidiaClockOffset, NvidiaClocksTable,
|
||||
@@ -22,20 +23,6 @@ use relm4::{
|
||||
|
||||
// This is only used on RDNA1 in practice
|
||||
const DEFAULT_VOLTAGE_OFFSET_RANGE: i32 = 250;
|
||||
const WARNING_TEXT: &str = "Warning: changing these values may lead to system instability and can potentially damage your hardware!";
|
||||
const NVIDIA_OC_INFO_TEXT: &str = "\
|
||||
Overclocking functionality on Nvidia includes setting offsets for GPU/VRAM clockspeeds and limiting the potential range of clockspeeds using the \"locked clocks\" feature.
|
||||
|
||||
On many cards, the VRAM clockpeed offset will only affect the actual memory clockspeed by half of the offset value. \
|
||||
For example, a +1000MHz VRAM offset may only increase the measured VRAM speed by 500MHz. \
|
||||
This is normal, and is how Nvidia handles GDDR data rates. Adjust your overclock accordingly.
|
||||
|
||||
Direct voltage control is not supported, as it does not exist in the Nvidia Linux driver.
|
||||
|
||||
It is possible to achieve a pseudo-undervolt by combining the locked clocks option with a positive clockspeed offset. \
|
||||
This will force the GPU to run at a voltage that's constrained by the locked clocks, while achieving a higher clockspeed due to the offset. \
|
||||
This can cause system instability if pushed too high.\
|
||||
";
|
||||
|
||||
pub struct ClocksFrame {
|
||||
clocks: FactoryHashMap<ClockspeedType, ClockAdjustmentRow>,
|
||||
@@ -61,9 +48,9 @@ impl relm4::Component for ClocksFrame {
|
||||
type CommandOutput = ();
|
||||
|
||||
view! {
|
||||
PageSection::new("Clockspeed and Voltage") {
|
||||
PageSection::new(&fl!(I18N, "overclock-section")) {
|
||||
append = >k::Label {
|
||||
set_label: WARNING_TEXT,
|
||||
set_label: &fl!(I18N, "oc-warning"),
|
||||
set_wrap_mode: pango::WrapMode::Word,
|
||||
set_halign: gtk::Align::Start,
|
||||
set_margin_horizontal: 5,
|
||||
@@ -83,7 +70,7 @@ impl relm4::Component for ClocksFrame {
|
||||
set_popover = >k::Popover {
|
||||
gtk::Label {
|
||||
set_margin_all: 5,
|
||||
set_markup: NVIDIA_OC_INFO_TEXT,
|
||||
set_markup: &fl!(I18N, "nvidia-oc-description"),
|
||||
set_wrap: true,
|
||||
set_max_width_chars: 75,
|
||||
}
|
||||
@@ -91,7 +78,7 @@ impl relm4::Component for ClocksFrame {
|
||||
},
|
||||
|
||||
append = >k::Label {
|
||||
set_label: "Nvidia Overclocking Information",
|
||||
set_label: &fl!(I18N, "nvidia-oc-info"),
|
||||
add_css_class: "heading",
|
||||
},
|
||||
},
|
||||
@@ -109,12 +96,12 @@ impl relm4::Component for ClocksFrame {
|
||||
set_hexpand: true,
|
||||
|
||||
append = >k::CheckButton {
|
||||
set_label: Some("Show all P-States"),
|
||||
set_label: Some(&fl!(I18N, "show-all-pstates")),
|
||||
add_binding["active"]: &model.show_all_pstates,
|
||||
},
|
||||
|
||||
append: gpu_locked_clocks_togglebutton = >k::CheckButton {
|
||||
set_label: Some("Enable GPU Locked Clocks"),
|
||||
set_label: Some(&fl!(I18N, "enable-gpu-locked-clocks")),
|
||||
add_binding["active"]: &model.enable_gpu_locked_clocks,
|
||||
connect_toggled => move |_| {
|
||||
APP_BROKER.send(AppMsg::SettingsChanged);
|
||||
@@ -122,7 +109,7 @@ impl relm4::Component for ClocksFrame {
|
||||
},
|
||||
|
||||
append: vram_locked_clocks_togglebutton = >k::CheckButton {
|
||||
set_label: Some("Enable VRAM Locked Clocks"),
|
||||
set_label: Some(&fl!(I18N, "enable-vram-locked-clocks")),
|
||||
add_binding["active"]: &model.enable_vram_locked_clocks,
|
||||
connect_toggled => move |_| {
|
||||
APP_BROKER.send(AppMsg::SettingsChanged);
|
||||
@@ -134,7 +121,7 @@ impl relm4::Component for ClocksFrame {
|
||||
add_binding["visible"]: &model.show_all_pstates,
|
||||
|
||||
set_margin_horizontal: 5,
|
||||
set_markup: "<b>The following values are clock offsets for each P-State, going from highest to lowest.</b>",
|
||||
set_markup: &fl!(I18N, "pstate-list-description"),
|
||||
set_wrap_mode: pango::WrapMode::Word,
|
||||
set_halign: gtk::Align::Start,
|
||||
},
|
||||
@@ -147,7 +134,7 @@ impl relm4::Component for ClocksFrame {
|
||||
},
|
||||
|
||||
append = >k::Label {
|
||||
set_label: "No clocks data available",
|
||||
set_label: &fl!(I18N, "no-clocks-data"),
|
||||
set_margin_horizontal: 10,
|
||||
set_halign: gtk::Align::Start,
|
||||
#[watch]
|
||||
@@ -155,10 +142,10 @@ impl relm4::Component for ClocksFrame {
|
||||
},
|
||||
|
||||
append = >k::Button {
|
||||
set_label: "Reset",
|
||||
set_label: &fl!(I18N, "reset-button"),
|
||||
set_halign: gtk::Align::End,
|
||||
set_margin_horizontal: 5,
|
||||
set_tooltip_text: Some("Warning: this resets all clock settings to defaults!"),
|
||||
set_tooltip_text: Some(&fl!(I18N, "reset-oc-tooltip")),
|
||||
set_css_classes: &["destructive-action"],
|
||||
#[watch]
|
||||
set_visible: !model.clocks.is_empty(),
|
||||
@@ -319,7 +306,7 @@ impl ClocksFrame {
|
||||
current: sclk_offset,
|
||||
min: sclk_offset_min,
|
||||
max: sclk_offset_max,
|
||||
custom_title: Some("Maximum GPU Clock Offset (MHz)"),
|
||||
custom_title: Some(fl!(I18N, "gpu-clock-offset")),
|
||||
is_secondary: false,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
use crate::{
|
||||
app::{msg::AppMsg, pages::oc_adjustment::OcAdjustment},
|
||||
APP_BROKER,
|
||||
APP_BROKER, I18N,
|
||||
};
|
||||
use gtk::{
|
||||
glib::{object::ObjectExt, SignalHandlerId},
|
||||
prelude::{AdjustmentExt, OrientableExt, RangeExt, ScaleExt, WidgetExt},
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_schema::request::ClockspeedType;
|
||||
use relm4::{prelude::FactoryComponent, RelmWidgetExt};
|
||||
|
||||
pub struct ClockAdjustmentRow {
|
||||
clock_type: ClockspeedType,
|
||||
custom_title: Option<&'static str>,
|
||||
custom_title: Option<String>,
|
||||
value_ratio: f64,
|
||||
change_signal: SignalHandlerId,
|
||||
adjustment: OcAdjustment,
|
||||
@@ -22,7 +23,7 @@ pub struct ClocksData {
|
||||
pub current: i32,
|
||||
pub min: i32,
|
||||
pub max: i32,
|
||||
pub custom_title: Option<&'static str>,
|
||||
pub custom_title: Option<String>,
|
||||
pub is_secondary: bool,
|
||||
}
|
||||
|
||||
@@ -64,19 +65,19 @@ impl FactoryComponent for ClockAdjustmentRow {
|
||||
gtk::Label {
|
||||
set_xalign: 0.0,
|
||||
#[watch]
|
||||
set_markup: &match self.custom_title {
|
||||
Some(title) => title.to_owned(),
|
||||
set_markup: &match &self.custom_title {
|
||||
Some(title) => title.clone(),
|
||||
None => {
|
||||
match self.clock_type {
|
||||
ClockspeedType::MaxCoreClock => "Maximum GPU Clock (MHz)".to_owned(),
|
||||
ClockspeedType::MaxMemoryClock => "Maximum VRAM Clock (MHz)".to_owned(),
|
||||
ClockspeedType::MaxVoltage => "Maximum GPU voltage (mV)".to_owned(),
|
||||
ClockspeedType::MinCoreClock => "Minimum GPU Clock (MHz)".to_owned(),
|
||||
ClockspeedType::MinMemoryClock => "Minimum VRAM Clock (MHz)".to_owned(),
|
||||
ClockspeedType::MinVoltage => "Minimum GPU voltage (mV)".to_owned(),
|
||||
ClockspeedType::VoltageOffset => "GPU voltage offset (mV)".to_owned(),
|
||||
ClockspeedType::GpuClockOffset(pstate) => format!("GPU P-State {pstate} Clock Offset (MHz)"),
|
||||
ClockspeedType::MemClockOffset(pstate) => format!("VRAM P-State {pstate} Clock Offset (MHz)"),
|
||||
ClockspeedType::MaxCoreClock => fl!(I18N, "max-gpu-clock"),
|
||||
ClockspeedType::MaxMemoryClock => fl!(I18N, "max-vram-clock"),
|
||||
ClockspeedType::MaxVoltage => fl!(I18N, "max-gpu-voltage"),
|
||||
ClockspeedType::MinCoreClock => fl!(I18N, "min-gpu-clock"),
|
||||
ClockspeedType::MinMemoryClock => fl!(I18N, "min-vram-clock"),
|
||||
ClockspeedType::MinVoltage => fl!(I18N, "min-gpu-voltage"),
|
||||
ClockspeedType::VoltageOffset => fl!(I18N, "gpu-voltage-offset"),
|
||||
ClockspeedType::GpuClockOffset(pstate) => fl!(I18N, "gpu-pstate-clock-offset", pstate = pstate),
|
||||
ClockspeedType::MemClockOffset(pstate) => fl!(I18N, "vram-pstate-clock-offset", pstate = pstate),
|
||||
ClockspeedType::Reset => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use crate::app::{
|
||||
ext::FlowBoxExt, info_row::InfoRow, page_section::PageSection, pages::PageUpdate,
|
||||
};
|
||||
use crate::I18N;
|
||||
use gtk::prelude::{ActionableExt, BoxExt, ButtonExt, OrientableExt, WidgetExt};
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_schema::{DeviceStats, PowerStats};
|
||||
use relm4::{ComponentParts, ComponentSender};
|
||||
use std::{fmt::Write, sync::Arc};
|
||||
@@ -18,7 +20,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
type Output = ();
|
||||
|
||||
view! {
|
||||
PageSection::new("Statistics") {
|
||||
PageSection::new(&fl!(I18N, "stats-section")) {
|
||||
append = >k::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_spacing: 5,
|
||||
@@ -44,9 +46,10 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
add_overlay = >k::Label {
|
||||
#[watch]
|
||||
set_label: &format!(
|
||||
"{}/{} MiB",
|
||||
"{}/{} {}",
|
||||
model.stats.vram.used.unwrap_or(0) / 1024 / 1024,
|
||||
model.stats.vram.total.unwrap_or(0) / 1024 / 1024,
|
||||
fl!(I18N, "mebibyte")
|
||||
),
|
||||
}
|
||||
},
|
||||
@@ -60,7 +63,15 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
set_selection_mode: gtk::SelectionMode::None,
|
||||
|
||||
append_child = &InfoRow {
|
||||
set_name: "GPU Core Clock (Average):",
|
||||
#[watch]
|
||||
set_name: {
|
||||
if model.stats.clockspeed.gpu_clockspeed.is_some()
|
||||
&& model.stats.clockspeed.current_gfxclk.is_some() {
|
||||
fl!(I18N, "gpu-clock-avg")
|
||||
} else {
|
||||
fl!(I18N, "gpu-clock")
|
||||
}
|
||||
},
|
||||
#[watch]
|
||||
set_value: format_clockspeed(model.stats.clockspeed.gpu_clockspeed, 1.0),
|
||||
set_spacing: 40,
|
||||
@@ -70,7 +81,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
},
|
||||
|
||||
append_child = &InfoRow {
|
||||
set_name: "GPU Core Clock (Target):",
|
||||
set_name: fl!(I18N, "gpu-clock-target"),
|
||||
#[watch]
|
||||
set_value: format_current_gfxclk(model.stats.clockspeed.current_gfxclk),
|
||||
set_spacing: 40,
|
||||
@@ -80,7 +91,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
},
|
||||
|
||||
append_child = &InfoRow {
|
||||
set_name: "GPU Voltage:",
|
||||
set_name: fl!(I18N, "gpu-voltage"),
|
||||
#[watch]
|
||||
set_value: format!("{:.3} V", model.stats.voltage.gpu.unwrap_or(0) as f64 / 1000f64),
|
||||
set_spacing: 40,
|
||||
@@ -90,15 +101,14 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
},
|
||||
|
||||
append = &InfoRow {
|
||||
#[watch]
|
||||
set_name: "Temperature:",
|
||||
set_name: fl!(I18N, "gpu-temp"),
|
||||
#[watch]
|
||||
set_value: temperature_text(&model.stats).unwrap_or_else(|| "N/A".to_owned()),
|
||||
set_spacing: 40,
|
||||
},
|
||||
|
||||
append_child = &InfoRow {
|
||||
set_name: "GPU Memory Clock:",
|
||||
set_name: fl!(I18N, "vram-clock"),
|
||||
#[watch]
|
||||
set_value: format_clockspeed(
|
||||
model.stats.clockspeed.vram_clockspeed,
|
||||
@@ -111,7 +121,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
},
|
||||
|
||||
append_child = &InfoRow {
|
||||
set_name: "GPU Usage:",
|
||||
set_name: fl!(I18N, "gpu-usage"),
|
||||
#[watch]
|
||||
set_value: format!("{}%", model.stats.busy_percent.unwrap_or(0)),
|
||||
set_spacing: 40,
|
||||
@@ -121,7 +131,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
},
|
||||
|
||||
append_child = &InfoRow {
|
||||
set_name: "Power Usage:",
|
||||
set_name: fl!(I18N, "power-usage"),
|
||||
#[watch]
|
||||
set_value: {
|
||||
let PowerStats {
|
||||
@@ -136,9 +146,10 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
.or(power_average);
|
||||
|
||||
format!(
|
||||
"<b>{:.1}/{} W</b>",
|
||||
"<b>{:.1}/{} {}</b>",
|
||||
power_current.unwrap_or(0.0),
|
||||
power_cap_current.unwrap_or(0.0)
|
||||
power_cap_current.unwrap_or(0.0),
|
||||
fl!(I18N, "watt")
|
||||
)
|
||||
},
|
||||
set_spacing: 40,
|
||||
@@ -148,7 +159,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
},
|
||||
|
||||
append = &InfoRow {
|
||||
set_name: "Throttling:",
|
||||
set_name: fl!(I18N, "throttling"),
|
||||
#[watch]
|
||||
set_value: throttling_text(&model.stats),
|
||||
set_spacing: 40,
|
||||
@@ -156,7 +167,7 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
},
|
||||
|
||||
append = >k::Button {
|
||||
set_label: "Show historical charts",
|
||||
set_label: &fl!(I18N, "show-historical-charts"),
|
||||
set_action_name: Some("app.show-graphs-window"),
|
||||
},
|
||||
}
|
||||
@@ -190,7 +201,11 @@ impl relm4::SimpleComponent for GpuStatsSection {
|
||||
}
|
||||
|
||||
fn format_clockspeed(value: Option<u64>, ratio: f64) -> String {
|
||||
format!("{:.3} GHz", value.unwrap_or(0) as f64 / 1000.0 * ratio)
|
||||
format!(
|
||||
"{:.3} {}",
|
||||
value.unwrap_or(0) as f64 / 1000.0 * ratio,
|
||||
fl!(I18N, "ghz")
|
||||
)
|
||||
}
|
||||
|
||||
fn format_current_gfxclk(value: Option<u64>) -> String {
|
||||
@@ -198,12 +213,12 @@ fn format_current_gfxclk(value: Option<u64>) -> String {
|
||||
// if the APU/GPU dose not acually support current_gfxclk,
|
||||
// the value will be `u16::MAX (65535)`
|
||||
if v >= u16::MAX as u64 || v == 0 {
|
||||
"N/A".to_string()
|
||||
fl!(I18N, "missing-stat")
|
||||
} else {
|
||||
format_clockspeed(Some(v), 1.0)
|
||||
}
|
||||
} else {
|
||||
"N/A".to_string()
|
||||
fl!(I18N, "missing-stat")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +226,7 @@ pub fn throttling_text(stats: &DeviceStats) -> String {
|
||||
match &stats.throttle_info {
|
||||
Some(throttle_info) => {
|
||||
if throttle_info.is_empty() {
|
||||
"No".to_owned()
|
||||
fl!(I18N, "no-throttling")
|
||||
} else {
|
||||
let type_text: Vec<String> = throttle_info
|
||||
.iter()
|
||||
@@ -227,7 +242,9 @@ pub fn throttling_text(stats: &DeviceStats) -> String {
|
||||
type_text.join(", ")
|
||||
}
|
||||
}
|
||||
None => "Unknown".to_owned(),
|
||||
None => {
|
||||
fl!(I18N, "unknown-throttling")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ mod heuristics_list;
|
||||
use super::OcPageMsg;
|
||||
use crate::{
|
||||
app::{msg::AppMsg, page_section::PageSection},
|
||||
APP_BROKER,
|
||||
APP_BROKER, I18N,
|
||||
};
|
||||
use amdgpu_sysfs::gpu_handle::{power_profile_mode::PowerProfileModesTable, PerformanceLevel};
|
||||
use gtk::{
|
||||
@@ -13,6 +13,7 @@ use gtk::{
|
||||
StringObject,
|
||||
};
|
||||
use heuristics_list::PowerProfileHeuristicsList;
|
||||
use i18n_embed_fl::fl;
|
||||
use relm4::{Component, ComponentController, ComponentParts, ComponentSender, RelmWidgetExt};
|
||||
|
||||
const PERFORMANCE_LEVELS: [PerformanceLevel; 4] = [
|
||||
@@ -58,18 +59,18 @@ impl relm4::Component for PerformanceFrame {
|
||||
|
||||
gtk::Label {
|
||||
#[watch]
|
||||
set_label: match model.performance_level {
|
||||
Some(PerformanceLevel::Auto) => "Automatically adjust GPU and VRAM clocks. (Default)",
|
||||
Some(PerformanceLevel::High) => "Always use the highest clockspeeds for GPU and VRAM.",
|
||||
Some(PerformanceLevel::Low) => "Always use the lowest clockspeeds for GPU and VRAM.",
|
||||
Some(PerformanceLevel::Manual) => "Manual performance control.",
|
||||
_ => "",
|
||||
set_label: &match model.performance_level {
|
||||
Some(PerformanceLevel::Auto) => fl!(I18N, "performance-level-auto-description"),
|
||||
Some(PerformanceLevel::High) => fl!(I18N, "performance-level-high-description"),
|
||||
Some(PerformanceLevel::Low) => fl!(I18N, "performance-level-low-description"),
|
||||
Some(PerformanceLevel::Manual) => fl!(I18N, "performance-level-manual-description"),
|
||||
_ => String::new(),
|
||||
},
|
||||
set_hexpand: true,
|
||||
set_halign: gtk::Align::End,
|
||||
},
|
||||
|
||||
gtk::DropDown::from_strings(&PERFORMANCE_LEVELS.map(level_friendly_name)) {
|
||||
gtk::DropDown::from_strings(&level_names_ref) {
|
||||
#[watch]
|
||||
#[block_signal(level_select_handler)]
|
||||
set_selected: PERFORMANCE_LEVELS.iter().position(|level| model.performance_level == Some(*level)).unwrap_or(0) as u32,
|
||||
@@ -90,7 +91,7 @@ impl relm4::Component for PerformanceFrame {
|
||||
set_spacing: 10,
|
||||
|
||||
gtk::Label {
|
||||
set_label: "Power Profile Mode:",
|
||||
set_label: &fl!(I18N, "power-profile-mode"),
|
||||
set_hexpand: true,
|
||||
set_halign: gtk::Align::Start,
|
||||
},
|
||||
@@ -103,7 +104,7 @@ impl relm4::Component for PerformanceFrame {
|
||||
#[wrap(Some)]
|
||||
set_popover = >k::Popover {
|
||||
gtk::Label {
|
||||
set_label: "Performance level has to be set to \"manual\" to use power states and modes",
|
||||
set_label: &fl!(I18N, "manual-level-needed"),
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -160,6 +161,12 @@ impl relm4::Component for PerformanceFrame {
|
||||
_root: Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
let level_names = PERFORMANCE_LEVELS.map(level_friendly_name);
|
||||
let level_names_ref = level_names
|
||||
.iter()
|
||||
.map(|level| level.as_str())
|
||||
.collect::<Vec<&str>>();
|
||||
|
||||
let model = Self {
|
||||
performance_level: None,
|
||||
power_profile_modes_table: None,
|
||||
@@ -282,11 +289,11 @@ impl PerformanceFrame {
|
||||
}
|
||||
}
|
||||
|
||||
const fn level_friendly_name(level: PerformanceLevel) -> &'static str {
|
||||
fn level_friendly_name(level: PerformanceLevel) -> String {
|
||||
match level {
|
||||
PerformanceLevel::Auto => "Automatic",
|
||||
PerformanceLevel::Low => "Lowest Clocks",
|
||||
PerformanceLevel::High => "Highest Clocks",
|
||||
PerformanceLevel::Manual => "Manual",
|
||||
PerformanceLevel::Auto => fl!(I18N, "performance-level-auto"),
|
||||
PerformanceLevel::Low => fl!(I18N, "performance-level-low"),
|
||||
PerformanceLevel::High => fl!(I18N, "performance-level-high"),
|
||||
PerformanceLevel::Manual => fl!(I18N, "performance-level-manual"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ use crate::{
|
||||
page_section::PageSection,
|
||||
pages::{oc_adjustment::OcAdjustment, PageUpdate},
|
||||
},
|
||||
APP_BROKER,
|
||||
APP_BROKER, I18N,
|
||||
};
|
||||
use gtk::{
|
||||
glib::object::ObjectExt,
|
||||
prelude::{AdjustmentExt, BoxExt, ButtonExt, OrientableExt, RangeExt, ScaleExt, WidgetExt},
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_schema::PowerStats;
|
||||
use relm4::{ComponentParts, ComponentSender, RelmWidgetExt};
|
||||
use std::fmt::Write;
|
||||
@@ -37,7 +38,7 @@ impl relm4::Component for PowerCapSection {
|
||||
|
||||
view! {
|
||||
#[root]
|
||||
PageSection::new("Power usage limit") {
|
||||
PageSection::new(&fl!(I18N, "power-cap")) {
|
||||
append = >k::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
|
||||
@@ -56,7 +57,7 @@ impl relm4::Component for PowerCapSection {
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label: "Default",
|
||||
set_label: &fl!(I18N, "reset-button"),
|
||||
connect_clicked => PowerCapMsg::Reset,
|
||||
},
|
||||
}
|
||||
@@ -113,9 +114,10 @@ impl relm4::Component for PowerCapSection {
|
||||
self.value_text.clear();
|
||||
write!(
|
||||
self.value_text,
|
||||
"{}/{} W",
|
||||
"{}/{} {}",
|
||||
self.adjustment.value(),
|
||||
self.adjustment.upper()
|
||||
self.adjustment.upper(),
|
||||
fl!(I18N, "watt")
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -6,13 +6,14 @@ use crate::{
|
||||
PowerStatesListMsg, PowerStatesListOptions,
|
||||
},
|
||||
},
|
||||
APP_BROKER,
|
||||
APP_BROKER, I18N,
|
||||
};
|
||||
use amdgpu_sysfs::gpu_handle::{PerformanceLevel, PowerLevelKind};
|
||||
use gtk::{
|
||||
glib::{object::ObjectExt, SignalHandlerId},
|
||||
prelude::{BoxExt, CheckButtonExt, OrientableExt, WidgetExt},
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
use indexmap::IndexMap;
|
||||
use lact_schema::{DeviceStats, PowerStates};
|
||||
use relm4::{
|
||||
@@ -52,7 +53,7 @@ impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
|
||||
view! {
|
||||
gtk::Expander {
|
||||
set_label: Some("Power states"),
|
||||
set_label: Some(&fl!(I18N, "pstates")),
|
||||
add_binding: (&model.states_expanded, "expanded"),
|
||||
|
||||
gtk::Box {
|
||||
@@ -62,7 +63,7 @@ impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
add_binding: (&model.states_configurable, "sensitive"),
|
||||
|
||||
gtk::Label {
|
||||
set_label: "Note: performance level must be set to 'manual' to toggle power states",
|
||||
set_label: &fl!(I18N, "pstates-manual-needed"),
|
||||
set_margin_horizontal: 10,
|
||||
set_halign: gtk::Align::Start,
|
||||
#[watch]
|
||||
@@ -70,7 +71,7 @@ impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
},
|
||||
|
||||
gtk::CheckButton {
|
||||
set_label: Some("Enable power state configuration"),
|
||||
set_label: Some(&fl!(I18N, "enable-pstate-config")),
|
||||
add_binding: (&model.states_configured, "active"),
|
||||
#[watch]
|
||||
set_visible: model.performance_level.is_some(),
|
||||
@@ -95,14 +96,14 @@ impl relm4::SimpleComponent for PowerStatesFrame {
|
||||
) -> ComponentParts<Self> {
|
||||
let core_states_list = PowerStatesList::builder()
|
||||
.launch(PowerStatesListOptions {
|
||||
title: "GPU Power States",
|
||||
value_suffix: "MHz",
|
||||
title: fl!(I18N, "gpu-pstates"),
|
||||
value_suffix: fl!(I18N, "mhz"),
|
||||
})
|
||||
.detach();
|
||||
let vram_states_list = PowerStatesList::builder()
|
||||
.launch(PowerStatesListOptions {
|
||||
title: "VRAM Power States",
|
||||
value_suffix: "MHz",
|
||||
title: fl!(I18N, "vram-pstates"),
|
||||
value_suffix: fl!(I18N, "mhz"),
|
||||
})
|
||||
.detach();
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ use crate::{app::msg::AppMsg, APP_BROKER};
|
||||
|
||||
pub struct PowerStatesList {
|
||||
states: FactoryVecDeque<PowerStateRow>,
|
||||
value_suffix: &'static str,
|
||||
value_suffix: String,
|
||||
}
|
||||
|
||||
pub struct PowerStatesListOptions {
|
||||
pub title: &'static str,
|
||||
pub value_suffix: &'static str,
|
||||
pub title: String,
|
||||
pub value_suffix: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -31,7 +31,7 @@ impl relm4::SimpleComponent for PowerStatesList {
|
||||
view! {
|
||||
gtk::Frame {
|
||||
set_hexpand: true,
|
||||
set_label: Some(opts.title),
|
||||
set_label: Some(&opts.title),
|
||||
set_child: Some(model.states.widget()),
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ impl relm4::SimpleComponent for PowerStatesList {
|
||||
power_state.value = (power_state.value as f64 * value_ratio) as u64;
|
||||
let opts = PowerStateRowOptions {
|
||||
power_state,
|
||||
value_suffix: self.value_suffix,
|
||||
value_suffix: self.value_suffix.clone(),
|
||||
active: false,
|
||||
};
|
||||
states.push_back(opts);
|
||||
@@ -97,12 +97,12 @@ struct PowerStateRow {
|
||||
active: BoolBinding,
|
||||
enabled: BoolBinding,
|
||||
power_state: PowerState,
|
||||
value_suffix: &'static str,
|
||||
value_suffix: String,
|
||||
}
|
||||
|
||||
pub struct PowerStateRowOptions {
|
||||
pub power_state: PowerState,
|
||||
pub value_suffix: &'static str,
|
||||
pub value_suffix: String,
|
||||
pub active: bool,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@ mod vulkan;
|
||||
|
||||
use crate::{
|
||||
app::{format_friendly_size, info_row::InfoRow, page_section::PageSection},
|
||||
GUI_VERSION, REPO_URL,
|
||||
GUI_VERSION, I18N, REPO_URL,
|
||||
};
|
||||
use gtk::prelude::*;
|
||||
use i18n_embed_fl::fl;
|
||||
use indexmap::IndexMap;
|
||||
use lact_client::schema::{SystemInfo, GIT_COMMIT};
|
||||
use lact_schema::{DeviceInfo, VulkanInfo};
|
||||
@@ -42,10 +43,10 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
set_spacing: 15,
|
||||
set_margin_horizontal: 20,
|
||||
|
||||
PageSection::new("System") {
|
||||
append = &InfoRow::new_selectable("LACT Daemon:", &daemon_version),
|
||||
append = &InfoRow::new_selectable("LACT GUI:", &gui_version),
|
||||
append = &InfoRow::new_selectable("Kernel Version:", &system_info.kernel_version),
|
||||
PageSection::new(&fl!(I18N, "system-section")) {
|
||||
append = &InfoRow::new_selectable(&fl!(I18N, "lact-daemon"), &daemon_version),
|
||||
append = &InfoRow::new_selectable(&fl!(I18N, "lact-gui"), &gui_version),
|
||||
append = &InfoRow::new_selectable(&fl!(I18N, "kernel-version"), &system_info.kernel_version),
|
||||
},
|
||||
|
||||
#[name = "vulkan_stack"]
|
||||
@@ -61,32 +62,32 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
append = >k::Label {
|
||||
set_halign: gtk::Align::Start,
|
||||
set_hexpand: true,
|
||||
set_label: "Instance:"
|
||||
set_label: &fl!(I18N, "instance"),
|
||||
},
|
||||
|
||||
append = model.vulkan_driver_selector.widget(),
|
||||
},
|
||||
|
||||
append = &InfoRow {
|
||||
set_name: "Device Name:",
|
||||
set_name: fl!(I18N, "device-name"),
|
||||
#[watch]
|
||||
set_value: info.device_name.as_str(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "API Version:",
|
||||
set_name: fl!(I18N, "api-version"),
|
||||
#[watch]
|
||||
set_value: info.api_version.as_str(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Driver Name:",
|
||||
set_name: fl!(I18N, "driver-name"),
|
||||
#[watch]
|
||||
set_value: info.driver.name.as_deref().unwrap_or_default(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Driver Version:",
|
||||
set_name: fl!(I18N, "driver-version"),
|
||||
#[watch]
|
||||
set_value: info.driver.info.as_deref().unwrap_or_default(),
|
||||
set_selectable: true,
|
||||
@@ -99,12 +100,12 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
append = >k::Label {
|
||||
set_halign: gtk::Align::Start,
|
||||
set_hexpand: true,
|
||||
set_label: "Features:"
|
||||
set_label: &format!("{}:", fl!(I18N, "features")),
|
||||
},
|
||||
|
||||
append = >k::Button {
|
||||
connect_clicked => SoftwarePageMsg::ShowVulkanFeatures,
|
||||
set_label: "Show",
|
||||
set_label: &fl!(I18N, "show-button"),
|
||||
}
|
||||
},
|
||||
|
||||
@@ -115,12 +116,12 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
append = >k::Label {
|
||||
set_halign: gtk::Align::Start,
|
||||
set_hexpand: true,
|
||||
set_label: "Extensions:"
|
||||
set_label: &format!("{}:", fl!(I18N, "extensions")),
|
||||
},
|
||||
|
||||
append = >k::Button {
|
||||
connect_clicked => SoftwarePageMsg::ShowVulkanExtensions,
|
||||
set_label: "Show",
|
||||
set_label: &fl!(I18N, "show-button"),
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -128,7 +129,7 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
None => {
|
||||
PageSection::new("Vulkan") {
|
||||
append = >k::Label {
|
||||
set_label: "Vulkan device not found",
|
||||
set_label: &fl!(I18N, "device-not-found", kind = "Vulkan"),
|
||||
set_halign: gtk::Align::Start,
|
||||
},
|
||||
}
|
||||
@@ -140,55 +141,55 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
Some(info) => {
|
||||
PageSection::new("OpenCL") {
|
||||
append = &InfoRow {
|
||||
set_name: "Platform Name:",
|
||||
set_name: fl!(I18N, "platform-name"),
|
||||
#[watch]
|
||||
set_value: info.platform_name.as_str(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Device Name:",
|
||||
set_name: fl!(I18N, "device-name"),
|
||||
#[watch]
|
||||
set_value: info.device_name.as_str(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Version:",
|
||||
set_name: fl!(I18N, "version"),
|
||||
#[watch]
|
||||
set_value: info.version.as_str(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Driver Version:",
|
||||
set_name: fl!(I18N, "driver-version"),
|
||||
#[watch]
|
||||
set_value: info.driver_version.as_str(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "OpenCL C Version:",
|
||||
set_name: fl!(I18N, "cl-c-version"),
|
||||
#[watch]
|
||||
set_value: info.c_version.as_str(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Compute Units:",
|
||||
set_name: fl!(I18N, "compute-units"),
|
||||
#[watch]
|
||||
set_value: info.compute_units.to_string(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Workgroup Size:",
|
||||
set_name: fl!(I18N, "workgroup-size"),
|
||||
#[watch]
|
||||
set_value: info.workgroup_size.to_string(),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Global Memory:",
|
||||
set_name: fl!(I18N, "global-memory"),
|
||||
#[watch]
|
||||
set_value: format_friendly_size(info.global_memory),
|
||||
set_selectable: true,
|
||||
},
|
||||
append = &InfoRow {
|
||||
set_name: "Local Memory:",
|
||||
set_name: fl!(I18N, "local-memory"),
|
||||
#[watch]
|
||||
set_value: format_friendly_size(info.local_memory),
|
||||
set_selectable: true,
|
||||
@@ -198,7 +199,7 @@ impl relm4::SimpleComponent for SoftwarePage {
|
||||
None => {
|
||||
PageSection::new("OpenCL") {
|
||||
append = >k::Label {
|
||||
set_label: "OpenCL device not found",
|
||||
set_label: &fl!(I18N, "device-not-found", kind = "OpenCL"),
|
||||
set_halign: gtk::Align::Start,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
app::{info_row::InfoRow, msg::AppMsg, page_section::PageSection},
|
||||
APP_BROKER,
|
||||
APP_BROKER, I18N,
|
||||
};
|
||||
use amdgpu_sysfs::gpu_handle::fan_control::FanInfo;
|
||||
use fan_curve_frame::{
|
||||
@@ -22,6 +22,7 @@ use gtk::{
|
||||
prelude::{AdjustmentExt, BoxExt, ButtonExt, OrientableExt, RangeExt, ScaleExt, WidgetExt},
|
||||
Adjustment,
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_daemon::AMDGPU_FAMILY_GC_11_0_0;
|
||||
use lact_schema::{
|
||||
config::{FanControlSettings, FanCurve, GpuConfig},
|
||||
@@ -107,31 +108,31 @@ impl relm4::Component for ThermalsPage {
|
||||
set_visible: model.system_info.amdgpu_overdrive_enabled == Some(false) && model.has_pmfw,
|
||||
|
||||
gtk::Label {
|
||||
set_label: "Warning: Overclocking support is disabled, fan control functionality is not available.",
|
||||
set_label: &fl!(I18N, "oc-missing-fan-control-warning"),
|
||||
},
|
||||
},
|
||||
|
||||
PageSection::new("Monitoring") {
|
||||
PageSection::new(&fl!(I18N, "monitoring-section")) {
|
||||
append = &InfoRow {
|
||||
set_name: "Temperatures:",
|
||||
set_name: fl!(I18N, "temperatures"),
|
||||
#[watch]
|
||||
set_value: model.temperatures.as_deref().unwrap_or("No sensors found"),
|
||||
},
|
||||
|
||||
append = &InfoRow {
|
||||
set_name: "Fan Speed:",
|
||||
set_name: fl!(I18N, "fan-speed"),
|
||||
#[watch]
|
||||
set_value: model.fan_speed.as_deref().unwrap_or("No fan detected"),
|
||||
},
|
||||
|
||||
append = &InfoRow {
|
||||
set_name: "Throttling:",
|
||||
set_name: fl!(I18N, "throttling"),
|
||||
#[watch]
|
||||
set_value: model.throttling.as_str(),
|
||||
},
|
||||
},
|
||||
|
||||
PageSection::new("Fan Control") {
|
||||
PageSection::new(&fl!(I18N, "fan-control-section")) {
|
||||
// Disable fan configuration when overdrive is disabled on GPUs that have PMFW (RDNA3+)
|
||||
#[watch]
|
||||
set_sensitive: model.fan_speed.is_some() && !(model.system_info.amdgpu_overdrive_enabled == Some(false) && model.has_pmfw),
|
||||
@@ -145,7 +146,7 @@ impl relm4::Component for ThermalsPage {
|
||||
#[watch]
|
||||
set_visible: model.fan_speed.is_some(),
|
||||
|
||||
add_titled[Some(AUTO_PAGE), "Automatic"] = >k::Box {
|
||||
add_titled[Some(AUTO_PAGE), &fl!(I18N, "auto-page")] = >k::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
|
||||
@@ -156,7 +157,7 @@ impl relm4::Component for ThermalsPage {
|
||||
|
||||
#[template_child]
|
||||
label {
|
||||
set_label: "Target temperature (°C)",
|
||||
set_label: &fl!(I18N, "target-temp"),
|
||||
set_size_group: &label_size_group,
|
||||
},
|
||||
|
||||
@@ -179,7 +180,7 @@ impl relm4::Component for ThermalsPage {
|
||||
|
||||
#[template_child]
|
||||
label {
|
||||
set_label: "Acoustic Limit (RPM)",
|
||||
set_label: &fl!(I18N, "acoustic-limit"),
|
||||
set_size_group: &label_size_group,
|
||||
},
|
||||
|
||||
@@ -202,7 +203,7 @@ impl relm4::Component for ThermalsPage {
|
||||
|
||||
#[template_child]
|
||||
label {
|
||||
set_label: "Acoustic Target (RPM)",
|
||||
set_label: &fl!(I18N, "acoustic-target"),
|
||||
set_size_group: &label_size_group,
|
||||
},
|
||||
|
||||
@@ -225,7 +226,7 @@ impl relm4::Component for ThermalsPage {
|
||||
|
||||
#[template_child]
|
||||
label {
|
||||
set_label: "Minimum Fan Speed (%)",
|
||||
set_label: &fl!(I18N, "min-fan-speed"),
|
||||
set_size_group: &label_size_group,
|
||||
},
|
||||
|
||||
@@ -248,7 +249,7 @@ impl relm4::Component for ThermalsPage {
|
||||
set_visible: model.pmfw_options.zero_rpm_available.get(),
|
||||
|
||||
gtk::Label {
|
||||
set_label: "Zero RPM",
|
||||
set_label: &fl!(I18N, "zero-rpm"),
|
||||
set_xalign: 0.0,
|
||||
set_size_group: &label_size_group,
|
||||
},
|
||||
@@ -267,7 +268,7 @@ impl relm4::Component for ThermalsPage {
|
||||
|
||||
#[template_child]
|
||||
label {
|
||||
set_label: "Zero RPM stop temperature (°C)",
|
||||
set_label: &fl!(I18N, "zero-rpm-stop-temp"),
|
||||
set_size_group: &label_size_group,
|
||||
},
|
||||
|
||||
@@ -284,10 +285,10 @@ impl relm4::Component for ThermalsPage {
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label: "Reset",
|
||||
set_label: &fl!(I18N, "reset-button"),
|
||||
set_halign: gtk::Align::End,
|
||||
set_margin_vertical: 5,
|
||||
set_tooltip_text: Some("Warning: this resets the fan firmware settings!"),
|
||||
set_tooltip_text: Some(&fl!(I18N, "pmfw-reset-warning")),
|
||||
add_css_class: "destructive-action",
|
||||
set_size_group: &spin_size_group,
|
||||
#[watch]
|
||||
@@ -297,8 +298,8 @@ impl relm4::Component for ThermalsPage {
|
||||
}
|
||||
},
|
||||
},
|
||||
add_titled[Some(CURVE_PAGE), "Curve"] = model.fan_curve_frame.widget(),
|
||||
add_titled[Some(STATIC_PAGE), "Static"] = >k::Box {
|
||||
add_titled[Some(CURVE_PAGE), &fl!(I18N, "curve-page")] = model.fan_curve_frame.widget(),
|
||||
add_titled[Some(STATIC_PAGE), &fl!(I18N, "static-page")] = >k::Box {
|
||||
set_valign: gtk::Align::Start,
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
@@ -308,7 +309,7 @@ impl relm4::Component for ThermalsPage {
|
||||
FanSettingRow {
|
||||
#[template_child]
|
||||
label {
|
||||
set_label: "Static Speed (%)",
|
||||
set_label: &fl!(I18N, "static-speed"),
|
||||
},
|
||||
|
||||
#[template_child]
|
||||
|
||||
+16
-1
@@ -1,11 +1,15 @@
|
||||
mod app;
|
||||
mod config;
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use anyhow::Context;
|
||||
use app::{AppModel, APP_BROKER};
|
||||
use config::UiConfig;
|
||||
use lact_schema::args::GuiArgs;
|
||||
use i18n_embed::fluent::{fluent_language_loader, FluentLanguageLoader};
|
||||
use lact_schema::{args::GuiArgs, i18n};
|
||||
use relm4::{RelmApp, SharedState};
|
||||
use rust_embed::RustEmbed;
|
||||
use tracing::metadata::LevelFilter;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
@@ -15,6 +19,13 @@ const GUI_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const APP_ID: &str = "io.github.ilya_zlobintsev.LACT";
|
||||
pub const REPO_URL: &str = "https://github.com/ilya-zlobintsev/LACT";
|
||||
|
||||
pub(crate) static I18N: LazyLock<FluentLanguageLoader> =
|
||||
LazyLock::new(|| i18n::loader(fluent_language_loader!(), &Localizations));
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "i18n"]
|
||||
pub struct Localizations;
|
||||
|
||||
pub fn run(args: GuiArgs) -> anyhow::Result<()> {
|
||||
let env_filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::INFO.into())
|
||||
@@ -22,6 +33,10 @@ pub fn run(args: GuiArgs) -> anyhow::Result<()> {
|
||||
.context("Invalid log level")?;
|
||||
tracing_subscriber::fmt().with_env_filter(env_filter).init();
|
||||
|
||||
// Pre-init localization
|
||||
LazyLock::force(&I18N);
|
||||
LazyLock::force(&lact_schema::i18n::LANGUAGE_LOADER);
|
||||
|
||||
if let Some(existing_config) = UiConfig::load() {
|
||||
*CONFIG.write() = existing_config;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,13 @@ serde_with = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
indexmap = { workspace = true }
|
||||
i18n-embed = { workspace = true }
|
||||
i18n-embed-fl = { workspace = true }
|
||||
rust-embed = { workspace = true }
|
||||
|
||||
serde-error = "=0.1.3"
|
||||
clap = { version = "4.4.18", features = ["derive"], optional = true }
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
vergen = { version = "8.0.0", features = ["git", "gitcl"] }
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
fallback_language = "en"
|
||||
|
||||
[fluent]
|
||||
assets_dir = "i18n"
|
||||
@@ -0,0 +1,24 @@
|
||||
gpu-model = GPU Model
|
||||
subvendor = Card Manufacturer
|
||||
subdevice = Card Model
|
||||
driver-used = Driver Used
|
||||
vbios-version = VBIOS Version
|
||||
vram-size = VRAM Size
|
||||
vram-type = VRAM Type
|
||||
gpu-family = GPU Family
|
||||
asic-name = ASIC Name
|
||||
compute-units = Compute Units
|
||||
execution-units = Execution Units
|
||||
subslices = Subslices
|
||||
cuda-cores = CUDA Cores
|
||||
hardware-count = {$name} Count
|
||||
isa = Instruction Set
|
||||
l1-cache-per-cu = L1 Cache (Per CU)
|
||||
l2-cache = L2 Cache
|
||||
l3-cache = L3 Cache
|
||||
rebar = Resizable Bar
|
||||
cpu-vram = CPU Accessible VRAM
|
||||
pcie-speed = PCIe Link Speed
|
||||
|
||||
enabled = Enabled
|
||||
disabled = Disabled
|
||||
@@ -0,0 +1,22 @@
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use i18n_embed::{
|
||||
fluent::{fluent_language_loader, FluentLanguageLoader},
|
||||
DesktopLanguageRequester, I18nAssets,
|
||||
};
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
pub static LANGUAGE_LOADER: LazyLock<FluentLanguageLoader> =
|
||||
LazyLock::new(|| loader(fluent_language_loader!(), &Localizations));
|
||||
|
||||
pub fn loader(loader: FluentLanguageLoader, assets: &dyn I18nAssets) -> FluentLanguageLoader {
|
||||
let requested_languages = DesktopLanguageRequester::requested_languages();
|
||||
let _selected_languages = i18n_embed::select(&loader, assets, &requested_languages)
|
||||
.expect("Failed to select localization");
|
||||
|
||||
loader
|
||||
}
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "i18n"]
|
||||
pub struct Localizations;
|
||||
+43
-25
@@ -1,6 +1,7 @@
|
||||
#[cfg(feature = "args")]
|
||||
pub mod args;
|
||||
pub mod config;
|
||||
pub mod i18n;
|
||||
mod profiles;
|
||||
pub mod request;
|
||||
mod response;
|
||||
@@ -8,6 +9,7 @@ mod response;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use i18n_embed_fl::fl;
|
||||
pub use request::Request;
|
||||
pub use response::Response;
|
||||
|
||||
@@ -29,7 +31,7 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use crate::config::ProfileHooks;
|
||||
use crate::{config::ProfileHooks, i18n::LANGUAGE_LOADER};
|
||||
|
||||
pub const GIT_COMMIT: &str = env!("VERGEN_GIT_SHA");
|
||||
|
||||
@@ -134,7 +136,7 @@ impl DeviceInfo {
|
||||
.unwrap_or(1.0)
|
||||
}
|
||||
|
||||
pub fn info_elements(&self, stats: Option<&DeviceStats>) -> Vec<(&str, Option<String>)> {
|
||||
pub fn info_elements(&self, stats: Option<&DeviceStats>) -> Vec<(String, Option<String>)> {
|
||||
let pci_info = self.pci_info.as_ref();
|
||||
|
||||
let mut gpu_model = self
|
||||
@@ -186,16 +188,22 @@ impl DeviceInfo {
|
||||
};
|
||||
|
||||
let mut elements = vec![
|
||||
("GPU Model", Some(gpu_model)),
|
||||
("Card Manufacturer", Some(card_manufacturer)),
|
||||
("Card Model", Some(card_model)),
|
||||
("Driver Used", Some(self.driver.clone())),
|
||||
("VBIOS Version", self.vbios_version.clone()),
|
||||
(fl!(LANGUAGE_LOADER, "gpu-model"), Some(gpu_model)),
|
||||
(fl!(LANGUAGE_LOADER, "subvendor"), Some(card_manufacturer)),
|
||||
(fl!(LANGUAGE_LOADER, "subdevice"), Some(card_model)),
|
||||
(
|
||||
fl!(LANGUAGE_LOADER, "driver-used"),
|
||||
Some(self.driver.clone()),
|
||||
),
|
||||
(
|
||||
fl!(LANGUAGE_LOADER, "vbios-version"),
|
||||
self.vbios_version.clone(),
|
||||
),
|
||||
];
|
||||
|
||||
if let Some(stats) = stats {
|
||||
elements.push((
|
||||
"VRAM Size",
|
||||
fl!(LANGUAGE_LOADER, "vram-size"),
|
||||
stats
|
||||
.vram
|
||||
.total
|
||||
@@ -222,35 +230,41 @@ impl DeviceInfo {
|
||||
}
|
||||
|
||||
elements.extend([
|
||||
("GPU Family", drm_info.family_name.clone()),
|
||||
("ASIC Name", drm_info.asic_name.clone()),
|
||||
(
|
||||
"Compute Units",
|
||||
fl!(LANGUAGE_LOADER, "gpu-family"),
|
||||
drm_info.family_name.clone(),
|
||||
),
|
||||
(
|
||||
fl!(LANGUAGE_LOADER, "asic-name"),
|
||||
drm_info.asic_name.clone(),
|
||||
),
|
||||
(
|
||||
fl!(LANGUAGE_LOADER, "compute-units"),
|
||||
drm_info.compute_units.map(|count| count.to_string()),
|
||||
),
|
||||
(
|
||||
"Execution Units",
|
||||
fl!(LANGUAGE_LOADER, "execution-units"),
|
||||
drm_info
|
||||
.intel
|
||||
.execution_units
|
||||
.map(|count| count.to_string()),
|
||||
),
|
||||
(
|
||||
"Subslices",
|
||||
fl!(LANGUAGE_LOADER, "subslices"),
|
||||
drm_info.intel.subslices.map(|count| count.to_string()),
|
||||
),
|
||||
(
|
||||
"Cuda Cores",
|
||||
fl!(LANGUAGE_LOADER, "cuda-cores"),
|
||||
drm_info.cuda_cores.map(|count| count.to_string()),
|
||||
),
|
||||
(
|
||||
"SM Count",
|
||||
fl!(LANGUAGE_LOADER, "hardware-count", name = "SM"),
|
||||
drm_info
|
||||
.streaming_multiprocessors
|
||||
.map(|count| count.to_string()),
|
||||
),
|
||||
(
|
||||
"ROP Count",
|
||||
fl!(LANGUAGE_LOADER, "hardware-count", name = "ROP"),
|
||||
drm_info.rop_info.as_ref().map(|rop| {
|
||||
format!(
|
||||
"{} ({} * {})",
|
||||
@@ -258,34 +272,38 @@ impl DeviceInfo {
|
||||
)
|
||||
}),
|
||||
),
|
||||
("Instruction Set", drm_info.isa.clone()),
|
||||
("VRAM Type", vram_type),
|
||||
(fl!(LANGUAGE_LOADER, "isa"), drm_info.isa.clone()),
|
||||
(fl!(LANGUAGE_LOADER, "vram-type"), vram_type),
|
||||
(
|
||||
"L1 Cache (Per CU)",
|
||||
fl!(LANGUAGE_LOADER, "l1-cache-per-cu"),
|
||||
drm_info
|
||||
.l1_cache_per_cu
|
||||
.map(|cache| format!("{} KiB", cache / 1024)),
|
||||
),
|
||||
(
|
||||
"L2 Cache",
|
||||
fl!(LANGUAGE_LOADER, "l2-cache"),
|
||||
drm_info
|
||||
.l2_cache
|
||||
.map(|cache| format!("{} KiB", cache / 1024)),
|
||||
),
|
||||
(
|
||||
"L3 Cache",
|
||||
fl!(LANGUAGE_LOADER, "l3-cache"),
|
||||
drm_info.l3_cache_mb.map(|cache| format!("{cache} MiB")),
|
||||
),
|
||||
]);
|
||||
|
||||
if let Some(memory_info) = &drm_info.memory_info {
|
||||
if let Some(rebar) = memory_info.resizeable_bar {
|
||||
let rebar = if rebar { "Enabled" } else { "Disabled" };
|
||||
elements.push(("Resizeable bar", Some(rebar.to_owned())));
|
||||
let rebar = if rebar {
|
||||
fl!(LANGUAGE_LOADER, "enabled")
|
||||
} else {
|
||||
fl!(LANGUAGE_LOADER, "disabled")
|
||||
};
|
||||
elements.push((fl!(LANGUAGE_LOADER, "rebar"), Some(rebar.to_owned())));
|
||||
}
|
||||
|
||||
elements.push((
|
||||
"CPU Accessible VRAM",
|
||||
fl!(LANGUAGE_LOADER, "cpu-vram"),
|
||||
Some((memory_info.cpu_accessible_total / 1024 / 1024).to_string()),
|
||||
));
|
||||
}
|
||||
@@ -297,7 +315,7 @@ impl DeviceInfo {
|
||||
if let (Some(current_link_speed), Some(current_link_width)) =
|
||||
(&self.link_info.current_speed, &self.link_info.current_width)
|
||||
{
|
||||
elements.push(("PCIe Link Speed", Some(format!("{current_link_speed} x{current_link_width} (Max: {max_link_speed} x{max_link_width})"))));
|
||||
elements.push((fl!(LANGUAGE_LOADER, "pcie-speed"), Some(format!("{current_link_speed} x{current_link_width} (Max: {max_link_speed} x{max_link_width})"))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user