This commit is contained in:
Luke D. Jones
2024-02-27 14:39:46 +13:00
parent 7b0f037cba
commit a88c33c201
64 changed files with 3424 additions and 7019 deletions

View File

@@ -2,11 +2,17 @@
set -e set -e
echo 'find -name \*.slint | xargs slint-tr-extractor -o rog-control-center/translations/en/rog-control-center.po'
find -name \*.slint | xargs slint-tr-extractor -o rog-control-center/translations/en/rog-control-center.po
echo '+cargo +nightly fmt --all -- --check' echo '+cargo +nightly fmt --all -- --check'
cargo +nightly fmt --all -- --check cargo +nightly fmt --all -- --check
echo '+cargo clippy --all -- -D warnings' echo '+cargo clippy --all -- -D warnings'
cargo clippy --all -- -D warnings cargo clippy --all -- -D warnings
echo '+cargo test --all' echo '+cargo test --all'
cargo test --all cargo test --all
echo '+cargo cranky' echo '+cargo cranky'
cargo cranky cargo cranky

View File

@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [Unreleased]
### Changed
- Upgrade to zbus 4.0.1
- Switch UI over to slint
## [v5.0.8] ## [v5.0.8]
### Changed ### Changed

172
Cargo.lock generated
View File

@@ -35,9 +35,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.9" version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"getrandom", "getrandom",
@@ -123,7 +123,7 @@ checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
[[package]] [[package]]
name = "asusctl" name = "asusctl"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"asusd", "asusd",
"cargo-husky", "cargo-husky",
@@ -144,14 +144,14 @@ dependencies = [
[[package]] [[package]]
name = "asusd" name = "asusd"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"cargo-husky", "cargo-husky",
"concat-idents", "concat-idents",
"config-traits", "config-traits",
"dmi_id", "dmi_id",
"env_logger", "env_logger",
"futures-lite 2.2.0", "futures-lite 1.13.0",
"inotify", "inotify",
"log", "log",
"logind-zbus", "logind-zbus",
@@ -169,7 +169,7 @@ dependencies = [
[[package]] [[package]]
name = "asusd-user" name = "asusd-user"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"cargo-husky", "cargo-husky",
"config-traits", "config-traits",
@@ -373,7 +373,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -408,7 +408,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -449,7 +449,7 @@ dependencies = [
"derive_utils", "derive_utils",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -504,7 +504,7 @@ dependencies = [
"regex", "regex",
"rustc-hash", "rustc-hash",
"shlex", "shlex",
"syn 2.0.50", "syn 2.0.51",
"which", "which",
] ]
@@ -608,7 +608,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -682,9 +682,9 @@ checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.87" version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3286b845d0fccbdd15af433f61c5970e711987036cb468f437ff6badd70f4e24" checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@@ -851,7 +851,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d" checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -865,7 +865,7 @@ dependencies = [
[[package]] [[package]]
name = "config-traits" name = "config-traits"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"cargo-husky", "cargo-husky",
"log", "log",
@@ -892,7 +892,7 @@ source = "git+https://github.com/flukejones/sixtyfps.git#f63c4e3b8510e88a8496328
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -975,7 +975,7 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
[[package]] [[package]]
name = "cpuctl" name = "cpuctl"
version = "5.0.8" version = "6.0.0-alpha1"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
@@ -1053,12 +1053,12 @@ dependencies = [
[[package]] [[package]]
name = "ctor" name = "ctor"
version = "0.2.6" version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e" checksum = "ad291aa74992b9b7a7e88c38acbbf6ad7e107f1d90ee8775b7bc1fc3394f485c"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -1114,7 +1114,7 @@ checksum = "61bb5a1014ce6dfc2a378578509abe775a5aa06bff584a547555d9efdb81b926"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -1185,7 +1185,7 @@ dependencies = [
[[package]] [[package]]
name = "dmi_id" name = "dmi_id"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"log", "log",
"udev 0.7.0", "udev 0.7.0",
@@ -1302,7 +1302,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -1577,7 +1577,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -1663,7 +1663,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -1825,6 +1825,26 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "gettext-rs"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e49ea8a8fad198aaa1f9655a2524b64b70eb06b2f3ff37da407566c93054f364"
dependencies = [
"gettext-sys",
"locale_config",
]
[[package]]
name = "gettext-sys"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c63ce2e00f56a206778276704bbe38564c8695249fdc8f354b4ef71c57c3839d"
dependencies = [
"cc",
"temp-dir",
]
[[package]] [[package]]
name = "gif" name = "gif"
version = "0.12.0" version = "0.12.0"
@@ -1937,7 +1957,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -2093,7 +2113,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -2118,9 +2138,9 @@ dependencies = [
[[package]] [[package]]
name = "half" name = "half"
version = "2.3.1" version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crunchy", "crunchy",
@@ -2300,6 +2320,7 @@ dependencies = [
"derive_more", "derive_more",
"euclid", "euclid",
"fontdue", "fontdue",
"gettext-rs",
"i-slint-common", "i-slint-common",
"i-slint-core-macros", "i-slint-core-macros",
"image", "image",
@@ -2336,7 +2357,7 @@ version = "1.5.0"
source = "git+https://github.com/flukejones/sixtyfps.git#f63c4e3b8510e88a8496328a47e8a8dccdb1bcf3" source = "git+https://github.com/flukejones/sixtyfps.git#f63c4e3b8510e88a8496328a47e8a8dccdb1bcf3"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -2830,6 +2851,19 @@ version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "locale_config"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934"
dependencies = [
"lazy_static",
"objc",
"objc-foundation",
"regex",
"winapi",
]
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.11" version = "0.4.11"
@@ -3145,7 +3179,7 @@ dependencies = [
"proc-macro-crate 3.1.0", "proc-macro-crate 3.1.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -3322,7 +3356,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -3447,7 +3481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -3591,9 +3625,9 @@ checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544"
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.8.1" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd"
dependencies = [ dependencies = [
"either", "either",
"rayon-core", "rayon-core",
@@ -3692,10 +3726,12 @@ dependencies = [
[[package]] [[package]]
name = "rog-control-center" name = "rog-control-center"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"asusd", "asusd",
"cargo-husky", "cargo-husky",
"concat-idents",
"config-traits",
"dirs", "dirs",
"env_logger", "env_logger",
"gtk", "gtk",
@@ -3713,6 +3749,7 @@ dependencies = [
"rog_dbus", "rog_dbus",
"rog_platform", "rog_platform",
"rog_profiles", "rog_profiles",
"ron",
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
@@ -3721,7 +3758,6 @@ dependencies = [
"supergfxctl", "supergfxctl",
"tempfile", "tempfile",
"tokio", "tokio",
"toml 0.5.11",
"versions", "versions",
"winit", "winit",
"zbus", "zbus",
@@ -3729,7 +3765,7 @@ dependencies = [
[[package]] [[package]]
name = "rog_anime" name = "rog_anime"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"cargo-husky", "cargo-husky",
"dmi_id", "dmi_id",
@@ -3746,7 +3782,7 @@ dependencies = [
[[package]] [[package]]
name = "rog_aura" name = "rog_aura"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"cargo-husky", "cargo-husky",
"dmi_id", "dmi_id",
@@ -3760,7 +3796,7 @@ dependencies = [
[[package]] [[package]]
name = "rog_dbus" name = "rog_dbus"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"asusd", "asusd",
"cargo-husky", "cargo-husky",
@@ -3773,7 +3809,7 @@ dependencies = [
[[package]] [[package]]
name = "rog_platform" name = "rog_platform"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"cargo-husky", "cargo-husky",
"concat-idents", "concat-idents",
@@ -3790,7 +3826,7 @@ dependencies = [
[[package]] [[package]]
name = "rog_profiles" name = "rog_profiles"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"cargo-husky", "cargo-husky",
"log", "log",
@@ -3804,7 +3840,7 @@ dependencies = [
[[package]] [[package]]
name = "rog_simulators" name = "rog_simulators"
version = "5.0.8" version = "6.0.0-alpha1"
dependencies = [ dependencies = [
"glam", "glam",
"log", "log",
@@ -4048,7 +4084,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -4070,7 +4106,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -4390,13 +4426,13 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustversion", "rustversion",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
name = "supergfxctl" name = "supergfxctl"
version = "5.2.0" version = "5.2.0"
source = "git+https://gitlab.com/asus-linux/supergfxctl.git#21b23f3074b0f501ed1ac32af1c6ba324cee5202" source = "git+https://gitlab.com/asus-linux/supergfxctl.git#82e2cc93222998a9fd26427f682e0828f00f5a57"
dependencies = [ dependencies = [
"log", "log",
"logind-zbus", "logind-zbus",
@@ -4431,9 +4467,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.50" version = "2.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -4491,10 +4527,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "tempfile" name = "temp-dir"
version = "3.10.0" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" checksum = "dd16aa9ffe15fe021c6ee3766772132c6e98dfa395a167e16864f61a9cfb71d6"
[[package]]
name = "tempfile"
version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand 2.0.1", "fastrand 2.0.1",
@@ -4534,7 +4576,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -4653,7 +4695,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -4751,7 +4793,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -5010,7 +5052,7 @@ source = "git+https://github.com/flukejones/sixtyfps.git#f63c4e3b8510e88a8496328
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -5056,7 +5098,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@@ -5090,7 +5132,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@@ -5536,9 +5578,9 @@ checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.29.10" version = "0.29.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf" checksum = "272be407f804517512fdf408f0fe6c067bf24659a913c61af97af176bfd5aa92"
dependencies = [ dependencies = [
"ahash", "ahash",
"android-activity", "android-activity",
@@ -5828,7 +5870,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.50", "syn 2.0.51",
] ]
[[package]] [[package]]
@@ -5842,9 +5884,9 @@ dependencies = [
[[package]] [[package]]
name = "zvariant" name = "zvariant"
version = "4.0.1" version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a660524eaa9f4a65c673006b034d2167a9a3ef821e9bd7311b2f1c77b904e312" checksum = "2c1b3ca6db667bfada0f1ebfc94b2b1759ba25472ee5373d4551bb892616389a"
dependencies = [ dependencies = [
"endi", "endi",
"enumflags2", "enumflags2",
@@ -5855,9 +5897,9 @@ dependencies = [
[[package]] [[package]]
name = "zvariant_derive" name = "zvariant_derive"
version = "4.0.1" version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55b1565fbb82205a83de0bd1293fb2b5c9e34d4e74250fd4aed54903545b1fa2" checksum = "b7a4b236063316163b69039f77ce3117accb41a09567fd24c168e43491e521bc"
dependencies = [ dependencies = [
"proc-macro-crate 3.1.0", "proc-macro-crate 3.1.0",
"proc-macro2", "proc-macro2",

View File

@@ -24,7 +24,7 @@ default-members = [
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
version = "5.0.8" version = "6.0.0-alpha1"
rust-version = "1.76" rust-version = "1.76"
[workspace.dependencies] [workspace.dependencies]

View File

@@ -20,7 +20,10 @@ pub const AURA_ZBUS_NAME: &str = "Aura";
pub const AURA_ZBUS_PATH: &str = "/org/asuslinux/Aura"; pub const AURA_ZBUS_PATH: &str = "/org/asuslinux/Aura";
#[derive(Clone)] #[derive(Clone)]
pub struct CtrlAuraZbus(pub Arc<Mutex<CtrlKbdLed>>); pub struct CtrlAuraZbus(
pub Arc<Mutex<CtrlKbdLed>>,
pub Option<SignalContext<'static>>,
);
impl CtrlAuraZbus { impl CtrlAuraZbus {
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> { fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
@@ -38,7 +41,7 @@ impl crate::ZbusRun for CtrlAuraZbus {
} }
} }
/// The main interface for changing, reading, or notfying signals /// The main interface for changing, reading, or notfying
/// ///
/// LED commands are split between Brightness, Modes, Per-Key /// LED commands are split between Brightness, Modes, Per-Key
#[interface(name = "org.asuslinux.Daemon")] #[interface(name = "org.asuslinux.Daemon")]
@@ -116,6 +119,10 @@ impl CtrlAuraZbus {
ctrl.sysfs_node ctrl.sysfs_node
.set_brightness(ctrl.config.brightness.into())?; .set_brightness(ctrl.config.brightness.into())?;
ctrl.config.write(); ctrl.config.write();
if let Some(ct) = self.1.as_ref() {
self.led_mode_data_invalidate(ct).await.ok();
}
Ok(()) Ok(())
} }
@@ -154,6 +161,10 @@ impl CtrlAuraZbus {
.set_brightness(ctrl.config.brightness.into())?; .set_brightness(ctrl.config.brightness.into())?;
ctrl.config.set_builtin(effect); ctrl.config.set_builtin(effect);
ctrl.config.write(); ctrl.config.write();
if let Some(ct) = self.1.as_ref() {
self.led_mode_invalidate(ct).await.ok();
}
Ok(()) Ok(())
} }

View File

@@ -385,6 +385,7 @@ impl CtrlPlatform {
} }
self.power.set_charge_control_end_threshold(limit)?; self.power.set_charge_control_end_threshold(limit)?;
self.config.lock().await.charge_control_end_threshold = limit; self.config.lock().await.charge_control_end_threshold = limit;
self.config.lock().await.write();
Ok(()) Ok(())
} }
@@ -402,12 +403,14 @@ impl CtrlPlatform {
self.set_gfx_mode(mode.into()).map_err(|err| { self.set_gfx_mode(mode.into()).map_err(|err| {
warn!("RogPlatform: set_gpu_mux_mode {}", err); warn!("RogPlatform: set_gpu_mux_mode {}", err);
FdoErr::Failed(format!("RogPlatform: set_gpu_mux_mode: {err}")) FdoErr::Failed(format!("RogPlatform: set_gpu_mux_mode: {err}"))
}) })?;
self.config.lock().await.write();
} else { } else {
Err(FdoErr::NotSupported( return Err(FdoErr::NotSupported(
"RogPlatform: set_gpu_mux_mode not supported".to_owned(), "RogPlatform: set_gpu_mux_mode not supported".to_owned(),
)) ));
} }
Ok(())
} }
/// Toggle to next platform_profile. Names provided by `Profiles`. /// Toggle to next platform_profile. Names provided by `Profiles`.
@@ -452,6 +455,7 @@ impl CtrlPlatform {
let change_epp = self.config.lock().await.throttle_policy_linked_epp; let change_epp = self.config.lock().await.throttle_policy_linked_epp;
let epp = self.get_config_epp_for_throttle(policy).await; let epp = self.get_config_epp_for_throttle(policy).await;
self.check_and_set_epp(epp, change_epp); self.check_and_set_epp(epp, change_epp);
self.config.lock().await.write();
self.platform self.platform
.set_throttle_thermal_policy(policy.into()) .set_throttle_thermal_policy(policy.into())
.map_err(|err| { .map_err(|err| {
@@ -473,6 +477,7 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_throttle_policy_linked_epp(&self, linked: bool) -> Result<(), zbus::Error> { async fn set_throttle_policy_linked_epp(&self, linked: bool) -> Result<(), zbus::Error> {
self.config.lock().await.throttle_policy_linked_epp = linked; self.config.lock().await.throttle_policy_linked_epp = linked;
self.config.lock().await.write();
Ok(()) Ok(())
} }
@@ -488,6 +493,7 @@ impl CtrlPlatform {
) -> Result<(), FdoErr> { ) -> Result<(), FdoErr> {
self.config.lock().await.throttle_policy_on_battery = policy; self.config.lock().await.throttle_policy_on_battery = policy;
self.set_throttle_thermal_policy(policy).await?; self.set_throttle_thermal_policy(policy).await?;
self.config.lock().await.write();
Ok(()) Ok(())
} }
@@ -500,6 +506,7 @@ impl CtrlPlatform {
async fn set_throttle_policy_on_ac(&mut self, policy: ThrottlePolicy) -> Result<(), FdoErr> { async fn set_throttle_policy_on_ac(&mut self, policy: ThrottlePolicy) -> Result<(), FdoErr> {
self.config.lock().await.throttle_policy_on_ac = policy; self.config.lock().await.throttle_policy_on_ac = policy;
self.set_throttle_thermal_policy(policy).await?; self.set_throttle_thermal_policy(policy).await?;
self.config.lock().await.write();
Ok(()) Ok(())
} }
@@ -515,6 +522,7 @@ impl CtrlPlatform {
let change_pp = self.config.lock().await.throttle_policy_linked_epp; let change_pp = self.config.lock().await.throttle_policy_linked_epp;
self.config.lock().await.throttle_quiet_epp = epp; self.config.lock().await.throttle_quiet_epp = epp;
self.check_and_set_epp(epp, change_pp); self.check_and_set_epp(epp, change_pp);
self.config.lock().await.write();
Ok(()) Ok(())
} }
@@ -530,6 +538,7 @@ impl CtrlPlatform {
let change_pp = self.config.lock().await.throttle_policy_linked_epp; let change_pp = self.config.lock().await.throttle_policy_linked_epp;
self.config.lock().await.throttle_balanced_epp = epp; self.config.lock().await.throttle_balanced_epp = epp;
self.check_and_set_epp(epp, change_pp); self.check_and_set_epp(epp, change_pp);
self.config.lock().await.write();
Ok(()) Ok(())
} }
@@ -545,6 +554,7 @@ impl CtrlPlatform {
let change_pp = self.config.lock().await.throttle_policy_linked_epp; let change_pp = self.config.lock().await.throttle_policy_linked_epp;
self.config.lock().await.throttle_performance_epp = epp; self.config.lock().await.throttle_performance_epp = epp;
self.check_and_set_epp(epp, change_pp); self.check_and_set_epp(epp, change_pp);
self.config.lock().await.write();
Ok(()) Ok(())
} }
@@ -561,12 +571,14 @@ impl CtrlPlatform {
self.platform.set_post_animation_sound(on).map_err(|err| { self.platform.set_post_animation_sound(on).map_err(|err| {
warn!("RogPlatform: set_post_animation_sound {}", err); warn!("RogPlatform: set_post_animation_sound {}", err);
FdoErr::Failed(format!("RogPlatform: set_post_animation_sound: {err}")) FdoErr::Failed(format!("RogPlatform: set_post_animation_sound: {err}"))
}) })?;
self.config.lock().await.write();
} else { } else {
Err(FdoErr::NotSupported( return Err(FdoErr::NotSupported(
"RogPlatform: set_post_animation_sound not supported".to_owned(), "RogPlatform: set_post_animation_sound not supported".to_owned(),
)) ));
} }
Ok(())
} }
/// Get the `panel_od` value from platform. Updates the stored value in /// Get the `panel_od` value from platform. Updates the stored value in
@@ -578,7 +590,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> { async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> {
platform_set_bool!(self, panel_od, "panel_od", overdrive) platform_set_bool!(self, panel_od, "panel_od", overdrive)?;
self.config.lock().await.write();
Ok(())
} }
/// Get the `panel_od` value from platform. Updates the stored value in /// Get the `panel_od` value from platform. Updates the stored value in
@@ -590,7 +604,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> { async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> {
platform_set_bool!(self, mini_led_mode, "mini_led_mode", on) platform_set_bool!(self, mini_led_mode, "mini_led_mode", on)?;
self.config.lock().await.write();
Ok(())
} }
#[zbus(property)] #[zbus(property)]
@@ -614,7 +630,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> { async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_pl1_spl, "ppt_pl1_spl", value, 5, 250) platform_set_with_min_max!(self, ppt_pl1_spl, "ppt_pl1_spl", value, 5, 250)?;
self.config.lock().await.write();
Ok(())
} }
/// Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT, /// Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT,
@@ -627,7 +645,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_ppt_pl2_sppt(&mut self, value: u8) -> Result<(), FdoErr> { async fn set_ppt_pl2_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_pl2_sppt, "ppt_pl2_sppt", value, 5, 250) platform_set_with_min_max!(self, ppt_pl2_sppt, "ppt_pl2_sppt", value, 5, 250)?;
self.config.lock().await.write();
Ok(())
} }
/// Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only: /// Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only:
@@ -639,7 +659,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_ppt_fppt(&mut self, value: u8) -> Result<(), FdoErr> { async fn set_ppt_fppt(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_fppt, "ppt_fppt", value, 5, 250) platform_set_with_min_max!(self, ppt_fppt, "ppt_fppt", value, 5, 250)?;
self.config.lock().await.write();
Ok(())
} }
/// Set the APU SPPT limit. Shown on full AMD systems only: /// Set the APU SPPT limit. Shown on full AMD systems only:
@@ -651,7 +673,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_ppt_apu_sppt(&mut self, value: u8) -> Result<(), FdoErr> { async fn set_ppt_apu_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_apu_sppt, "ppt_apu_sppt", value, 5, 130) platform_set_with_min_max!(self, ppt_apu_sppt, "ppt_apu_sppt", value, 5, 130)?;
self.config.lock().await.write();
Ok(())
} }
/// Set the platform SPPT limit. Shown on full AMD systems only: /// Set the platform SPPT limit. Shown on full AMD systems only:
@@ -663,7 +687,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_ppt_platform_sppt(&mut self, value: u8) -> Result<(), FdoErr> { async fn set_ppt_platform_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, ppt_platform_sppt, "ppt_platform_sppt", value, 5, 130) platform_set_with_min_max!(self, ppt_platform_sppt, "ppt_platform_sppt", value, 5, 130)?;
self.config.lock().await.write();
Ok(())
} }
/// Set the dynamic boost limit of the Nvidia dGPU: /// Set the dynamic boost limit of the Nvidia dGPU:
@@ -675,7 +701,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_nv_dynamic_boost(&mut self, value: u8) -> Result<(), FdoErr> { async fn set_nv_dynamic_boost(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, nv_dynamic_boost, "nv_dynamic_boost", value, 5, 25) platform_set_with_min_max!(self, nv_dynamic_boost, "nv_dynamic_boost", value, 5, 25)?;
self.config.lock().await.write();
Ok(())
} }
/// Set the target temperature limit of the Nvidia dGPU: /// Set the target temperature limit of the Nvidia dGPU:
@@ -687,7 +715,9 @@ impl CtrlPlatform {
#[zbus(property)] #[zbus(property)]
async fn set_nv_temp_target(&mut self, value: u8) -> Result<(), FdoErr> { async fn set_nv_temp_target(&mut self, value: u8) -> Result<(), FdoErr> {
platform_set_with_min_max!(self, nv_temp_target, "nv_temp_target", value, 5, 87) platform_set_with_min_max!(self, nv_temp_target, "nv_temp_target", value, 5, 87)?;
self.config.lock().await.write();
Ok(())
} }
} }

View File

@@ -107,7 +107,9 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
// detection first // detection first
match CtrlKbdLed::new(laptop) { match CtrlKbdLed::new(laptop) {
Ok(ctrl) => { Ok(ctrl) => {
let zbus = CtrlAuraZbus(Arc::new(Mutex::new(ctrl))); let mut zbus = CtrlAuraZbus(Arc::new(Mutex::new(ctrl)), None);
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
zbus.1 = Some(sig_ctx);
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?; let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
start_tasks(zbus, &mut connection, sig_ctx).await?; start_tasks(zbus, &mut connection, sig_ctx).await?;
} }

View File

@@ -1,4 +1,6 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node> <node>
<interface name="org.asuslinux.Daemon"> <interface name="org.asuslinux.Daemon">
<!-- <!--
@@ -54,4 +56,40 @@
--> -->
<property name="OffWhenUnplugged" type="b" access="readwrite"/> <property name="OffWhenUnplugged" type="b" access="readwrite"/>
</interface> </interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg type="v" direction="out"/>
</method>
<method name="Set">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method>
<method name="GetAll">
<arg name="interface_name" type="s" direction="in"/>
<arg type="a{sv}" direction="out"/>
</method>
<!--
Emits the `org.freedesktop.DBus.Properties.PropertiesChanged` signal.
-->
<signal name="PropertiesChanged">
<arg name="interface_name" type="s"/>
<arg name="changed_properties" type="a{sv}"/>
<arg name="invalidated_properties" type="as"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" direction="out"/>
</method>
</interface>
</node> </node>

View File

@@ -1,6 +1,11 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node> <node>
<interface name="org.asuslinux.Daemon"> <interface name="org.asuslinux.Daemon">
<method name="GetLedModeData">
<arg type="(uu(yyy)(yyy)ss)" direction="out"/>
</method>
<!-- <!--
Get the data set for every mode available Get the data set for every mode available
--> -->
@@ -52,7 +57,7 @@
For Modern ROG devices the "enabled" flag is ignored. For Modern ROG devices the "enabled" flag is ignored.
--> -->
<property name="LedPower" type="(ayay((ubbbb)(ubbbb)(ubbbb)(ubbbb)(ubbbb)))" access="readwrite"/> <property name="LedPower" type="(auau((ubbbb)(ubbbb)(ubbbb)(ubbbb)(ubbbb)))" access="readwrite"/>
<!-- <!--
The total available modes The total available modes
--> -->
@@ -64,4 +69,40 @@
<property name="SupportedBrightness" type="au" access="read"/> <property name="SupportedBrightness" type="au" access="read"/>
<property name="SupportedPowerZones" type="au" access="read"/> <property name="SupportedPowerZones" type="au" access="read"/>
</interface> </interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg type="v" direction="out"/>
</method>
<method name="Set">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method>
<method name="GetAll">
<arg name="interface_name" type="s" direction="in"/>
<arg type="a{sv}" direction="out"/>
</method>
<!--
Emits the `org.freedesktop.DBus.Properties.PropertiesChanged` signal.
-->
<signal name="PropertiesChanged">
<arg name="interface_name" type="s"/>
<arg name="changed_properties" type="a{sv}"/>
<arg name="invalidated_properties" type="as"/>
</signal>
</interface>
</node> </node>

View File

@@ -1,12 +1,45 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node> <node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg type="v" direction="out"/>
</method>
<method name="Set">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method>
<method name="GetAll">
<arg name="interface_name" type="s" direction="in"/>
<arg type="a{sv}" direction="out"/>
</method>
<!--
Emits the `org.freedesktop.DBus.Properties.PropertiesChanged` signal.
-->
<signal name="PropertiesChanged">
<arg name="interface_name" type="s"/>
<arg name="changed_properties" type="a{sv}"/>
<arg name="invalidated_properties" type="as"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.asuslinux.Daemon"> <interface name="org.asuslinux.Daemon">
<!-- <!--
Set all fan curves for a profile to enabled status. Will also activate a Set all fan curves for a profile to enabled status. Will also activate a
fan curve if in the same profile mode fan curve if in the same profile mode
--> -->
<method name="SetFanCurvesEnabled"> <method name="SetFanCurvesEnabled">
<arg name="profile" type="s" direction="in"/> <arg name="profile" type="u" direction="in"/>
<arg name="enabled" type="b" direction="in"/> <arg name="enabled" type="b" direction="in"/>
</method> </method>
<!-- <!--
@@ -14,7 +47,7 @@
activate a fan curve if in the same profile mode activate a fan curve if in the same profile mode
--> -->
<method name="SetProfileFanCurveEnabled"> <method name="SetProfileFanCurveEnabled">
<arg name="profile" type="s" direction="in"/> <arg name="profile" type="u" direction="in"/>
<arg name="fan" type="s" direction="in"/> <arg name="fan" type="s" direction="in"/>
<arg name="enabled" type="b" direction="in"/> <arg name="enabled" type="b" direction="in"/>
</method> </method>
@@ -22,7 +55,7 @@
Get the fan-curve data for the currently active ThrottlePolicy Get the fan-curve data for the currently active ThrottlePolicy
--> -->
<method name="FanCurveData"> <method name="FanCurveData">
<arg name="profile" type="s" direction="in"/> <arg name="profile" type="u" direction="in"/>
<arg type="a(s(yyyyyyyy)(yyyyyyyy)b)" direction="out"/> <arg type="a(s(yyyyyyyy)(yyyyyyyy)b)" direction="out"/>
</method> </method>
<!-- <!--
@@ -30,7 +63,7 @@
Will also activate the fan curve if the user is in the same mode. Will also activate the fan curve if the user is in the same mode.
--> -->
<method name="SetFanCurve"> <method name="SetFanCurve">
<arg name="profile" type="s" direction="in"/> <arg name="profile" type="u" direction="in"/>
<arg name="curve" type="(s(yyyyyyyy)(yyyyyyyy)b)" direction="in"/> <arg name="curve" type="(s(yyyyyyyy)(yyyyyyyy)b)" direction="in"/>
</method> </method>
<!-- <!--
@@ -50,7 +83,12 @@
read only for the currently active profile. read only for the currently active profile.
--> -->
<method name="ResetProfileCurves"> <method name="ResetProfileCurves">
<arg name="profile" type="s" direction="in"/> <arg name="profile" type="u" direction="in"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" direction="out"/>
</method> </method>
</interface> </interface>
</node> </node>

View File

@@ -1,4 +1,6 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node> <node>
<interface name="org.asuslinux.Daemon"> <interface name="org.asuslinux.Daemon">
<!-- <!--
@@ -25,22 +27,107 @@
internal config also. internal config also.
--> -->
<property name="MiniLedMode" type="b" access="readwrite"/> <property name="MiniLedMode" type="b" access="readwrite"/>
<!--
Set the dynamic boost limit of the Nvidia dGPU:
* min=5, max=25
-->
<property name="NvDynamicBoost" type="y" access="readwrite"/> <property name="NvDynamicBoost" type="y" access="readwrite"/>
<!--
Set the target temperature limit of the Nvidia dGPU:
* min=75, max=87
-->
<property name="NvTempTarget" type="y" access="readwrite"/> <property name="NvTempTarget" type="y" access="readwrite"/>
<!-- <!--
Get the `panel_od` value from platform. Updates the stored value in Get the `panel_od` value from platform. Updates the stored value in
internal config also. internal config also.
--> -->
<property name="PanelOd" type="b" access="readwrite"/> <property name="PanelOd" type="b" access="readwrite"/>
<!--
***********************************************************************
-->
<property name="PostAnimationSound" type="b" access="readwrite"/> <property name="PostAnimationSound" type="b" access="readwrite"/>
<!--
Set the APU SPPT limit. Shown on full AMD systems only:
* min=5, max=130
-->
<property name="PptApuSppt" type="y" access="readwrite"/> <property name="PptApuSppt" type="y" access="readwrite"/>
<!--
Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only:
* min=5, max=250
-->
<property name="PptFppt" type="y" access="readwrite"/> <property name="PptFppt" type="y" access="readwrite"/>
<!-- <!--
************************************************************************ ***********************************************************************
Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD.
Shown on Intel+Nvidia or AMD+Nvidia based systems:
* min=5, max=250
--> -->
<property name="PptPl1Spl" type="y" access="readwrite"/> <property name="PptPl1Spl" type="y" access="readwrite"/>
<!--
Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT,
on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems:
* min=5, max=250
-->
<property name="PptPl2Sppt" type="y" access="readwrite"/> <property name="PptPl2Sppt" type="y" access="readwrite"/>
<!--
Set the platform SPPT limit. Shown on full AMD systems only:
* min=5, max=130
-->
<property name="PptPlatformSppt" type="y" access="readwrite"/> <property name="PptPlatformSppt" type="y" access="readwrite"/>
<property name="ThrottleThermalPolicy" type="s" access="readwrite"/> <!--
The energy_performance_preference for the balanced throttle/platform
profile
-->
<property name="ThrottleBalancedEpp" type="u" access="readwrite"/>
<!--
The energy_performance_preference for the performance throttle/platform
profile
-->
<property name="ThrottlePerformanceEpp" type="u" access="readwrite"/>
<property name="ThrottlePolicyLinkedEpp" type="b" access="readwrite"/>
<property name="ThrottlePolicyOnAc" type="u" access="readwrite"/>
<property name="ThrottlePolicyOnBattery" type="u" access="readwrite"/>
<!--
The energy_performance_preference for the quiet throttle/platform
profile
-->
<property name="ThrottleQuietEpp" type="u" access="readwrite"/>
<property name="ThrottleThermalPolicy" type="u" access="readwrite"/>
</interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg type="v" direction="out"/>
</method>
<method name="Set">
<arg name="interface_name" type="s" direction="in"/>
<arg name="property_name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method>
<method name="GetAll">
<arg name="interface_name" type="s" direction="in"/>
<arg type="a{sv}" direction="out"/>
</method>
<!--
Emits the `org.freedesktop.DBus.Properties.PropertiesChanged` signal.
-->
<signal name="PropertiesChanged">
<arg name="interface_name" type="s"/>
<arg name="changed_properties" type="a{sv}"/>
<arg name="invalidated_properties" type="as"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping">
</method>
<method name="GetMachineId">
<arg type="s" direction="out"/>
</method>
</interface> </interface>
</node> </node>

View File

@@ -1,25 +0,0 @@
/* eslint-env node */
module.exports = {
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
root: true,
rules: {
// enable additional rules
indent: ["error", 4],
"linebreak-style": ["error", "unix"],
quotes: ["error", "double"],
semi: ["error", "always"],
// override configuration set by extending "eslint:recommended"
"no-empty": "warn",
"no-cond-assign": ["error", "always"],
// disable rules from base configurations
"for-direction": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/ban-ts-comment": "off",
},
};

View File

@@ -1,13 +0,0 @@
# Generated files
/@types/gir-generated/*
# Build outputes
/dist/
/build/
# Node configuration and modules
/package.json
/node_modules/
# Files I prefer not to be formatted
*.md

View File

@@ -1,9 +0,0 @@
{
"printWidth": 100,
"useTabs": false,
"semi": true,
"singleQuote": false,
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "always"
}

View File

@@ -1,373 +0,0 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -1,21 +0,0 @@
# asusctl
Requires `asusd` to be installed and running.
## build and install
```
npm install
npm run build && gnome-extensions install asusctl-gnome@asus-linux.org.zip --force
npm run build && gnome-extensions enable asusctl-gnome@asus-linux.org.zip
```
You will need to restart Gnome after installing or updating
## development
```
npm run build
gnome-extensions install asusctl-gnome@asus-linux.org.zip --force
MUTTER_DEBUG_DUMMY_MODE_SPECS=1366x768 dbus-run-session -- gnome-shell --nested --wayland
```

View File

@@ -1,67 +0,0 @@
import { build } from "esbuild";
import { exec } from "child_process";
import { copyFileSync, cpSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";
import AdmZip from "adm-zip";
import metadata from "./src/metadata.json" assert { type: "json" };
build({
entryPoints: ["src/extension.ts"],
outdir: "dist",
bundle: true,
// Do not remove the functions `enable()`, `disable()` and `init()`
treeShaking: false,
// firefox60 // Since GJS 1.53.90
// firefox68 // Since GJS 1.63.90
// firefox78 // Since GJS 1.65.90
// firefox91 // Since GJS 1.71.1
// firefox102 // Since GJS 1.73.2
target: "firefox102",
//platform: "neutral",
platform: "node",
// mainFields: ['main'],
// conditions: ['require', 'default'],
format: "esm",
external: ["gi://*", "resource://*", "system", "gettext", "cairo"],
}).then(() => {
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const metaSrc = resolve(__dirname, "src/metadata.json");
const metaDist = resolve(__dirname, "dist/metadata.json");
const schemaSrc = resolve(__dirname, "schemas");
const schemaDist = resolve(__dirname, "dist/schemas");
const dbusXmlSrc = resolve(__dirname, "../../bindings/dbus-xml");
const dbusXmlDist = resolve(__dirname, "dist/resources/dbus");
const zipFilename = `${metadata.uuid}.zip`;
const zipDist = resolve(__dirname, zipFilename);
exec("glib-compile-schemas schemas/", (error, stdout, stderr) => {
console.log("stdout: " + stdout);
console.log("stderr: " + stderr);
});
copyFileSync(metaSrc, metaDist);
cpSync(schemaSrc, schemaDist, { recursive: true }, (err) => {
if (err) {
console.error(err);
}
});
cpSync(dbusXmlSrc, dbusXmlDist, { recursive: true }, (err) => {
if (err) {
console.error(err);
}
});
const zip = new AdmZip();
zip.addLocalFolder(resolve(__dirname, "dist"));
zip.writeZip(zipDist);
console.log(`Build complete. Zip file: ${zipFilename}\n`);
console.log(`Install with: gnome-extensions install ${zipFilename}`);
console.log(`Update with: gnome-extensions install ${zipFilename} --force`);
console.log(`Enable with: gnome-extensions enable ${metadata.uuid} --user`);
});

View File

@@ -1,51 +0,0 @@
#!/bin/bash
## Script to initialise dev-environment (types)
gv="44"
wd=${PWD}
# cleanup
rm -rf @types
# generate GJS from gir (this does not include the extensions)
echo "Generating GJS types from gir.."
npx ts-for-gir generate Shell-12 St-12 Gtk-4.0 \
-g /usr/share/gir-1.0 \
-g /usr/share/gnome-shell \
-g /usr/share/gnome-shell/gir-1.0 \
-g /usr/lib64/mutter-12 \
-t esm -o @types/Gjs
# get latest js (44) in this case and create the types for it
echo "Generating GJS Extension (Gex) types from extension source.."
mkdir -p ./_tmp/
cd ./_tmp
wget -q -O gnome-shell-js-${gv}.tar.gz https://gitlab.gnome.org/GNOME/gnome-shell/-/archive/gnome-${gv}/gnome-shell-gnome-${gv}.tar.gz?path=js
tar xf gnome-shell-js-${gv}.tar.gz
cd gnome-shell-gnome-${gv}-js
cat >tsconfig.json <<EOL
{
"include": ["js/ui/*"],
"exclude": [
"js/ui/shellDBus.js",
"node_modules",
"**/node_modules/*"
],
"compilerOptions": {
"allowJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "gex-types",
"declarationMap": true,
"lib": ["es2019"]
}
}
EOL
npx tsc
cd ${wd}
mv ./_tmp/gnome-shell-gnome-${gv}-js/gex-types @types/Gex
# rm -rf ./_tmp/
echo "done."
exit 0

File diff suppressed because it is too large Load Diff

View File

@@ -1,55 +0,0 @@
{
"name": "asusctl-gnome",
"version": "5.0.0-RC1",
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
"type": "module",
"main": "dist/extension.js",
"scripts": {
"clear": "rm -rf dist",
"compile": "tsc --build tsconfig.json",
"build:app": "node esbuild.js",
"build": "yarn run clear && yarn run build:app",
"validate": "tsc --noEmit",
"generate:gir-types": "ts-for-gir generate",
"check:types": "tsc --build tsconfig.types.json",
"lint": "eslint .",
"format": "prettier . -w"
},
"devDependencies": {
"@girs/gnome-shell": "^45.0.0-beta2",
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"adm-zip": "^0.5.10",
"esbuild": "^0.19.5",
"eslint": "^8.51.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-promise": "^6.1.1",
"prettier": "^3.0.3",
"typescript": "^5.2.2"
},
"dependencies": {
"@girs/gjs": "^3.2.5",
"@girs/gobject-2.0": "^2.78.0-3.2.5",
"@girs/st-13": "^13.0.0-3.2.5"
},
"repository": {
"type": "git",
"url": "git+ssh://git@gitlab.com/asus-linux/asusctl.git"
},
"keywords": [
"gnome-shell",
"extension",
"asusctl",
"asus",
"rog",
"gnome",
"gjs",
"typescript"
],
"author": "Armas Spann, Marco Laux, Luke Jones",
"license": "MPL-2",
"bugs": {
"url": "https://gitlab.com/asus-linux/asusctl/issues"
},
"homepage": "https://gitlab.com/asus-linux/asusctl/desktop-extensions/gnome#readme"
}

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="AsusctlGnomeExtension">
<schema id="org.gnome.shell.extensions.asusctl-gnome" path="/org/gnome/shell/extensions/asusctl-gnome/" >
<key type="b" name="mini-led-enabled">
<default>false</default>
</key>
<key type="b" name="panel-od-enabled">
<default>false</default>
</key>
<key type="b" name="anime-power">
<default>false</default>
</key>
<key type="b" name="anime-builtins">
<default>false</default>
</key>
<key name="charge-level" type="u">
<range min="20" max="100"/>
<default>100</default>
</key>
<key type="s" name="primary-quickmenu-toggle">
<default>"mini-led"</default>
</key>
</schema>
</schemalist>

View File

@@ -1 +0,0 @@
../../../bindings/ts

View File

@@ -1,127 +0,0 @@
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
import * as platform from "./bindings/platform";
import { AsusQuickToggle } from "./modules/rog_quick_toggle";
import { AsusMenuToggle } from "./modules/rog_menu_toggle";
import { AsusIndicator } from "./modules/rog_indicator";
import { AsusSlider } from "./modules/rog_slider_100pc";
import { FeatureMenuToggle } from "./modules/quick_menus/laptop_features";
import { DbusBase } from "./modules/dbus_proxy";
import { main } from "@girs/gnome-shell/ui";
export const uuid = "asusctl-gnome@asus-linux.org";
export default class AsusExtension extends Extension {
// public dbus_aura: AuraDbus = new AuraDbus;
// public dbus_anime: AnimeDbus = new AnimeDbus;
public dbus_platform: DbusBase | undefined;
public dbus_anime: DbusBase | undefined;
private individual = false;
public supported_properties!: platform.Properties;
public supported_interfaces: string[] = [];
private feature_menu = null;
private panel_od = null;
private mini_led = null;
private anime_display = null;
private anime_builtins = null;
private charge_thres = null;
// private _feature: typeof FeatureMenuToggle;
async enable() {
log(this.path);
if (this.dbus_platform == undefined) {
this.dbus_platform = new DbusBase("org-asuslinux-platform-4.xml", "/org/asuslinux/Platform");
await this.dbus_platform.start();
}
if (this.dbus_anime == undefined) {
this.dbus_anime = new DbusBase("org-asuslinux-anime-4.xml", "/org/asuslinux/Anime");
await this.dbus_anime.start();
}
this.supported_interfaces = this.dbus_platform?.proxy.SupportedInterfacesSync()[0];
this.supported_properties = this.dbus_platform?.proxy.SupportedPropertiesSync()[0];
log(this.supported_interfaces);
log(this.supported_properties);
// new AsusIndicator("selection-mode-symbolic", "mini-led-enabled");
// new AsusIndicator("selection-mode-symbolic", "panel-od-enabled");
if (!this.individual) {
if (this.feature_menu == null)
this.feature_menu = new FeatureMenuToggle(this.dbus_platform, this.dbus_anime);
} else {
if (this.supported_properties.includes("PanelOd") && this.dbus_platform.proxy.PanelOd != null)
if (this.panel_od == null) {
this.panel_od = new AsusQuickToggle(
this.dbus_platform,
"PanelOd",
"panel-od-enabled",
"Panel Overdrive",
);
}
if (this.supported_properties.includes("MiniLed") && this.dbus_platform.proxy.MiniLed != null)
if (this.mini_led == null) {
this.mini_led = new AsusQuickToggle(
this.dbus_platform,
"MiniLed",
"mini-led-enabled",
"Mini-LED",
);
}
if (
this.supported_interfaces.includes("Anime") &&
this.dbus_anime.proxy.EnableDisplay != null
)
if (this.anime_display == null) {
this.anime_display = new AsusQuickToggle(
this.dbus_anime,
"EnableDisplay",
"anime-power",
"AniMe Display",
);
}
if (
this.supported_interfaces.includes("Anime") &&
this.dbus_anime.proxy.BuiltinsEnabled != null
)
if (this.anime_builtins == null) {
this.anime_builtins = new AsusQuickToggle(
this.dbus_anime,
"BuiltinsEnabled",
"anime-builtins",
"Use builtins",
);
}
}
if (
this.supported_properties.includes("ChargeControlEndThreshold") &&
this.dbus_platform.proxy.ChargeControlEndThreshold != null
)
if (this.charge_thres == null) {
this.charge_thres = new AsusSlider(
this.dbus_platform,
"ChargeControlEndThreshold",
"charge-level",
"Charge Level",
);
}
}
disable() {
this.dbus_platform?.stop();
this.dbus_anime?.stop();
this.feature_menu?.destroy();
feature_menu?.destroy();
panel_od?.destroy();
mini_led?.destroy();
anime_display?.destroy();
anime_builtins?.destroy();
charge_thres?.destroy();
}
}

View File

@@ -1,9 +0,0 @@
{
"name": "asusctl-gnome",
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
"uuid": "asusctl-gnome@asus-linux.org",
"uuid-dev": "asusctl-gnome-dev@asus-linux.org",
"settings-schema": "org.gnome.shell.extensions.asusctl-gnome",
"version": "4.3.2",
"shell-version": ["45"]
}

View File

@@ -1,98 +0,0 @@
import { DbusBase } from "../dbus_proxy";
import {
DeviceState,
AnimBooting,
Brightness,
AnimAwake,
AnimSleeping,
AnimShutdown,
} from "../../bindings/anime";
export class AnimeDbus extends DbusBase {
deviceState: DeviceState = {
display_enabled: false,
display_brightness: Brightness.Med,
builtin_anims_enabled: false,
builtin_anims: {
boot: AnimBooting.GlitchConstruction,
awake: AnimAwake.BinaryBannerScroll,
sleep: AnimSleeping.BannerSwipe,
shutdown: AnimShutdown.GlitchOut,
},
off_when_unplugged: false,
off_when_suspended: false,
off_when_lid_closed: false,
};
// TODO: interface or something to enforce requirement of "sync()" method
public notifyAnimeStateSubscribers: any[] = [];
constructor() {
super("org-asuslinux-anime-4", "/org/asuslinux/Anime");
}
_parseData(data: any) {
if (data.length > 0) {
this.deviceState.display_enabled = data[0];
this.deviceState.display_brightness = Brightness[data[1] as Brightness];
this.deviceState.builtin_anims_enabled = data[2];
this.deviceState.builtin_anims.boot = AnimBooting[data[3][0] as AnimBooting];
this.deviceState.builtin_anims.awake = AnimAwake[data[3][1] as AnimAwake];
this.deviceState.builtin_anims.sleep = AnimSleeping[data[3][2] as AnimSleeping];
this.deviceState.builtin_anims.shutdown = AnimShutdown[data[3][3] as AnimShutdown];
this.deviceState.off_when_unplugged = data[4];
this.deviceState.off_when_suspended = data[5];
this.deviceState.off_when_lid_closed = data[6];
}
}
public getDeviceState() {
if (this.isRunning()) {
try {
// janky shit going on with DeviceStateSync
this._parseData(this.dbus_proxy.DeviceStateSync());
//@ts-ignore
log("Anime Matrix: display_enabled: " + this.deviceState.display_enabled);
//@ts-ignore
log("Anime Matrix: display_brightness: " + this.deviceState.display_brightness);
//@ts-ignore
log("Anime Matrix: builtin_anims_enabled: " + this.deviceState.builtin_anims_enabled);
//@ts-ignore
log("Anime Matrix: builtin_anims: " + this.deviceState.builtin_anims);
//@ts-ignore
log("Anime Matrix: off_when_unplugged: " + this.deviceState.off_when_unplugged);
//@ts-ignore
log("Anime Matrix: off_when_suspended: " + this.deviceState.off_when_suspended);
//@ts-ignore
log("Anime Matrix: off_when_lid_closed: " + this.deviceState.off_when_lid_closed);
} catch (e) {
//@ts-ignore
log("Failed to fetch DeviceState!", e);
}
}
return this.deviceState;
}
async start() {
await super.start();
this.getDeviceState();
this.dbus_proxy.connectSignal(
"NotifyDeviceState",
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(proxy: any = null, name: string, data: string) => {
if (proxy) {
// idiot xml parsing mneans the get is not nested while this is
this._parseData(data[0]);
this.notifyAnimeStateSubscribers.forEach((sub) => {
sub.sync();
});
}
},
);
}
async stop() {
await super.stop();
}
}

View File

@@ -1,300 +0,0 @@
import {
AuraDevRog1,
AuraDevTuf,
AuraDevice,
AuraEffect,
AuraModeNum,
AuraPower,
AuraPowerDev,
AuraZone,
Direction,
PowerZones,
Speed,
} from "../../bindings/aura";
import { DbusBase } from "./base";
export class AuraDbus extends DbusBase {
public device: AuraDevice = AuraDevice.Unknown;
public current_aura_mode: AuraModeNum = AuraModeNum.Static;
public aura_modes: Map<AuraModeNum, AuraEffect> = new Map();
public leds_powered: AuraPowerDev = {
tuf: [],
old_rog: [],
rog: {
keyboard: {
zone: PowerZones.Keyboard,
boot: false,
awake: false,
sleep: false,
shutdown: false,
},
logo: {
zone: PowerZones.Logo,
boot: false,
awake: false,
sleep: false,
shutdown: false,
},
lightbar: {
zone: PowerZones.Lightbar,
boot: false,
awake: false,
sleep: false,
shutdown: false,
},
lid: {
zone: PowerZones.Lid,
boot: false,
awake: false,
sleep: false,
shutdown: false,
},
rear_glow: {
zone: PowerZones.RearGlow,
boot: false,
awake: false,
sleep: false,
shutdown: false,
},
},
};
// TODO: interface or something to enforce requirement of "sync()" method
public notifyAuraModeSubscribers: any[] = [];
public notifyAuraPowerSubscribers: any[] = [];
constructor() {
super("org-asuslinux-aura-4", "/org/asuslinux/Aura");
}
public getDevice() {
if (this.isRunning()) {
try {
this.device = AuraDevice[this.dbus_proxy.DeviceTypeSync() as AuraDevice];
//@ts-ignore
log("LED device: " + this.device);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
_parsePowerStates(data: any[]) {
const power: AuraPowerDev = this.leds_powered;
power.tuf = data[0].map((value: string) => {
return AuraDevTuf[value as AuraDevTuf];
});
power.old_rog = data[1].map((value: string) => {
return AuraDevRog1[value as AuraDevRog1];
});
power.rog = {
keyboard: {
zone: PowerZones[data[2][0][0] as PowerZones],
boot: data[2][0][1],
awake: data[2][0][2],
sleep: data[2][0][3],
shutdown: data[2][0][4],
},
logo: {
zone: PowerZones[data[2][1][0] as PowerZones],
boot: data[2][1][1],
awake: data[2][1][2],
sleep: data[2][1][3],
shutdown: data[2][1][4],
},
lightbar: {
zone: PowerZones[data[2][2][0] as PowerZones],
boot: data[2][2][1],
awake: data[2][2][2],
sleep: data[2][2][3],
shutdown: data[2][2][4],
},
lid: {
zone: PowerZones[data[2][3][0] as PowerZones],
boot: data[2][3][1],
awake: data[2][3][2],
sleep: data[2][3][3],
shutdown: data[2][3][4],
},
rear_glow: {
zone: PowerZones[data[2][4][0] as PowerZones],
boot: data[2][4][1],
awake: data[2][4][2],
sleep: data[2][4][3],
shutdown: data[2][4][4],
},
};
return power;
}
public getLedPower() {
if (this.isRunning()) {
try {
const data = this.dbus_proxy.LedPowerSync();
this.leds_powered = this._parsePowerStates(data);
//@ts-ignore
log("LED power tuf: " + this.leds_powered.tuf);
//@ts-ignore
log("LED power x1866: " + this.leds_powered.old_rog);
//@ts-ignore
log("LED power x19b6: " + this.leds_powered.rog);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
public getLedMode() {
if (this.isRunning()) {
try {
this.current_aura_mode = AuraModeNum[this.dbus_proxy.LedModeSync() as AuraModeNum];
//@ts-ignore
log("Current LED mode:", this.current_aura_mode);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
public setLedMode(mode: AuraEffect) {
if (this.isRunning()) {
try {
this.dbus_proxy.SetLedModeSync([
mode.mode,
mode.zone,
[mode.colour1.r, mode.colour1.g, mode.colour1.b],
[mode.colour2.r, mode.colour2.g, mode.colour2.b],
mode.speed,
mode.direction,
]);
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
_parseAuraEffect(data: any[]) {
const aura: AuraEffect = {
mode: AuraModeNum[data[0] as AuraModeNum],
zone: AuraZone[data[1] as AuraZone],
colour1: {
r: parseInt(data[2][0]),
g: parseInt(data[2][1]),
b: parseInt(data[2][2]),
},
colour2: {
r: parseInt(data[3][0]),
g: parseInt(data[3][1]),
b: parseInt(data[3][2]),
},
speed: Speed[data[4] as Speed],
direction: Direction[data[5] as Direction],
};
return aura;
}
// Return a list of the available modes, and the current settings for each
public getLedModes() {
// {'Breathe': ('Breathe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Comet': ('Comet', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Static': ('Static', 'None', (78, 0, 0), (0, 0, 0), 'Med', 'Right'),
// 'Strobe': ('Strobe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right')}
if (this.isRunning()) {
try {
const _data = this.dbus_proxy.LedModesSync();
for (const key in _data[0]) {
const data = _data[0][key];
const aura: AuraEffect = this._parseAuraEffect(data);
this.aura_modes.set(AuraModeNum[key as AuraModeNum], aura);
}
for (const [key, value] of this.aura_modes) {
//@ts-ignore
log(key, value.zone, value.colour1.r, value.speed, value.direction);
}
} catch (e) {
//@ts-ignore
log("Failed to fetch supported functionalities", e);
}
}
}
async start() {
try {
await super.start();
this.getDevice();
this.getLedPower();
this.getLedMode();
this.getLedModes();
//@ts-ignore
log("Current LED mode data:", this.aura_modes.get(this.current_aura_mode)?.speed);
this.dbus_proxy.connectSignal("NotifyLed", (proxy: any = null, name: string, data: any) => {
if (proxy) {
const aura: AuraEffect = this._parseAuraEffect(data[0]);
this.current_aura_mode = aura.mode;
this.aura_modes.set(aura.mode, aura);
//@ts-ignore
log(
"LED data has changed to ",
aura.mode,
aura.zone,
aura.colour1.r,
aura.speed,
aura.direction,
);
this.notifyAuraModeSubscribers.forEach((sub) => {
sub.sync();
});
}
});
this.dbus_proxy.connectSignal(
"NotifyPowerStates",
(proxy: any = null, name: string, data: any) => {
if (proxy) {
const power: AuraPowerDev = this._parsePowerStates(data[0]);
this.leds_powered = power;
switch (this.device) {
case AuraDevice.Tuf:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.tuf);
break;
case AuraDevice.X1854:
case AuraDevice.X1869:
case AuraDevice.X18c6:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.old_rog);
break;
case AuraDevice.X19b6:
case AuraDevice.X1a30:
//@ts-ignore
log("LED power has changed to ", this.leds_powered.rog);
break;
default:
break;
}
//@ts-ignore
log("LED power has changed to ", this.leds_powered.rog);
this.notifyAuraPowerSubscribers.forEach((sub) => {
sub.sync();
});
}
},
);
} catch (e) {
//@ts-ignore
log("Supported DBus initialization failed!", e);
}
}
async stop() {
await super.stop();
}
}

View File

@@ -1,64 +0,0 @@
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
import { Gio } from "@girs/gio-2.0";
import { GLib } from "@girs/glib-2.0";
import { imports } from "@girs/gjs";
// Reads the contents of a file contained in the global resources archive. The data
// is returned as a string.
export function getStringResource(path: string | null) {
const data = Gio.resources_lookup_data(path, 0);
return new TextDecoder().decode(data.get_data()?.buffer);
}
export class DbusBase {
proxy!: Gio.DBusProxy;
connected = false;
ifaceXml = "";
dbus_path = "";
constructor(file_name: string, dbus_path: string) {
let extensionObject = Extension.lookupByUUID("asusctl-gnome@asus-linux.org");
const path = extensionObject?.path + "/resources/dbus/" + file_name;
const [ok, data] = GLib.file_get_contents(path);
if (!ok) {
throw new Error("could not read interface file");
}
this.ifaceXml = imports.byteArray.toString(data);
this.dbus_path = dbus_path;
}
async start() {
//@ts-ignore
log(`Starting ${this.dbus_path} dbus module`);
try {
log(this.ifaceXml);
this.proxy = Gio.DBusProxy.makeProxyWrapper(this.ifaceXml)(
Gio.DBus.system,
"org.asuslinux.Daemon",
this.dbus_path,
);
this.connected = true;
//@ts-ignore
log(`${this.dbus_path} client started successfully.`);
} catch (e) {
//@ts-ignore
logError(`${this.xml_resource} dbus init failed!`, e);
}
}
async stop() {
//@ts-ignore
log(`Stopping ${this.xml_resource} dbus module`);
if (this.connected && this.proxy != undefined) {
this.proxy.run_dispose();
this.proxy = undefined;
this.connected = false;
}
}
isRunning(): boolean {
return this.connected;
}
}

View File

@@ -1,14 +0,0 @@
import * as Main from "resource:///org/gnome/shell/ui/main.js";
import { QuickToggle } from "resource:///org/gnome/shell/ui/quickSettings.js";
export function addQuickSettingsItems(items: [typeof QuickToggle], width = 1) {
const QuickSettingsMenu = Main.panel.statusArea.quickSettings;
items.forEach((item) => QuickSettingsMenu.menu.addItem(item, width));
// Ensure the tile(s) are above the background apps menu
for (const item of items) {
QuickSettingsMenu.menu._grid.set_child_below_sibling(
item,
QuickSettingsMenu._backgroundApps.quickSettingsItems[0],
);
}
}

View File

@@ -1,85 +0,0 @@
import { addQuickSettingsItems } from "../helpers";
import { AuraDbus } from "../dbus/aura";
import { AuraEffect, AuraModeNum } from "../../bindings/aura";
import GObject from "gi://GObject";
import * as PopupMenu from "resource:///org/gnome/shell/ui/popupMenu.js";
import * as QuickSettings from "resource:///org/gnome/shell/ui/quickSettings.js";
export const AuraMenuToggle = GObject.registerClass(
class AuraMenuToggle extends QuickSettings.QuickMenuToggle {
private _dbus_aura: AuraDbus;
private _last_mode: AuraModeNum = AuraModeNum.Static;
constructor(dbus_aura: AuraDbus) {
super({
title: "Aura Modes",
iconName: "selection-mode-symbolic",
toggleMode: true,
});
this._dbus_aura = dbus_aura;
this.connectObject(this);
this.menu.setHeader("selection-mode-symbolic", this._dbus_aura.current_aura_mode);
this._itemsSection = new PopupMenu.PopupMenuSection();
this._dbus_aura.aura_modes.forEach((mode, key) => {
this._itemsSection.addAction(
key,
() => {
this._dbus_aura.setLedMode(mode);
this.sync();
},
"",
);
});
this.menu.addMenuItem(this._itemsSection);
// Add an entry-point for more settings
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
// const settingsItem = this.menu.addAction("More Settings",
// () => ExtensionUtils.openPrefs());
// // Ensure the settings are unavailable when the screen is locked
// settingsItem.visible = Main.sessionMode.allowSettings;
// this.menu._settingsActions[Me.uuid] = settingsItem;
this.connectObject(
"clicked",
() => {
let mode: AuraEffect | undefined;
if (this._dbus_aura.current_aura_mode == AuraModeNum.Static) {
mode = this._dbus_aura.aura_modes.get(this._last_mode);
} else {
mode = this._dbus_aura.aura_modes.get(AuraModeNum.Static);
}
if (mode != undefined) {
this._dbus_aura.setLedMode(mode);
this.sync();
}
},
this,
);
this._dbus_aura.notifyAuraModeSubscribers.push(this);
this.sync();
addQuickSettingsItems([this]);
}
sync() {
const checked = this._dbus_aura.current_aura_mode != AuraModeNum.Static;
this.title = this._dbus_aura.current_aura_mode;
if (
this._last_mode != this._dbus_aura.current_aura_mode &&
this._dbus_aura.current_aura_mode != AuraModeNum.Static
) {
this._last_mode = this._dbus_aura.current_aura_mode;
}
if (this.checked !== checked) this.set({ checked });
}
},
);

View File

@@ -1,216 +0,0 @@
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
import { quickSettings, popupMenu } from "@girs/gnome-shell/ui";
import { GObject } from "@girs/gobject-2.0";
import { DbusBase } from "../../modules/dbus_proxy";
import { addQuickSettingsItems } from "../helpers";
import * as AsusExtension from "../../extension";
import * as platform from "../../bindings/platform";
import { uuid } from "../../extension";
import { AsusMenuToggle } from "../rog_menu_toggle";
export const FeatureMenuToggle = GObject.registerClass(
class FeatureMenuToggle extends quickSettings.QuickMenuToggle {
private dbus_platform: DbusBase;
private dbus_anime: DbusBase;
private last_selection = "mini-led";
private supported_properties!: platform.Properties;
private supported_interfaces: string[] = [];
private miniLed?: typeof AsusMenuToggle;
private panelOd?: typeof AsusMenuToggle;
private animeDisplayPower?: typeof AsusMenuToggle;
private animePowersaveAnim?: typeof AsusMenuToggle;
_itemsSection: popupMenu.PopupMenuSection;
constructor(dbus_platform: DbusBase, dbus_anime: DbusBase) {
super({
label: "Laptop",
toggle_mode: true,
icon_name: "selection-mode-symbolic",
});
this.label = "Laptop";
this.title = "Laptop";
this.dbus_platform = dbus_platform;
this.dbus_anime = dbus_anime;
this.menu.setHeader("selection-mode-symbolic", "Laptop features");
this.last_selection = Extension.lookupByUUID(AsusExtension.uuid)
?.getSettings()
.get_string("primary-quickmenu-toggle")!;
this.supported_interfaces = this.dbus_platform?.proxy.SupportedInterfacesSync()[0];
this.supported_properties = this.dbus_platform?.proxy.SupportedPropertiesSync()[0];
// TODO: temporary block
if (this.last_selection == "mini-led" && !this.supported_properties.includes("MiniLed")) {
this.last_selection = "panel-od";
} else if (
this.last_selection == "panel-od" &&
!this.supported_properties.includes("PanelOd")
) {
this.last_selection = "anime-power";
} else if (
this.last_selection == "anime-power" &&
!this.supported_interfaces.includes("Anime")
) {
this.last_selection = "mini-led";
} else if (this.last_selection.length == 0) {
this.last_selection = "panel-od";
}
// AsusExtension.extension._settings.connect('changed::primary-quickmenu-toggle', this.sync);
Extension.lookupByUUID(uuid)
?.getSettings()
.set_string("primary-quickmenu-toggle", this.last_selection);
this._itemsSection = new popupMenu.PopupMenuSection();
if (this.supported_properties.includes("MiniLed")) {
if (this.miniLed == null) {
this.miniLed = new AsusMenuToggle(
this.dbus_platform,
"MiniLed",
"mini-led-enabled",
"Mini-LED Enabled",
);
this._itemsSection.addMenuItem(this.miniLed, 0);
this.miniLed.toggle_callback = () => {
this.last_selection = "mini-led";
};
}
}
if (this.supported_properties.includes("PanelOd")) {
if (this.panelOd == null) {
this.panelOd = new AsusMenuToggle(
this.dbus_platform,
"PanelOd",
"panel-od-enabled",
"Panel Overdrive Enabled",
);
this._itemsSection.addMenuItem(this.panelOd, 1);
this.panelOd.toggle_callback = () => {
this.last_selection = "panel-od";
};
}
}
if (this.supported_interfaces.includes("Anime")) {
if (this.animeDisplayPower == null) {
this.animeDisplayPower = new AsusMenuToggle(
this.dbus_anime,
"EnableDisplay",
"anime-power",
"AniMe Display Enabled",
);
this._itemsSection.addMenuItem(this.animeDisplayPower, 2);
this.animeDisplayPower.toggle_callback = () => {
this.last_selection = "anime-power";
};
}
if (this.animePowersaveAnim == null) {
this.animePowersaveAnim = new AsusMenuToggle(
this.dbus_anime,
"BuiltinsEnabled",
"anime-builtins",
"AniMe Built-in Animations",
);
this._itemsSection.addMenuItem(this.animePowersaveAnim, 3);
this.animePowersaveAnim.toggle_callback = () => {
this.last_selection = "anime-builtins";
};
}
}
this.connectObject(
"clicked",
() => {
this._toggle();
},
this,
);
this.menu.addMenuItem(this._itemsSection, 0);
this.dbus_platform?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
//const properties = changed.deepUnpack();
this.sync();
});
this.dbus_anime?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
//const properties = changed.deepUnpack();
this.sync();
});
// // Add an entry-point for more extension._settings
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
// const settingsItem = this.menu.addAction("More Settings",
// () => ExtensionUtils.openPrefs());
// // Ensure the extension._settings are unavailable when the screen is locked
// settingsItem.visible = Main.sessionMode.allowSettings;
// this.menu._settingsActions[Me.uuid] = settingsItem;
this.sync();
addQuickSettingsItems([this]);
}
_toggle() {
if (this.last_selection == "mini-led" && this.miniLed != null) {
if (this.checked !== this.dbus_platform.proxy.MiniLed)
this.dbus_platform.proxy.MiniLed = this.checked;
}
if (this.last_selection == "panel-od" && this.panelOd != null) {
if (this.checked !== this.dbus_platform.proxy.PanelOd) {
this.dbus_platform.proxy.PanelOd = this.checked;
}
}
if (this.last_selection == "anime-power" && this.animeDisplayPower != null) {
if (this.checked !== this.dbus_anime.proxy.EnableDisplay)
this.dbus_anime.proxy.EnableDisplay = this.checked;
}
if (this.last_selection == "anime-builtins" && this.animePowersaveAnim != null) {
if (this.checked !== this.dbus_anime.proxy.BuiltinsEnabled)
this.dbus_anime.proxy.BuiltinsEnabled = this.checked;
}
}
sync() {
let checked = false;
if (this.last_selection == "mini-led" && this.miniLed != null) {
this.title = this.miniLed.title;
checked = this.dbus_platform.proxy.MiniLed;
}
if (this.last_selection == "panel-od" && this.panelOd != null) {
this.title = this.panelOd.title;
checked = this.dbus_platform.proxy.PanelOd;
}
if (this.last_selection == "anime-power" && this.animeDisplayPower != null) {
this.title = this.animeDisplayPower.title;
checked = this.dbus_anime.proxy.EnableDisplay;
}
if (this.last_selection == "anime-builtins" && this.animePowersaveAnim != null) {
this.title = this.animePowersaveAnim.title;
checked = this.dbus_anime.proxy.BuiltinsEnabled;
}
// if (this.animePowersaveAnim != null) {
// }
if (this.checked !== checked) this.set({ checked });
}
destroy() {
// this.panelOd?.destroy();
}
},
);

View File

@@ -1,26 +0,0 @@
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
import { quickSettings, main } from "@girs/gnome-shell/ui";
import { Gio } from "@girs/gio-2.0";
import { GObject } from "@girs/gobject-2.0";
import { uuid } from "../extension";
//import { DbusBase } from '../dbus_proxy';
export const AsusIndicator = GObject.registerClass(
class AsusIndicator extends quickSettings.SystemIndicator {
private _indicator: any;
private _settings: Gio.Settings | undefined;
constructor(icon_name: string, setting_name: string) {
super();
// Create an icon for the indicator
this._indicator = this._addIndicator();
this._indicator.icon_name = icon_name;
// Showing an indicator when the feature is enabled
this._settings = Extension.lookupByUUID(uuid)?.getSettings();
this._settings?.bind(setting_name, this._indicator, "visible", Gio.SettingsBindFlags.DEFAULT);
main.panel.statusArea.quickSettings.addExternalIndicator(this);
}
},
);

View File

@@ -1,50 +0,0 @@
import { popupMenu } from "@girs/gnome-shell/ui";
import { GObject } from "@girs/gobject-2.0";
import { DbusBase } from "./dbus_proxy";
export const AsusMenuToggle = GObject.registerClass(
class AsusMenuToggle extends popupMenu.PopupSwitchMenuItem {
public title: string = "";
dbus!: DbusBase;
prop_name: string = "";
public toggle_callback = () => {};
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
super(title, true);
this.prop_name = prop_name;
this.dbus = dbus;
this.title = title;
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
const properties = changed.deepUnpack();
// .find() fails on some shit for some reason
for (const v of Object.entries(properties)) {
if (v[0] == this.prop_name) {
this.sync();
break;
}
}
});
this.connectObject("toggled", () => this._toggleMode(), this);
this.connect("destroy", () => {
this.destroy();
});
this.sync();
}
_toggleMode() {
// hacky shit, index to get base object property and set it
const state = this.dbus.proxy[this.prop_name];
if (this.state !== state) this.dbus.proxy[this.prop_name] = this.state;
this.toggle_callback();
}
sync() {
const state = this.dbus.proxy[this.prop_name];
if (this.state !== state) this.setToggleState(state);
}
},
);

View File

@@ -1,64 +0,0 @@
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
import { addQuickSettingsItems } from "./helpers";
import { quickSettings } from "@girs/gnome-shell/ui";
import { Gio } from "@girs/gio-2.0";
import { GObject } from "@girs/gobject-2.0";
import { uuid } from "../extension";
import { DbusBase } from "./dbus_proxy";
export const AsusQuickToggle = GObject.registerClass(
class AsusQuickToggle extends quickSettings.QuickToggle {
dbus!: DbusBase;
prop_name: string = "";
public toggle_callback = () => {};
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
super({
label: title,
icon_name: "selection-mode-symbolic",
toggle_mode: true,
});
this.prop_name = prop_name;
this.label = title;
this.dbus = dbus;
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
const properties = changed.deepUnpack();
// .find() fails on some shit for some reason
for (const v of Object.entries(properties)) {
if (v[0] == this.prop_name) {
const checked = v[1].unpack();
if (this.checked !== checked) this.checked = checked;
break;
}
}
});
this.connectObject("clicked", () => this._toggleMode(), this);
this.connect("destroy", () => {
this.destroy();
});
Extension.lookupByUUID(uuid)
?.getSettings()
.bind(setting, this, "checked", Gio.SettingsBindFlags.DEFAULT);
this.sync();
addQuickSettingsItems([this]);
}
_toggleMode() {
// hacky shit, index to get base object property and set it
const checked = this.dbus.proxy[this.prop_name];
if (this.checked !== checked) this.dbus.proxy[this.prop_name] = this.checked;
this.toggle_callback();
}
sync() {
const checked = this.dbus.proxy[this.prop_name];
if (this.checked !== checked) this.set({ checked });
}
},
);

View File

@@ -1,75 +0,0 @@
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
import { addQuickSettingsItems } from "./helpers";
import { quickSettings } from "@girs/gnome-shell/ui";
import { Gio } from "@girs/gio-2.0";
import { GObject } from "@girs/gobject-2.0";
import { uuid } from "../extension";
import { DbusBase } from "./dbus_proxy";
export const AsusSlider = GObject.registerClass(
class AsusSlider extends quickSettings.QuickSlider {
private dbus: DbusBase;
private settings: any = undefined;
private setting = "";
private prop_name = "";
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
super({
label: title,
icon_name: "selection-mode-symbolic",
});
this.label = title;
this.dbus = dbus;
this.setting = setting;
this.prop_name = prop_name;
this.settings = Extension.lookupByUUID(uuid)?.getSettings();
this._sliderChangedId = this.slider.connect("drag-end", this._onSliderChanged.bind(this));
// Binding the slider to a GSettings key
this.settings.connect(`changed::${this.setting}`, this._onSettingsChanged.bind(this));
// Set an accessible name for the slider
this.slider.accessible_name = title;
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
const properties = changed.deepUnpack();
// .find() fails on some shit for some reason
for (const v of Object.entries(properties)) {
if (v[0] == this.prop_name) {
const checked = v[1].unpack();
this._sync();
break;
}
}
});
this._sync();
this._onSettingsChanged();
addQuickSettingsItems([this], 2);
}
_onSettingsChanged() {
// Prevent the slider from emitting a change signal while being updated
this.slider.block_signal_handler(this._sliderChangedId);
this.slider.value = this.settings.get_uint(this.setting) / 100.0;
this.slider.unblock_signal_handler(this._sliderChangedId);
}
_onSliderChanged() {
// Assuming our GSettings holds values between 0..100, adjust for the
// slider taking values between 0..1
const percent = Math.floor(this.slider.value * 100);
const stored = Math.floor(this.settings.get_uint(this.setting) / 100.0);
if (this.slider.value !== stored) this.dbus.proxy[this.prop_name] = percent;
this.settings.set_uint(this.setting, percent);
}
_sync() {
const value = this.dbus.proxy[this.prop_name];
if (this.slider.value !== value / 100) this.settings.set_uint(this.setting, value);
}
},
);

View File

@@ -1,19 +0,0 @@
{
// "extends": "@tsconfig/strictest/tsconfig.json",
"compilerOptions": {
"lib": ["ESNext"],
"types": [],
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"declaration": true,
"removeComments": true,
"strict": true,
"allowJs": true,
"paths": {},
"skipLibCheck": true
},
"files": ["./src/extension.ts"],
"include": ["src/*.ts"],
"exclude": [".ts-for-girrc.js", ".eslintrc.cjs"]
}

File diff suppressed because it is too large Load Diff

View File

@@ -58,13 +58,25 @@ impl From<u8> for Brightness {
fn from(v: u8) -> Brightness { fn from(v: u8) -> Brightness {
match v { match v {
0 => Brightness::Off, 0 => Brightness::Off,
2 => Brightness::Low, 1 => Brightness::Low,
3 => Brightness::High, 3 => Brightness::High,
_ => Brightness::Med, _ => Brightness::Med,
} }
} }
} }
impl From<i32> for Brightness {
fn from(v: i32) -> Brightness {
(v as u8).into()
}
}
impl From<Brightness> for i32 {
fn from(v: Brightness) -> i32 {
v as i32
}
}
#[cfg_attr( #[cfg_attr(
feature = "dbus", feature = "dbus",
derive(Type, Value, OwnedValue), derive(Type, Value, OwnedValue),
@@ -90,6 +102,22 @@ impl FromStr for AnimBooting {
} }
} }
impl From<i32> for AnimBooting {
fn from(value: i32) -> Self {
match value {
0 => Self::GlitchConstruction,
1 => Self::StaticEmergence,
_ => Self::default(),
}
}
}
impl From<AnimBooting> for i32 {
fn from(value: AnimBooting) -> Self {
value as i32
}
}
#[cfg_attr( #[cfg_attr(
feature = "dbus", feature = "dbus",
derive(Type, Value, OwnedValue), derive(Type, Value, OwnedValue),
@@ -115,6 +143,22 @@ impl FromStr for AnimAwake {
} }
} }
impl From<i32> for AnimAwake {
fn from(value: i32) -> Self {
match value {
0 => Self::BinaryBannerScroll,
1 => Self::RogLogoGlitch,
_ => Self::default(),
}
}
}
impl From<AnimAwake> for i32 {
fn from(value: AnimAwake) -> Self {
value as i32
}
}
#[cfg_attr( #[cfg_attr(
feature = "dbus", feature = "dbus",
derive(Type, Value, OwnedValue), derive(Type, Value, OwnedValue),
@@ -140,6 +184,22 @@ impl FromStr for AnimSleeping {
} }
} }
impl From<i32> for AnimSleeping {
fn from(value: i32) -> Self {
match value {
0 => Self::BannerSwipe,
1 => Self::Starfield,
_ => Self::default(),
}
}
}
impl From<AnimSleeping> for i32 {
fn from(value: AnimSleeping) -> Self {
value as i32
}
}
#[cfg_attr( #[cfg_attr(
feature = "dbus", feature = "dbus",
derive(Type, Value, OwnedValue), derive(Type, Value, OwnedValue),
@@ -165,6 +225,22 @@ impl FromStr for AnimShutdown {
} }
} }
impl From<i32> for AnimShutdown {
fn from(value: i32) -> Self {
match value {
0 => Self::GlitchOut,
1 => Self::SeeYa,
_ => Self::default(),
}
}
}
impl From<AnimShutdown> for i32 {
fn from(value: AnimShutdown) -> Self {
value as i32
}
}
/// `get_anime_type` is very broad, matching on part of the laptop board name /// `get_anime_type` is very broad, matching on part of the laptop board name
/// only. For this reason `find_node()` must be used also to verify if the USB /// only. For this reason `find_node()` must be used also to verify if the USB
/// device is available. /// device is available.

View File

@@ -67,6 +67,24 @@ impl From<LedBrightness> for u8 {
} }
} }
impl From<LedBrightness> for i32 {
fn from(l: LedBrightness) -> Self {
l as i32
}
}
impl From<i32> for LedBrightness {
fn from(l: i32) -> Self {
match l {
0 => LedBrightness::Off,
1 => LedBrightness::Low,
2 => LedBrightness::Med,
3 => LedBrightness::High,
_ => LedBrightness::Med,
}
}
}
#[typeshare] #[typeshare]
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))] #[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
#[derive(Debug, Clone, PartialEq, Eq, Copy, Deserialize, Serialize)] #[derive(Debug, Clone, PartialEq, Eq, Copy, Deserialize, Serialize)]
@@ -156,6 +174,26 @@ impl FromStr for Speed {
} }
} }
impl From<i32> for Speed {
fn from(value: i32) -> Self {
match value {
0 => Self::Low,
2 => Self::High,
_ => Self::Med,
}
}
}
impl From<Speed> for i32 {
fn from(value: Speed) -> Self {
match value {
Speed::Low => 0,
Speed::Med => 1,
Speed::High => 2,
}
}
}
impl From<Speed> for u8 { impl From<Speed> for u8 {
fn from(s: Speed) -> u8 { fn from(s: Speed) -> u8 {
match s { match s {
@@ -198,6 +236,23 @@ impl FromStr for Direction {
} }
} }
impl From<i32> for Direction {
fn from(value: i32) -> Self {
match value {
1 => Self::Left,
2 => Self::Up,
3 => Self::Down,
_ => Self::Right,
}
}
}
impl From<Direction> for i32 {
fn from(value: Direction) -> Self {
value as i32
}
}
/// Enum of modes that convert to the actual number required by a USB HID packet /// Enum of modes that convert to the actual number required by a USB HID packet
#[typeshare] #[typeshare]
#[cfg_attr( #[cfg_attr(
@@ -292,6 +347,18 @@ impl From<u8> for AuraModeNum {
} }
} }
impl From<i32> for AuraModeNum {
fn from(mode: i32) -> Self {
(mode as u8).into()
}
}
impl From<AuraModeNum> for i32 {
fn from(value: AuraModeNum) -> Self {
value as i32
}
}
impl From<AuraEffect> for AuraModeNum { impl From<AuraEffect> for AuraModeNum {
fn from(value: AuraEffect) -> Self { fn from(value: AuraEffect) -> Self {
value.mode value.mode
@@ -345,6 +412,27 @@ impl FromStr for AuraZone {
} }
} }
impl From<i32> for AuraZone {
fn from(value: i32) -> Self {
match value {
1 => Self::Key1,
2 => Self::Key2,
3 => Self::Key3,
4 => Self::Key4,
5 => Self::Logo,
6 => Self::BarLeft,
7 => Self::BarRight,
_ => Self::default(),
}
}
}
impl From<AuraZone> for i32 {
fn from(value: AuraZone) -> Self {
value as i32
}
}
/// Default factory modes structure. This easily converts to an USB HID packet /// Default factory modes structure. This easily converts to an USB HID packet
/// with: /// with:
/// ```rust /// ```rust

View File

@@ -15,6 +15,7 @@ libappindicator = "0.9" # Tray icon
gtk = "0.18" gtk = "0.18"
asusd = { path = "../asusd" } asusd = { path = "../asusd" }
config-traits = { path = "../config-traits" }
rog_anime = { path = "../rog-anime" } rog_anime = { path = "../rog-anime" }
rog_dbus = { path = "../rog-dbus" } rog_dbus = { path = "../rog-dbus" }
rog_aura = { path = "../rog-aura" } rog_aura = { path = "../rog-aura" }
@@ -28,12 +29,13 @@ env_logger.workspace = true
tokio.workspace = true tokio.workspace = true
serde.workspace = true serde.workspace = true
toml.workspace = true ron.workspace = true
serde_json.workspace = true serde_json.workspace = true
serde_derive.workspace = true serde_derive.workspace = true
zbus.workspace = true zbus.workspace = true
dirs.workspace = true dirs.workspace = true
notify-rust.workspace = true notify-rust.workspace = true
concat-idents.workspace = true
png_pong.workspace = true png_pong.workspace = true
@@ -50,7 +52,7 @@ winit = "*"
[dependencies.slint] [dependencies.slint]
git = "https://github.com/flukejones/sixtyfps.git" git = "https://github.com/flukejones/sixtyfps.git"
default-features = false default-features = false
features = ["std", "compat-1-0", "backend-winit-wayland", "backend-linuxkms", "renderer-femtovg"] features = ["std", "gettext", "compat-1-0", "backend-winit-wayland", "backend-linuxkms", "renderer-femtovg"]
[build-dependencies.slint-build] [build-dependencies.slint-build]
git = "https://github.com/flukejones/sixtyfps.git" git = "https://github.com/flukejones/sixtyfps.git"

View File

@@ -1,22 +1,11 @@
# App template # ROGALOG
This is a trial app cut down to bare essentials to show how to create an app that can run in the background ### Translations
with some user-config options.
egui based. Keep in mind that this is very much a bit of a mess due to experimenting. You can help with translations by following https://slint.dev/releases/1.1.0/docs/slint/src/concepts/translations#translate-the-strings
## Running Begin by copying `rog-control-center/translations/en/rog-control-center.po` to `rog-control-center/translations/<YOUR LOCALE>/rog-control-center.po`, then edit that file.
Use `WINIT_UNIX_BACKEND=x11 rog-control-center`. `WINIT_UNIX_BACKEND` is required due to window decorations not updating and the window not really being set as visible/invisible on wayland. Run `msgfmt rog-control-center/translations/<YOUR LOCALE>/rog-control-center.po -o rog-control-center/translations/<YOUR LOCALE>/LC_MESSAGES/rog-control-center.mo` to make the binary formatted translation where `<YOUR LOCALE>` is changed to your translation locale.
## Build features To test you local translations run `RUST_TRANSLATIONS=1 rog-control-center`.
For testing some features that are typically not available on all laptops:
```rust
cargo run --features mocking
```
## TODO
- Add notification watch for certain UI elements to enforce an update (for example when a user changes Aura via a hot key).

View File

@@ -1,33 +1,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
// use std::fs::OpenOptions;
// use std::io::Write;
// use diter_protocol::ParameterDefinitions;
// use ron::ser::PrettyConfig;
// const LOCALE_EN: &str = use slint_build::CompilerConfiguration;
// include_str!("../data/localization/en/parameters.json"); const LOCALE_IT:
// &str = include_str!("../data/localization/it/parameters.json");
// const LOCALE_ZH: &str =
// include_str!("../data/localization/zh/parameters.json");
// fn write_locales() {
// let root = env!("CARGO_MANIFEST_DIR");
// let mut path = PathBuf::from_str(root).unwrap();
// path.push("src/locales.ron");
// let mut file = OpenOptions::new();
// file.truncate(true).create(true).write(true);
// let en: ParameterDefinitions = serde_json::from_str(LOCALE_EN).unwrap();
// let mut writer = file.open(path).unwrap();
// let en = ron::ser::to_string_pretty(&en,
// PrettyConfig::new().depth_limit(4)).unwrap(); writer.write_all(en.
// to_string().as_bytes()).unwrap();
// // let it: ParameterDefinitions =
// serde_json::from_str(LOCALE_IT).unwrap(); // let zh: ParameterDefinitions
// = serde_json::from_str(LOCALE_ZH).unwrap(); }
fn main() { fn main() {
// write_locales(); // write_locales();
@@ -35,5 +9,9 @@ fn main() {
let root = env!("CARGO_MANIFEST_DIR"); let root = env!("CARGO_MANIFEST_DIR");
let mut path = PathBuf::from_str(root).unwrap(); let mut path = PathBuf::from_str(root).unwrap();
path.push("ui/main_window.slint"); path.push("ui/main_window.slint");
slint_build::compile(path).unwrap(); slint_build::compile_with_config(
path,
CompilerConfiguration::new().with_style("cosmic-dark".into()),
)
.unwrap();
} }

View File

@@ -1,10 +1,8 @@
use std::fs::{create_dir, OpenOptions}; use std::fs::create_dir;
use std::io::{Read, Write};
use log::{error, info, warn}; use config_traits::{StdConfig, StdConfigLoad1};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use crate::error::Error;
use crate::update_and_notify::EnabledNotifications; use crate::update_and_notify::EnabledNotifications;
const CFG_DIR: &str = "rog"; const CFG_DIR: &str = "rog";
@@ -38,134 +36,32 @@ impl Default for Config {
} }
} }
impl Config { impl StdConfig for Config {
pub fn load() -> Result<Config, Error> { fn new() -> Self {
let mut path = if let Some(dir) = dirs::config_dir() { Config {
info!("Found XDG config dir {dir:?}"); ..Default::default()
dir }
} else { }
error!("Could not get XDG config dir");
return Err(Error::XdgVars); fn config_dir() -> std::path::PathBuf {
}; let mut path = dirs::config_dir().unwrap_or_default();
path.push(CFG_DIR); path.push(CFG_DIR);
if !path.exists() { if !path.exists() {
create_dir(path.clone())?; create_dir(path.clone())
info!("Created {path:?}"); .map_err(|e| log::error!("Could not create config dir: {e}"))
.ok();
log::info!("Created {path:?}");
} }
path
path.push(CFG_FILE_NAME);
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)?;
let mut buf = String::new();
// Lint to allow, because we want the above file behaviour
#[allow(clippy::verbose_file_reads)]
if let Ok(read_len) = file.read_to_string(&mut buf) {
if read_len == 0 {
warn!("Zero len read of Config file");
let default = Config::default();
let t = toml::to_string_pretty(&default).unwrap();
file.write_all(t.as_bytes())?;
return Ok(default);
} else if let Ok(data) = toml::from_str::<Config>(&buf) {
info!("Loaded config file {path:?}");
return Ok(data);
} else if let Ok(data) = toml::from_str::<Config461>(&buf) {
info!("Loaded old v4.6.1 config file {path:?}");
return Ok(data.into());
} else if let Ok(data) = toml::from_str::<Config460>(&buf) {
info!("Loaded old v4.6.0 config file {path:?}");
return Ok(data.into());
} else if let Ok(data) = toml::from_str::<Config455>(&buf) {
info!("Loaded old v4.5.5 config file {path:?}");
return Ok(data.into());
}
}
Err(Error::ConfigLoadFail)
} }
pub fn save(&mut self, enabled_notifications: &EnabledNotifications) -> Result<(), Error> { fn file_name(&self) -> String {
let mut path = if let Some(dir) = dirs::config_dir() { CFG_FILE_NAME.to_owned()
dir
} else {
return Err(Error::XdgVars);
};
path.push(CFG_DIR);
if !path.exists() {
create_dir(path.clone())?;
info!("Created {path:?}");
}
path.push(CFG_FILE_NAME);
let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(&path)?;
self.enabled_notifications = enabled_notifications.clone();
let t = toml::to_string_pretty(&self).unwrap();
file.write_all(t.as_bytes())?;
info!("Saved config file {path:?}");
Ok(())
} }
} }
#[derive(Debug, Clone, Deserialize, Serialize)] impl StdConfigLoad1<Config461> for Config {}
pub struct Config455 {
pub run_in_background: bool,
pub startup_in_background: bool,
pub enable_notifications: bool,
pub enabled_notifications: EnabledNotifications,
}
impl From<Config455> for Config {
fn from(c: Config455) -> Self {
Self {
run_in_background: c.run_in_background,
startup_in_background: c.startup_in_background,
enable_tray_icon: true,
enable_notifications: c.enable_notifications,
enabled_notifications: c.enabled_notifications,
dark_mode: true,
ac_command: String::new(),
bat_command: String::new(),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Config460 {
pub run_in_background: bool,
pub startup_in_background: bool,
pub ac_command: String,
pub bat_command: String,
pub enable_notifications: bool,
pub enabled_notifications: EnabledNotifications,
}
impl From<Config460> for Config {
fn from(c: Config460) -> Self {
Self {
run_in_background: c.run_in_background,
startup_in_background: c.startup_in_background,
enable_tray_icon: true,
ac_command: c.ac_command,
bat_command: c.bat_command,
dark_mode: true,
enable_notifications: c.enable_notifications,
enabled_notifications: c.enabled_notifications,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Config461 { pub struct Config461 {

View File

@@ -19,6 +19,7 @@ pub mod error;
pub mod mocking; pub mod mocking;
pub mod system_state; pub mod system_state;
pub mod tray; pub mod tray;
pub mod ui_setup;
pub mod update_and_notify; pub mod update_and_notify;
#[cfg(feature = "mocking")] #[cfg(feature = "mocking")]

View File

@@ -3,9 +3,10 @@ use std::env::args;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread::{self, sleep, spawn}; use std::thread::{self, sleep};
use std::time::Duration; use std::time::Duration;
use config_traits::{StdConfig, StdConfigLoad1};
use gumdrop::Options; use gumdrop::Options;
use log::LevelFilter; use log::LevelFilter;
use rog_control_center::cli_options::CliStart; use rog_control_center::cli_options::CliStart;
@@ -14,12 +15,12 @@ use rog_control_center::error::Result;
use rog_control_center::slint::ComponentHandle; use rog_control_center::slint::ComponentHandle;
use rog_control_center::system_state::{AuraCreation, SystemState}; use rog_control_center::system_state::{AuraCreation, SystemState};
use rog_control_center::tray::init_tray; use rog_control_center::tray::init_tray;
use rog_control_center::ui_setup::setup_window;
use rog_control_center::update_and_notify::{start_notifications, EnabledNotifications}; use rog_control_center::update_and_notify::{start_notifications, EnabledNotifications};
use rog_control_center::{ use rog_control_center::{
get_ipc_file, on_tmp_dir_exists, print_versions, AvailableSystemProperties, MainWindow, get_ipc_file, on_tmp_dir_exists, print_versions, MainWindow, RogDbusClientBlocking, QUIT_APP,
RogDbusClientBlocking, SystemPage, QUIT_APP, SHOWING_GUI, SHOW_GUI, SHOWING_GUI, SHOW_GUI,
}; };
use rog_dbus::zbus_platform::{PlatformProxy, PlatformProxyBlocking};
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
// use winit::monitor::VideoMode; // use winit::monitor::VideoMode;
// use winit::window::{Fullscreen, WindowLevel}; // use winit::window::{Fullscreen, WindowLevel};
@@ -76,12 +77,11 @@ fn main() -> Result<()> {
}; };
// Startup // Startup
let mut config = Config::load()?; let mut config = Config::new().load();
if config.startup_in_background { if config.startup_in_background {
config.run_in_background = true; config.run_in_background = true;
let tmp = config.enabled_notifications.clone(); // ends up being a double clone, oh well. config.write();
config.save(&tmp)?;
} else { } else {
get_ipc_file().unwrap().write_all(&[SHOW_GUI, 0]).unwrap(); get_ipc_file().unwrap().write_all(&[SHOW_GUI, 0]).unwrap();
} }
@@ -92,14 +92,27 @@ fn main() -> Result<()> {
// TODO: config mutex to share config in various places // TODO: config mutex to share config in various places
let states = setup_page_state_and_notifs(aura_creation, &enabled_notifications, &config)?; let states = setup_page_state_and_notifs(aura_creation, &enabled_notifications, &config)?;
if config.enable_tray_icon { let enable_tray_icon = config.enable_tray_icon;
init_tray(supported_properties, states.clone()); let startup_in_background = config.startup_in_background;
let config = Arc::new(Mutex::new(config));
if enable_tray_icon {
init_tray(supported_properties, states.clone(), config.clone());
} }
thread_local! { pub static UI: std::cell::RefCell<Option<MainWindow>> = Default::default()}; thread_local! { pub static UI: std::cell::RefCell<Option<MainWindow>> = Default::default()};
i_slint_backend_selector::with_platform(|_| Ok(())).unwrap(); i_slint_backend_selector::with_platform(|_| Ok(())).unwrap();
let mut do_once = !config.startup_in_background; let mut do_once = !startup_in_background;
if std::env::var("RUST_TRANSLATIONS").is_ok() {
// don't care about content
log::debug!("---- Using local-dir translations");
slint::init_translations!("/usr/share/locale/");
} else {
log::debug!("Using system installed translations");
slint::init_translations!(concat!(env!("CARGO_MANIFEST_DIR"), "/translations/"));
}
thread::spawn(move || { thread::spawn(move || {
let mut buf = [0u8; 2]; let mut buf = [0u8; 2];
// blocks until it is read, typically the read will happen after a second // blocks until it is read, typically the read will happen after a second
@@ -113,7 +126,6 @@ fn main() -> Result<()> {
} }
if buf[0] == SHOW_GUI { if buf[0] == SHOW_GUI {
println!("Should show window {buf:?}");
// There's a balancing act with read/write timing of IPC, there needs to be a // There's a balancing act with read/write timing of IPC, there needs to be a
// small sleep after this to give any other process a chance to // small sleep after this to give any other process a chance to
// read the IPC before looping // read the IPC before looping
@@ -123,7 +135,7 @@ fn main() -> Result<()> {
.unwrap(); .unwrap();
sleep(Duration::from_millis(50)); sleep(Duration::from_millis(50));
let states = states.clone(); let config_copy = config.clone();
i_slint_core::api::invoke_from_event_loop(move || { i_slint_core::api::invoke_from_event_loop(move || {
UI.with(|ui| { UI.with(|ui| {
let mut ui = ui.borrow_mut(); let mut ui = ui.borrow_mut();
@@ -134,9 +146,8 @@ fn main() -> Result<()> {
slint::CloseRequestResponse::HideWindow slint::CloseRequestResponse::HideWindow
}); });
} else { } else {
let newui = setup_window(states.clone()); let newui = setup_window(config_copy);
newui.window().show().unwrap(); newui.window().show().unwrap();
println!("New window should be showing now"); // but it isn't
newui.window().on_close_requested(|| { newui.window().on_close_requested(|| {
get_ipc_file().unwrap().write_all(&[0, 0]).unwrap(); get_ipc_file().unwrap().write_all(&[0, 0]).unwrap();
slint::CloseRequestResponse::HideWindow slint::CloseRequestResponse::HideWindow
@@ -149,13 +160,13 @@ fn main() -> Result<()> {
} else if buf[1] == QUIT_APP { } else if buf[1] == QUIT_APP {
slint::quit_event_loop().unwrap(); slint::quit_event_loop().unwrap();
} else if buf[0] != SHOWING_GUI { } else if buf[0] != SHOWING_GUI {
Config::load().unwrap(); if let Ok(lock) = config.lock() {
if !config.run_in_background { if !lock.run_in_background {
slint::quit_event_loop().unwrap(); slint::quit_event_loop().unwrap();
return; return;
}
} }
println!("Should hide window {buf:?}");
i_slint_core::api::invoke_from_event_loop(move || { i_slint_core::api::invoke_from_event_loop(move || {
UI.with(|ui| { UI.with(|ui| {
let mut ui = ui.take(); let mut ui = ui.take();
@@ -173,106 +184,6 @@ fn main() -> Result<()> {
Ok(()) Ok(())
} }
fn setup_window(_states: Arc<Mutex<SystemState>>) -> MainWindow {
// slint::platform::set_platform(Box::new(i_slint_backend_winit::Backend::new().
// unwrap())).unwrap();
let ui = MainWindow::new().unwrap();
let handle = ui.as_weak();
ui.global::<SystemPage>().on_cancelled(move || {
handle.upgrade_in_event_loop(|_handle| {}).ok();
});
// TODO: macro
let conn = zbus::blocking::Connection::system().unwrap();
let proxy = PlatformProxyBlocking::new(&conn).unwrap();
let proxy2 = proxy.clone();
ui.global::<SystemPage>().on_set_charge_limit(move |limit| {
dbg!(limit);
proxy.set_charge_control_end_threshold(limit as u8).unwrap();
});
ui.global::<SystemPage>().on_set_panel_od(move |od| {
dbg!(od);
proxy2.set_panel_od(od).unwrap();
});
// let handle = ui.as_weak();
// ui.global::<SystemPage>().on_applied(move || {
// handle
// .upgrade_in_event_loop(|handle| {
// let data = handle.global::<SystemPage>();
// let charge_changed = data.get_charge_limit() as i32 !=
// data.get_last_charge_limit(); let charge =
// data.get_charge_limit() as u8; tokio::spawn(async move {
// let conn = zbus::Connection::system().await.unwrap();
// let proxy = PlatformProxy::new(&conn).await.unwrap();
// if charge_changed {
// proxy
// .set_charge_control_end_threshold(charge)
// .await
// .unwrap();
// }
// });
// })
// .ok();
// });
// or
// let handle = ui.as_weak();
// tokio::spawn(async move {
// // TODO: macro
// let conn = zbus::Connection::system().await.unwrap();
// let proxy = PlatformProxy::new(&conn).await.unwrap();
// let proxy2 = proxy.clone();
// handle.upgrade_in_event_loop(move |handle| {
// handle
// .global::<SystemPage>()
// .on_set_charge_limit(move |limit| {
// let proxy = proxy.clone();
// tokio::spawn(async move {
// dbg!(limit);
// proxy
// .set_charge_control_end_threshold(limit as u8)
// .await
// .unwrap();
// });
// });
// handle.global::<SystemPage>().on_set_panel_od(move |od| {
// let proxy2 = proxy2.clone();
// tokio::spawn(async move {
// dbg!(od);
// proxy2.set_panel_od(od).await.unwrap();
// });
// });
// }).ok();
// });
let props = AvailableSystemProperties {
ac_command: true,
bat_command: true,
charge_limit: true,
disable_nvidia_powerd_on_battery: true,
mini_led_mode: true,
nv_dynamic_boost: true,
nv_temp_target: true,
panel_od: true,
ppt_apu_sppt: true,
ppt_fppt: true,
ppt_pl1_spl: true,
ppt_pl2_sppt: true,
ppt_platform_sppt: true,
throttle_policy: true,
};
ui.global::<SystemPage>().set_available(props);
ui.on_exit_app(move || {
slint::quit_event_loop().unwrap();
});
ui
}
fn setup_page_state_and_notifs( fn setup_page_state_and_notifs(
aura_creation: AuraCreation, aura_creation: AuraCreation,
enabled_notifications: &Arc<Mutex<EnabledNotifications>>, enabled_notifications: &Arc<Mutex<EnabledNotifications>>,

View File

@@ -16,6 +16,7 @@ use supergfxctl::pci_device::{GfxMode, GfxPower};
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking; use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking;
use versions::Versioning; use versions::Versioning;
use crate::config::Config;
use crate::error::Result; use crate::error::Result;
use crate::system_state::SystemState; use crate::system_state::SystemState;
use crate::{get_ipc_file, SHOW_GUI}; use crate::{get_ipc_file, SHOW_GUI};
@@ -86,7 +87,7 @@ impl ROGTray {
e e
})?; })?;
let gfx_proxy = GfxProxyBlocking::builder(&conn).build().map_err(|e| { let gfx_proxy = GfxProxyBlocking::new(&conn).map_err(|e| {
error!("ROGTray: {e}"); error!("ROGTray: {e}");
e e
})?; })?;
@@ -438,7 +439,11 @@ impl ROGTray {
} }
/// The tray is controlled somewhat by `Arc<Mutex<SystemState>>` /// The tray is controlled somewhat by `Arc<Mutex<SystemState>>`
pub fn init_tray(supported_properties: Vec<Properties>, states: Arc<Mutex<SystemState>>) { pub fn init_tray(
supported_properties: Vec<Properties>,
states: Arc<Mutex<SystemState>>,
config: Arc<Mutex<Config>>,
) {
std::thread::spawn(move || { std::thread::spawn(move || {
let gtk_init = gtk::init().map_err(|e| { let gtk_init = gtk::init().map_err(|e| {
error!("ROGTray: gtk init {e}"); error!("ROGTray: gtk init {e}");
@@ -496,6 +501,12 @@ pub fn init_tray(supported_properties: Vec<Properties>, states: Arc<Mutex<System
info!("Started ROGTray"); info!("Started ROGTray");
loop { loop {
if let Ok(lock) = config.try_lock() {
if !lock.enable_tray_icon {
break;
}
}
let states = tray.states.clone(); let states = tray.states.clone();
if let Ok(mut lock) = states.lock() { if let Ok(mut lock) = states.lock() {
if lock.tray_should_update { if lock.tray_should_update {

View File

@@ -0,0 +1,691 @@
use std::sync::{Arc, Mutex};
use config_traits::StdConfig;
use rog_anime::Animations;
use rog_dbus::zbus_anime::AnimeProxy;
use rog_dbus::zbus_aura::AuraProxy;
use rog_dbus::zbus_platform::{PlatformProxy, PlatformProxyBlocking};
use rog_platform::platform::Properties;
use slint::{Color, ComponentHandle, Model, RgbaColor, SharedString, Weak};
use zbus::proxy::CacheProperties;
use crate::config::Config;
use crate::{
AnimePageData, AppSettingsPageData, AuraPageData, AvailableSystemProperties, MainWindow,
SystemPageData,
};
impl From<rog_aura::AuraEffect> for crate::slint_generatedMainWindow::AuraEffect {
fn from(m: rog_aura::AuraEffect) -> Self {
Self {
colour1: RgbaColor {
red: m.colour1.r,
green: m.colour1.g,
blue: m.colour1.b,
alpha: 255,
}
.into(),
colour2: RgbaColor {
red: m.colour2.r,
green: m.colour2.g,
blue: m.colour2.b,
alpha: 255,
}
.into(),
direction: m.direction.into(),
mode: m.mode.into(),
speed: m.speed.into(),
zone: m.zone.into(),
}
}
}
impl From<crate::slint_generatedMainWindow::AuraEffect> for rog_aura::AuraEffect {
fn from(m: crate::slint_generatedMainWindow::AuraEffect) -> Self {
let c1: RgbaColor<u8> = m.colour1.into();
let c2: RgbaColor<u8> = m.colour2.into();
Self {
colour1: rog_aura::Colour {
r: c1.red,
g: c1.green,
b: c1.blue,
},
colour2: rog_aura::Colour {
r: c2.red,
g: c2.green,
b: c2.blue,
},
direction: m.direction.into(),
mode: m.mode.into(),
speed: m.speed.into(),
zone: m.zone.into(),
}
}
}
// This macro expects are consistent naming between proxy calls and slint
// globals
macro_rules! set_ui_props_async {
($ui:ident, $proxy:ident, $global:ident, $proxy_fn:ident) => {
if let Ok(value) = $proxy.$proxy_fn().await {
$ui.upgrade_in_event_loop(move |handle| {
concat_idents::concat_idents!(set = set_, $proxy_fn {
handle.global::<$global>().set(value.into());
});
}).ok();
}
};
}
// this macro sets up:
// - a link from UI callback -> dbus proxy property
// - a link from dbus property signal -> UI state
// conv1 and conv2 are type conversion args
macro_rules! set_ui_callbacks {
($handle:ident, $data:ident($($conv1: tt)*),$proxy:ident.$proxy_fn:tt($($conv2: tt)*),$success:literal,$failed:literal) => {
let handle_copy = $handle.as_weak();
let proxy_copy = $proxy.clone();
let data = $handle.global::<$data>();
concat_idents::concat_idents!(on_set = on_set_, $proxy_fn {
data.on_set(move |value| {
let proxy_copy = proxy_copy.clone();
let handle_copy = handle_copy.clone();
tokio::spawn(async move {
concat_idents::concat_idents!(set = set_, $proxy_fn {
show_toast(
format!($success, value).into(),
$failed.into(),
handle_copy,
proxy_copy.set(value $($conv2)*).await,
);
});
});
});
});
let handle_copy = $handle.as_weak();
let proxy_copy = $proxy.clone();
concat_idents::concat_idents!(receive = receive_, $proxy_fn, _changed {
// spawn required since the while let never exits
tokio::spawn(async move {
let mut x = proxy_copy.receive().await;
concat_idents::concat_idents!(set = set_, $proxy_fn {
use zbus::export::futures_util::StreamExt;
while let Some(e) = x.next().await {
if let Ok(out) = e.get().await {
handle_copy.upgrade_in_event_loop(move |handle| {
handle.global::<$data>().set(out $($conv1)*);
}).ok();
}
}
});
});
});
};
}
pub fn setup_window(_config: Arc<Mutex<Config>>) -> MainWindow {
let ui = MainWindow::new().unwrap();
let conn = zbus::blocking::Connection::system().unwrap();
let platform = PlatformProxyBlocking::new(&conn).unwrap();
let interfaces = platform.supported_interfaces().unwrap();
log::debug!("Available interfaces: {interfaces:?}");
// "Anime", "Aura", "FanCurves", "Platform"
ui.set_sidebar_items_avilable(
[
// Needs to match the order of slint sidebar items
interfaces.contains(&"Platform".into()),
interfaces.contains(&"Aura".into()),
interfaces.contains(&"Anime".into()),
interfaces.contains(&"FanCurves".into()),
true,
true,
]
.into(),
);
ui.on_exit_app(move || {
slint::quit_event_loop().unwrap();
});
setup_app_settings_page(&ui, _config.clone());
setup_system_page(&ui, _config.clone());
setup_system_page_callbacks(&ui, _config.clone());
setup_aura_page(&ui, _config.clone());
setup_anime_page(&ui, _config);
ui
}
pub fn setup_app_settings_page(ui: &MainWindow, config: Arc<Mutex<Config>>) {
let config_copy = config.clone();
let global = ui.global::<AppSettingsPageData>();
global.on_set_run_in_background(move |enable| {
if let Ok(mut lock) = config_copy.try_lock() {
lock.run_in_background = enable;
lock.write();
}
});
let config_copy = config.clone();
global.on_set_startup_in_background(move |enable| {
if let Ok(mut lock) = config_copy.try_lock() {
lock.startup_in_background = enable;
lock.write();
}
});
let config_copy = config.clone();
global.on_set_enable_tray_icon(move |enable| {
if let Ok(mut lock) = config_copy.try_lock() {
lock.enable_tray_icon = enable;
lock.write();
}
});
let config_copy = config.clone();
global.on_set_enable_notifications(move |enable| {
if let Ok(mut lock) = config_copy.try_lock() {
lock.enable_notifications = enable;
lock.write();
}
});
if let Ok(lock) = config.try_lock() {
global.set_run_in_background(lock.run_in_background);
global.set_startup_in_background(lock.startup_in_background);
global.set_enable_tray_icon(lock.enable_tray_icon);
global.set_enable_notifications(lock.enable_notifications);
}
}
pub fn setup_system_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
let conn = zbus::blocking::Connection::system().unwrap();
let platform = PlatformProxyBlocking::new(&conn).unwrap();
let sys_props = platform.supported_properties().unwrap();
log::debug!("Available system properties: {sys_props:?}");
let props = AvailableSystemProperties {
ac_command: true,
bat_command: true,
charge_control_end_threshold: sys_props.contains(&Properties::ChargeControlEndThreshold),
disable_nvidia_powerd_on_battery: true,
mini_led_mode: sys_props.contains(&Properties::MiniLedMode),
nv_dynamic_boost: sys_props.contains(&Properties::NvDynamicBoost),
nv_temp_target: sys_props.contains(&Properties::NvTempTarget),
panel_od: sys_props.contains(&Properties::PanelOd),
ppt_apu_sppt: sys_props.contains(&Properties::PptApuSppt),
ppt_fppt: sys_props.contains(&Properties::PptFppt),
ppt_pl1_spl: sys_props.contains(&Properties::PptPl1Spl),
ppt_pl2_sppt: sys_props.contains(&Properties::PptPl2Sppt),
ppt_platform_sppt: sys_props.contains(&Properties::PptPlatformSppt),
throttle_thermal_policy: sys_props.contains(&Properties::ThrottlePolicy),
};
ui.global::<SystemPageData>().set_available(props);
}
pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
// This tokio spawn exists only to prevent blocking the UI, and to enable use of
// async zbus interfaces
let handle = ui.as_weak();
tokio::spawn(async move {
// Create the connections/proxies here to prevent future delays in process
let conn = zbus::Connection::system().await.unwrap();
let platform = PlatformProxy::new(&conn).await.unwrap();
set_ui_props_async!(
handle,
platform,
SystemPageData,
charge_control_end_threshold
);
set_ui_props_async!(handle, platform, SystemPageData, throttle_thermal_policy);
set_ui_props_async!(handle, platform, SystemPageData, throttle_policy_linked_epp);
set_ui_props_async!(handle, platform, SystemPageData, throttle_balanced_epp);
set_ui_props_async!(handle, platform, SystemPageData, throttle_performance_epp);
set_ui_props_async!(handle, platform, SystemPageData, throttle_quiet_epp);
set_ui_props_async!(handle, platform, SystemPageData, throttle_policy_on_battery);
set_ui_props_async!(handle, platform, SystemPageData, throttle_policy_on_ac);
set_ui_props_async!(handle, platform, SystemPageData, panel_od);
set_ui_props_async!(handle, platform, SystemPageData, mini_led_mode);
set_ui_props_async!(handle, platform, SystemPageData, ppt_pl1_spl);
set_ui_props_async!(handle, platform, SystemPageData, ppt_pl2_sppt);
set_ui_props_async!(handle, platform, SystemPageData, ppt_fppt);
set_ui_props_async!(handle, platform, SystemPageData, ppt_apu_sppt);
set_ui_props_async!(handle, platform, SystemPageData, ppt_platform_sppt);
set_ui_props_async!(handle, platform, SystemPageData, nv_dynamic_boost);
set_ui_props_async!(handle, platform, SystemPageData, nv_temp_target);
let sys_props = platform.supported_properties().await.unwrap();
log::debug!("Available system properties: {sys_props:?}");
let props = AvailableSystemProperties {
ac_command: true,
bat_command: true,
charge_control_end_threshold: sys_props
.contains(&Properties::ChargeControlEndThreshold),
disable_nvidia_powerd_on_battery: true,
mini_led_mode: sys_props.contains(&Properties::MiniLedMode),
nv_dynamic_boost: sys_props.contains(&Properties::NvDynamicBoost),
nv_temp_target: sys_props.contains(&Properties::NvTempTarget),
panel_od: sys_props.contains(&Properties::PanelOd),
ppt_apu_sppt: sys_props.contains(&Properties::PptApuSppt),
ppt_fppt: sys_props.contains(&Properties::PptFppt),
ppt_pl1_spl: sys_props.contains(&Properties::PptPl1Spl),
ppt_pl2_sppt: sys_props.contains(&Properties::PptPl2Sppt),
ppt_platform_sppt: sys_props.contains(&Properties::PptPlatformSppt),
throttle_thermal_policy: sys_props.contains(&Properties::ThrottlePolicy),
};
handle
.upgrade_in_event_loop(move |handle| {
handle.global::<SystemPageData>().set_available(props);
set_ui_callbacks!(handle,
SystemPageData(as f32),
platform.charge_control_end_threshold(as u8),
"Charge limit successfully set to {}",
"Setting Charge limit failed"
);
set_ui_callbacks!(
handle,
SystemPageData(),
platform.panel_od(),
"Panel OverDrive successfully set to {}",
"Setting Panel OverDrive failed"
);
set_ui_callbacks!(
handle,
SystemPageData(),
platform.mini_led_mode(),
"MiniLED mode successfully set to {}",
"Setting MiniLED mode failed"
);
set_ui_callbacks!(handle,
SystemPageData(as i32),
platform.throttle_thermal_policy(.into()),
"Throttle policy set to {}",
"Setting Throttle policy failed"
);
set_ui_callbacks!(handle,
SystemPageData(as i32),
platform.throttle_balanced_epp(.into()),
"Throttle policy EPP set to {}",
"Setting Throttle policy EPP failed"
);
set_ui_callbacks!(handle,
SystemPageData(as i32),
platform.throttle_performance_epp(.into()),
"Throttle policy EPP set to {}",
"Setting Throttle policy EPP failed"
);
set_ui_callbacks!(handle,
SystemPageData(as i32),
platform.throttle_quiet_epp(.into()),
"Throttle policy EPP set to {}",
"Setting Throttle policy EPP failed"
);
set_ui_callbacks!(
handle,
SystemPageData(),
platform.throttle_policy_linked_epp(),
"Throttle policy linked to EPP: {}",
"Setting Throttle policy linked to EPP failed"
);
set_ui_callbacks!(handle,
SystemPageData(as i32),
platform.throttle_policy_on_ac(.into()),
"Throttle policy on AC set to {}",
"Setting Throttle policy on AC failed"
);
set_ui_callbacks!(handle,
SystemPageData(as i32),
platform.throttle_policy_on_battery(.into()),
"Throttle policy on abttery set to {}",
"Setting Throttle policy on battery failed"
);
set_ui_callbacks!(handle,
SystemPageData(as f32),
platform.ppt_pl1_spl(as u8),
"ppt_pl1_spl successfully set to {}",
"Setting ppt_pl1_spl failed"
);
set_ui_callbacks!(handle,
SystemPageData(as f32),
platform.ppt_pl2_sppt(as u8),
"ppt_pl2_sppt successfully set to {}",
"Setting ppt_pl2_sppt failed"
);
set_ui_callbacks!(handle,
SystemPageData(as f32),
platform.ppt_fppt(as u8),
"ppt_fppt successfully set to {}",
"Setting ppt_fppt failed"
);
set_ui_callbacks!(handle,
SystemPageData(as f32),
platform.ppt_apu_sppt(as u8),
"ppt_apu_sppt successfully set to {}",
"Setting ppt_apu_sppt failed"
);
set_ui_callbacks!(handle,
SystemPageData(as f32),
platform.ppt_platform_sppt(as u8),
"ppt_platform_sppt successfully set to {}",
"Setting ppt_platform_sppt failed"
);
set_ui_callbacks!(handle,
SystemPageData(as f32),
platform.nv_temp_target(as u8),
"nv_temp_target successfully set to {}",
"Setting nv_temp_target failed"
);
set_ui_callbacks!(handle,
SystemPageData(as f32),
platform.nv_dynamic_boost(as u8),
"nv_dynamic_boost successfully set to {}",
"Setting nv_dynamic_boost failed"
);
})
.unwrap();
});
}
fn decode_hex(s: &str) -> RgbaColor<u8> {
let s = s.trim_start_matches('#');
let c: Vec<u8> = (0..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap_or(164))
.collect();
RgbaColor {
alpha: 255,
red: *c.get(0).unwrap_or(&255),
green: *c.get(1).unwrap_or(&128),
blue: *c.get(2).unwrap_or(&32),
}
}
fn _rgb_hi(colour: Color) -> (f32, f32) {
let c1: RgbaColor<f32> = RgbaColor::from(colour);
let r = c1.red / 255.0;
let g = c1.green / 255.0;
let b = c1.blue / 255.0;
let min = r.min(g.min(b));
let max = r.max(g.max(b));
let delta = max - min;
let h = match delta == 0.0 {
true => 0.0,
false => {
if r == max {
(g - b) / delta
} else if g == max {
2.0 + (b - r) / delta
} else {
4.0 + (r - g) / delta
}
}
};
let h2 = ((h * 60.0) + 360.0) % 360.0;
let i = 0.2126 * c1.red + 0.7152 * c1.green + 0.0722 * c1.blue;
(h2, i)
}
fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
ui.global::<AuraPageData>().on_blend_colour(|c1, c2, f| {
let c1: RgbaColor<f32> = RgbaColor::from(c1);
let c2: RgbaColor<f32> = RgbaColor::from(c2);
let c1 = RgbaColor {
alpha: 1.0,
red: c1.red + (c2.red - c1.red) * f,
green: c1.green + (c2.green - c1.green) * f,
blue: c1.blue + (c2.blue - c1.blue) * f,
};
c1.into()
});
ui.global::<AuraPageData>().on_blend_lightness(|c1, f| {
let c1: RgbaColor<f32> = RgbaColor::from(c1);
let c = RgbaColor {
alpha: 1.0,
red: c1.red * f,
green: c1.green * f,
blue: c1.blue * f,
};
// dbg!(rgb_hi(c.into()));
c.into()
});
ui.global::<AuraPageData>().on_set_hex_from_colour(|c| {
format!("#{:02X}{:02X}{:02X}", c.red(), c.green(), c.blue()).into()
});
ui.global::<AuraPageData>()
.on_set_hex_to_colour(|s| decode_hex(s.as_str()).into());
let handle = ui.as_weak();
tokio::spawn(async move {
let conn = zbus::Connection::system().await.unwrap();
let aura = AuraProxy::builder(&conn)
.cache_properties(CacheProperties::Yes)
.build()
.await
.unwrap();
set_ui_props_async!(handle, aura, AuraPageData, brightness);
set_ui_props_async!(handle, aura, AuraPageData, led_mode);
set_ui_props_async!(handle, aura, AuraPageData, led_mode_data);
if let Ok(modes) = aura.supported_basic_modes().await {
log::debug!("Available LED modes {modes:?}");
handle
.upgrade_in_event_loop(move |handle| {
let m: Vec<i32> = modes.iter().map(|n| (*n).into()).collect();
handle
.global::<AuraPageData>()
.set_supported_basic_modes(m.as_slice().into());
// Get the translated names
let names = handle.global::<AuraPageData>().get_mode_names();
let res: Vec<SharedString> = names
.iter()
.enumerate()
.filter(|(n, _)| modes.contains(&(*n as i32).into()) && *n != 9)
.map(|(_, i)| i)
.collect();
handle
.global::<AuraPageData>()
.set_available_mode_names(res.as_slice().into());
})
.ok();
}
let proxy_copy = aura.clone();
handle
.upgrade_in_event_loop(move |handle| {
set_ui_callbacks!(handle,
AuraPageData(.into()),
aura.brightness(.into()),
"Keyboard LED brightness successfully set to {}",
"Setting keyboard LED brightness failed"
);
set_ui_callbacks!(handle,
AuraPageData(.into()),
aura.led_mode(.into()),
"Keyboard LED mode successfully set to {}",
"Setting keyboard LEDmode failed"
);
set_ui_callbacks!(handle,
AuraPageData(.into()),
aura.led_mode_data(.into()),
"Keyboard LED mode set to {:?}",
"Setting keyboard LED mode failed"
);
})
.ok();
// Need to update the UI if the mode changes
let handle_copy = handle.clone();
// spawn required since the while let never exits
tokio::spawn(async move {
let mut x = proxy_copy.receive_led_mode_data_changed().await;
use zbus::export::futures_util::StreamExt;
while let Some(e) = x.next().await {
if let Ok(out) = e.get().await {
handle_copy
.upgrade_in_event_loop(move |handle| {
handle
.global::<AuraPageData>()
.invoke_update_led_mode_data(out.into());
})
.ok();
}
}
});
});
}
fn setup_anime_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
let handle = ui.as_weak();
tokio::spawn(async move {
let conn = zbus::Connection::system().await.unwrap();
let anime = AnimeProxy::new(&conn).await.unwrap();
set_ui_props_async!(handle, anime, AnimePageData, brightness);
set_ui_props_async!(handle, anime, AnimePageData, builtins_enabled);
set_ui_props_async!(handle, anime, AnimePageData, enable_display);
set_ui_props_async!(handle, anime, AnimePageData, off_when_lid_closed);
set_ui_props_async!(handle, anime, AnimePageData, off_when_suspended);
set_ui_props_async!(handle, anime, AnimePageData, off_when_unplugged);
let builtins = anime.builtin_animations().await.unwrap_or_default();
handle
.upgrade_in_event_loop(move |handle| {
{
let global = handle.global::<AnimePageData>();
global.set_boot_anim(builtins.boot as i32);
global.set_awake_anim(builtins.awake as i32);
global.set_sleep_anim(builtins.sleep as i32);
global.set_shutdown_anim(builtins.shutdown as i32);
let handle_copy = handle.as_weak();
let anime_copy = anime.clone();
global.on_set_builtin_animations(move |boot, awake, sleep, shutdown| {
let handle_copy = handle_copy.clone();
let anime_copy = anime_copy.clone();
tokio::spawn(async move {
show_toast(
"Anime builtin animations changed".into(),
"Failed to set Anime builtin animations".into(),
handle_copy,
anime_copy
.set_builtin_animations(Animations {
boot: boot.into(),
awake: awake.into(),
sleep: sleep.into(),
shutdown: shutdown.into(),
})
.await,
);
});
});
let handle_copy = handle.as_weak();
let anime_copy = anime.clone();
tokio::spawn(async move {
let mut x = anime_copy.receive_builtin_animations_changed().await;
use zbus::export::futures_util::StreamExt;
while let Some(e) = x.next().await {
if let Ok(out) = e.get().await {
handle_copy
.upgrade_in_event_loop(move |handle| {
handle
.global::<AnimePageData>()
.set_boot_anim(out.boot.into());
handle
.global::<AnimePageData>()
.set_awake_anim(out.awake.into());
handle
.global::<AnimePageData>()
.set_sleep_anim(out.sleep.into());
handle
.global::<AnimePageData>()
.set_shutdown_anim(out.shutdown.into());
})
.ok();
}
}
});
}
set_ui_callbacks!(handle,
AnimePageData(.into()),
anime.brightness(.into()),
"Anime LED brightness successfully set to {}",
"Setting Anime LED brightness failed"
);
set_ui_callbacks!(
handle,
AnimePageData(),
anime.builtins_enabled(),
"Keyboard LED mode successfully set to {}",
"Setting keyboard LEDmode failed"
);
set_ui_callbacks!(
handle,
AnimePageData(),
anime.enable_display(),
"Anime display successfully set to {}",
"Setting Anime display failed"
);
set_ui_callbacks!(
handle,
AnimePageData(),
anime.off_when_lid_closed(),
"Anime off_when_lid_closed successfully set to {}",
"Setting Anime off_when_lid_closed failed"
);
set_ui_callbacks!(
handle,
AnimePageData(),
anime.off_when_suspended(),
"Anime off_when_suspended successfully set to {}",
"Setting Anime off_when_suspended failed"
);
set_ui_callbacks!(
handle,
AnimePageData(),
anime.off_when_unplugged(),
"Anime off_when_unplugged successfully set to {}",
"Setting Anime off_when_unplugged failed"
);
})
.unwrap();
});
}
fn show_toast(
success: SharedString,
fail: SharedString,
handle: Weak<MainWindow>,
result: zbus::Result<()>,
) {
match result {
Ok(_) => {
slint::invoke_from_event_loop(move || handle.unwrap().invoke_show_toast(success)).ok()
}
Err(e) => slint::invoke_from_event_loop(move || {
log::warn!("{fail}: {e}");
handle.unwrap().invoke_show_toast(fail)
})
.ok(),
};
}

View File

@@ -0,0 +1,539 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-03-02 10:44+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: rog-control-center/ui/pages/anime.slint:7
msgctxt "Anime Brightness"
msgid "Off"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:8
msgctxt "Anime Brightness"
msgid "Low"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:9
msgctxt "Anime Brightness"
msgid "Med"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:10
msgctxt "Anime Brightness"
msgid "High"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:30
msgctxt "AnimePageData"
msgid "Glitch Construction"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:30
msgctxt "AnimePageData"
msgid "Static Emergence"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:32
msgctxt "AnimePageData"
msgid "Binary Banner Scroll"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:32
msgctxt "AnimePageData"
msgid "Rog Logo Glitch"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:34
msgctxt "AnimePageData"
msgid "Banner Swipe"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:34
msgctxt "AnimePageData"
msgid "Starfield"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:36
msgctxt "AnimePageData"
msgid "Glitch Out"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:36
msgctxt "AnimePageData"
msgid "See Ya"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:58
msgctxt "Anime Brightness"
msgid "Brightness"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:74
msgctxt "PageAnime"
msgid "Enable display"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:82 rog-control-center/ui/pages/anime.slint:105
msgctxt "PageAnime"
msgid "Advanced"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:97
msgctxt "PageAnime"
msgid "Use built-in animations"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:155
msgctxt "PageAnime"
msgid "Advanced Anime Display : TODO!"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:159
msgctxt "Anime built-in selection"
msgid "Boot Animation"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:169
msgctxt "Anime built-in selection"
msgid "Running Animation"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:179
msgctxt "Anime built-in selection"
msgid "Sleep Animation"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:189
msgctxt "Anime built-in selection"
msgid "Shutdown Animation"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:230
msgctxt "PageAnime"
msgid "Advanced Display Settings"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:235
msgctxt "PageAnime"
msgid "Off when lid closed"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:244
msgctxt "PageAnime"
msgid "Off when suspended"
msgstr ""
#: rog-control-center/ui/pages/anime.slint:253
msgctxt "PageAnime"
msgid "Off when on battery"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:24
msgctxt "Aura brightness"
msgid "Off"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:25
msgctxt "Aura brightness"
msgid "Low"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:26
msgctxt "Aura brightness"
msgid "Med"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:27
msgctxt "Aura brightness"
msgid "High"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:33 rog-control-center/ui/pages/aura.slint:48
msgctxt "Basic aura mode"
msgid "Static"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:34 rog-control-center/ui/pages/aura.slint:49
msgctxt "Basic aura mode"
msgid "Breathe"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:35 rog-control-center/ui/pages/aura.slint:50
msgctxt "Basic aura mode"
msgid "Strobe"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:36
msgctxt "Basic aura mode"
msgid "Rainbow"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:37
msgctxt "Basic aura mode"
msgid "Star"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:38
msgctxt "Basic aura mode"
msgid "Rain"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:39
msgctxt "Basic aura mode"
msgid "Highlight"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:40
msgctxt "Basic aura mode"
msgid "Laser"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:41
msgctxt "Basic aura mode"
msgid "Ripple"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:42
msgctxt "Basic aura mode"
msgid "Nothing"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:43
msgctxt "Basic aura mode"
msgid "Pulse"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:44
msgctxt "Basic aura mode"
msgid "Comet"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:45
msgctxt "Basic aura mode"
msgid "Flash"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:59
msgctxt "Aura zone"
msgid "None"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:60
msgctxt "Aura zone"
msgid "Key1"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:61
msgctxt "Aura zone"
msgid "Key2"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:62
msgctxt "Aura zone"
msgid "Key3"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:63
msgctxt "Aura zone"
msgid "Key4"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:64
msgctxt "Aura zone"
msgid "Logo"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:65
msgctxt "Aura zone"
msgid "Lightbar Left"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:66
msgctxt "Aura zone"
msgid "Lightbar Right"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:71
msgctxt "Aura direction"
msgid "Right"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:72
msgctxt "Aura direction"
msgid "Left"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:73
msgctxt "Aura direction"
msgid "Up"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:74
msgctxt "Aura direction"
msgid "Down"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:79
msgctxt "Aura speed"
msgid "Low"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:80
msgctxt "Aura speed"
msgid "Medium"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:81
msgctxt "Aura speed"
msgid "High"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:128
msgctxt "PageAura"
msgid "Brightness"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:139
msgctxt "PageAura"
msgid "Aura mode"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:156
msgctxt "PageAura"
msgid "Colour 1"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:187
msgctxt "PageAura"
msgid "Colour 2"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:224
msgctxt "PageAura"
msgid "Zone"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:244
msgctxt "PageAura"
msgid "Direction"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:264
msgctxt "PageAura"
msgid "Speed"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:282
msgctxt "PageAura"
msgid "Apply"
msgstr ""
#: rog-control-center/ui/pages/system.slint:27
msgctxt "SystemPageData"
msgid "Balanced"
msgstr ""
#: rog-control-center/ui/pages/system.slint:27 rog-control-center/ui/pages/system.slint:32
msgctxt "SystemPageData"
msgid "Performance"
msgstr ""
#: rog-control-center/ui/pages/system.slint:27
msgctxt "SystemPageData"
msgid "Quiet"
msgstr ""
#: rog-control-center/ui/pages/system.slint:31
msgctxt "SystemPageData"
msgid "Default"
msgstr ""
#: rog-control-center/ui/pages/system.slint:33
msgctxt "SystemPageData"
msgid "BalancePerformance"
msgstr ""
#: rog-control-center/ui/pages/system.slint:34
msgctxt "SystemPageData"
msgid "BalancePower"
msgstr ""
#: rog-control-center/ui/pages/system.slint:35
msgctxt "SystemPageData"
msgid "Power"
msgstr ""
#: rog-control-center/ui/pages/system.slint:116
msgctxt "PageSystem"
msgid "Base system settings"
msgstr ""
#: rog-control-center/ui/pages/system.slint:121
msgctxt "PageSystem"
msgid "Charge limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:133
msgctxt "PageSystem"
msgid "Throttle Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:143
msgctxt "PageSystem"
msgid "Advanced"
msgstr ""
#: rog-control-center/ui/pages/system.slint:155
msgctxt "PageSystem"
msgid "Panel Overdrive"
msgstr ""
#: rog-control-center/ui/pages/system.slint:163
msgctxt "PageSystem"
msgid "MiniLED Mode"
msgstr ""
#: rog-control-center/ui/pages/system.slint:181
msgctxt "PageSystem"
msgid "System performance settings"
msgstr ""
#: rog-control-center/ui/pages/system.slint:186
msgctxt "ppt_pl1_spl"
msgid "ppt_pl1_spl"
msgstr ""
#: rog-control-center/ui/pages/system.slint:196
msgctxt "ppt_pl2_sppt"
msgid "ppt_pl2_sppt"
msgstr ""
#: rog-control-center/ui/pages/system.slint:206
msgctxt "ppt_fppt"
msgid "ppt_fppt"
msgstr ""
#: rog-control-center/ui/pages/system.slint:216
msgctxt "ppt_apu_sppt"
msgid "ppt_apu_sppt"
msgstr ""
#: rog-control-center/ui/pages/system.slint:225
msgctxt "ppt_platform_sppt"
msgid "ppt_platform_sppt"
msgstr ""
#: rog-control-center/ui/pages/system.slint:235
msgctxt "nv_dynamic_boost"
msgid "nv_dynamic_boost"
msgstr ""
#: rog-control-center/ui/pages/system.slint:244
msgctxt "nv_temp_target"
msgid "nv_temp_target"
msgstr ""
#: rog-control-center/ui/pages/system.slint:290
msgctxt "PageSystem"
msgid "Energy Performance Preference linked to Throttle Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:294
msgctxt "PageSystem"
msgid "Change EPP based on Throttle Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:302
msgctxt "PageSystem"
msgid "EPP for Balanced Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:312
msgctxt "PageSystem"
msgid "EPP for Performance Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:322
msgctxt "PageSystem"
msgid "EPP for Quiet Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:340
msgctxt "PageSystem"
msgid "Throttle Policy for power state"
msgstr ""
#: rog-control-center/ui/pages/system.slint:344
msgctxt "PageSystem"
msgid "Throttle Policy on Battery"
msgstr ""
#: rog-control-center/ui/pages/system.slint:354
msgctxt "PageSystem"
msgid "Throttle Policy on AC"
msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:32
msgctxt "PageAppSettings"
msgid "Run in background after closing"
msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:41
msgctxt "PageAppSettings"
msgid "Start app in background (UI closed)"
msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:53
msgctxt "PageAppSettings"
msgid "Enable system tray icon"
msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:62
msgctxt "PageAppSettings"
msgid "Enable change notifications"
msgstr ""
#: rog-control-center/ui/main_window.slint:42
msgctxt "MainWindow"
msgid "ROG"
msgstr ""
#: rog-control-center/ui/main_window.slint:44
msgctxt "Menu1"
msgid "System Control"
msgstr ""
#: rog-control-center/ui/main_window.slint:45
msgctxt "Menu2"
msgid "Keyboard Aura"
msgstr ""
#: rog-control-center/ui/main_window.slint:46
msgctxt "Menu3"
msgid "AniMe Matrix"
msgstr ""
#: rog-control-center/ui/main_window.slint:47
msgctxt "Menu4"
msgid "Fan Curves"
msgstr ""
#: rog-control-center/ui/main_window.slint:48
msgctxt "Menu5"
msgid "App Settings"
msgstr ""
#: rog-control-center/ui/main_window.slint:49
msgctxt "Menu6"
msgid "About"
msgstr ""

View File

@@ -1,84 +1,110 @@
import { VerticalBox , StandardButton, Button} from "std-widgets.slint"; import { VerticalBox , StandardButton, Button, HorizontalBox, ComboBox, Switch, Slider} from "std-widgets.slint";
import { Theme } from "globals.slint"; import { Theme } from "globals.slint";
export component SquareImageButton inherits Rectangle { export component RogItem inherits Rectangle {
callback clicked; background: Theme.background-color;
in-out property <image> img; border-color: Colors.black;
border-radius: 7px; border-width: 3px;
border-width: 2px; border-radius: 10px;
border-color: Theme.control-outline; }
background: Theme.image-button-background;
touch := TouchArea {
clicked => {
root.clicked();
export component SystemSlider inherits RogItem {
in property <string> text;
in-out property <float> value;
in-out property <float> minimum;
in-out property <float> maximum;
callback released(int);
HorizontalLayout {
HorizontalBox {
width: 30%;
alignment: LayoutAlignment.start;
Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Theme.text-foreground-color;
text <=> root.text;
}
Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Theme.text-foreground-color;
text: ": \{Math.round(root.value)}";
}
} }
}
Image { HorizontalBox {
height: 90%; // alignment: LayoutAlignment.end;
width: 90%; padding-right: 20px;
x: (parent.width - self.width) / 2; Slider {
y: (parent.height - self.height) / 2; maximum: root.maximum;
source <=> root.img; minimum: root.minimum;
image-fit: contain; value <=> root.value;
// colorize: Theme.control-secondary; released => {
root.released(Math.round(root.value))
}
}
}
} }
} }
export component RoundImageButton inherits Rectangle { export component SystemToggle inherits RogItem {
callback clicked; in property <string> text;
in-out property <image> img; in-out property <bool> checked;
in property <length> size; callback toggled(bool);
width: self.size; HorizontalLayout {
height: self.size; HorizontalBox {
border-radius: root.width / 2; alignment: LayoutAlignment.start;
border-width: 6px; Text {
border-color: Theme.control-outline; font-size: 16px;
background: Theme.image-button-background; vertical-alignment: TextVerticalAlignment.center;
touch := TouchArea { color: Theme.text-foreground-color;
clicked => { text <=> root.text;
root.clicked(); }
} }
}
Image { HorizontalBox {
height: 60%; alignment: LayoutAlignment.end;
width: 60%; padding-right: 20px;
x: (parent.width - self.width) / 2; Switch {
y: (parent.height - self.height) / 2; checked <=> root.checked;
source <=> root.img; toggled => {
image-fit: contain; root.toggled(root.checked)
// colorize: Theme.control-secondary; }
}
}
} }
} }
export component SquareCharButton inherits Rectangle { export component SystemDropdown inherits RogItem {
callback clicked; in property <string> text;
in-out property <string> char; in-out property <int> current_index;
border-radius: 7px; in-out property <string> current_value;
border-width: 2px; in-out property <[string]> model;
border-color: Theme.control-outline; callback selected(int);
background: Theme.image-button-background; HorizontalLayout {
touch := TouchArea { HorizontalBox {
clicked => { alignment: LayoutAlignment.start;
root.clicked(); Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Theme.text-foreground-color;
text <=> root.text;
}
} }
}
Text { HorizontalBox {
// height: 90%; alignment: LayoutAlignment.end;
// width: 90%; padding-right: 20px;
x: (parent.width - self.width) / 2; ComboBox {
y: (parent.height - self.height) / 2; model <=> root.model;
text: char; current-index <=> root.current_index;
font-size: 28px; current-value <=> root.current_value;
font-weight: 900; selected => {
horizontal-alignment: center; root.selected(root.current_index)
vertical-alignment: center; }
color: Theme.control-foreground; }
}
} }
} }
@@ -87,33 +113,25 @@ export component ValueBar inherits Rectangle {
in property <float> value: 0.0; in property <float> value: 0.0;
in property <float> min: 0.0; in property <float> min: 0.0;
in property <float> max: 1.0; in property <float> max: 1.0;
function percentage(min: float, max: float, value: float) -> float{ function percentage(min: float, max: float, value: float) -> float {
if (min < 0.0 && max > 0.0) { if (min < 0.0 && max > 0.0) {
// do a percentage of each half as 0-50% // do a percentage of each half as 0-50%
if (value >= max + min) { if (value >= max + min) {
return (value - (max + min) / 2) / (max - min); return (value - (max + min) / 2) / (max - min);
} }
return 0.50 - (value - (min - max) / 2) / (max - min); return 0.50 - (value - (min - max) / 2) / (max - min);
} }
return (value - min) / (max - min); return (value - min) / (max - min);
} }
function set_x(min: float, max: float, value: float, width: length) -> length {
function set_x(min: float, max: float, value: float, width: length) -> length{
if (min < 0.0 && max > 0.0) { if (min < 0.0 && max > 0.0) {
if (value < max + min) { if (value < max + min) {
return width / 2 - width * (percentage(min, max, value)); return width / 2 - width * (percentage(min, max, value));
} }
return width / 2; return width / 2;
} }
return 0; return 0;
} }
Rectangle { Rectangle {
border-radius: 3px; border-radius: 3px;
background: Theme.neutral-box; background: Theme.neutral-box;
@@ -135,54 +153,6 @@ export component ValueBar inherits Rectangle {
} }
} }
// Single direction spinbox
export component SpinBoxUni inherits Rectangle {
in-out property <int> value;
in property <int> minimum;
in property <int> maximum: 100;
height: 32px;
HorizontalLayout {
spacing: 12px;
padding: 0;
SquareCharButton {
width: root.height - parent.padding * 2;
char: "-";
clicked => {
if (root.value > root.minimum) {
root.value -= 1;
}
}
}
Rectangle {
border-radius: 3px;
border-width: 2px;
border-color: Theme.control-outline;
// TODO: replace with visual min/max drawing
Text {
width: 100%;
height: 100%;
vertical-alignment: center;
horizontal-alignment: center;
text: root.value;
color: Theme.control-foreground;
}
}
SquareCharButton {
width: root.height - parent.padding * 2;
char: "+";
clicked => {
if (root.value < root.maximum) {
root.value += 1;
}
}
}
}
}
export component PopupNotification { export component PopupNotification {
in property <string> heading; in property <string> heading;
in property <string> content; in property <string> content;
@@ -238,7 +208,5 @@ export component PopupNotification {
public function show() { public function show() {
_p.show(); _p.show();
} }
} }

View File

@@ -5,15 +5,15 @@ struct ButtonColours {
} }
export global AppSize { export global AppSize {
out property <length> width: 800px; out property <length> width: 900px;
out property <length> height: 480px; out property <length> height: 500px;
} }
export global Theme { export global Theme {
out property <color> window-background: #000000; out property <color> window-background: #000000;
out property <color> neutral-box: #BDC0D1; out property <color> neutral-box: #BDC0D1;
// The background colour of pages and bars // The background colour of pages and bars
out property <color> background-color: root.dark-mode ? #12387b : white; out property <color> background-color: root.dark-mode ? #3a127b : white;
out property <color> text-foreground-color: root.dark-mode ? #F4F6FF : black; out property <color> text-foreground-color: root.dark-mode ? #F4F6FF : black;
out property <color> secondary-foreground-color: root.dark-mode ? #C1C3CA : #6C6E7A; out property <color> secondary-foreground-color: root.dark-mode ? #C1C3CA : #6C6E7A;
out property <color> image-button-background: root.dark-mode ? root.window-background : white; out property <color> image-button-background: root.dark-mode ? root.window-background : white;

View File

@@ -1,45 +1,63 @@
import { Button, VerticalBox } from "std-widgets.slint"; import { Button, VerticalBox } from "std-widgets.slint";
import { SpinBoxUni, ValueBar, SquareImageButton, RoundImageButton } from "common_widgets.slint";
import { Theme, AppSize } from "globals.slint"; import { Theme, AppSize } from "globals.slint";
import { PageSystem, AvailableSystemProperties, SystemPage } from "pages/system.slint"; import { PageSystem, AvailableSystemProperties, SystemPageData } from "pages/system.slint";
import { SideBar } from "widgets/sidebar.slint"; import { SideBar } from "widgets/sidebar.slint";
import { PageAbout } from "pages/about.slint"; import { PageAbout } from "pages/about.slint";
import { PageGpu } from "pages/gpu.slint";
import { PageFans } from "pages/fans.slint"; import { PageFans } from "pages/fans.slint";
import { PageAnime } from "pages/anime.slint"; import { PageAnime, AnimePageData } from "pages/anime.slint";
import { PageAura } from "pages/aura.slint"; import { PageAura, AuraPageData, AuraEffect } from "pages/aura.slint";
import { PageAppSettings, AppSettingsPageData } from "pages/app_settings.slint";
export { AppSize, Theme, AvailableSystemProperties, SystemPage } export { AppSize, AuraEffect, Theme, AvailableSystemProperties, SystemPageData, AuraPageData, AnimePageData, AppSettingsPageData }
export component MainWindow inherits Window { export component MainWindow inherits Window {
default-font-family: "DejaVu Sans"; default-font-family: "DejaVu Sans";
in property <[bool]> sidebar_items_avilable: [true, true, true, true, true, true];
private property <bool> show-notif; private property <bool> show-notif;
private property <bool> fade-cover; private property <bool> fade-cover;
private property <bool> toast: false;
private property <string> toast_text: "I show when something is waiting";
callback show_toast(string);
show_toast(text) => {
toast = text != "";
toast_text = text;
}
callback exit-app(); callback exit-app();
callback show-notification(bool); callback show-notification(bool);
show-notification(yes) => { show-notification(yes) => {
show-notif = yes; show-notif = yes;
fade-cover = yes; fade-cover = yes;
} }
in-out property <bool> charge-available; min-height: AppSize.height;
min-width: AppSize.width;
height: AppSize.height; background: Colors.black;
width: AppSize.width;
background: Colors.orange;
HorizontalLayout { HorizontalLayout {
padding: 0px; padding: 0px;
side-bar := SideBar {
title: @tr("ROG"); VerticalLayout {
model: [ side-bar := SideBar {
@tr("Menu" => "System Control"), title: @tr("ROG");
@tr("Menu" => "Keyboard Aura"), model: [
@tr("Menu" => "AniMe Matrix"), @tr("Menu1" => "System Control"),
@tr("Menu" => "Fan Curves"), @tr("Menu2" => "Keyboard Aura"),
@tr("Menu" => "GPU Control"), @tr("Menu3" => "AniMe Matrix"),
@tr("Menu" => "About"), @tr("Menu4" => "Fan Curves"),
]; @tr("Menu5" => "App Settings"),
@tr("Menu6" => "About"),
];
available: root.sidebar_items_avilable;
}
Button {
max-height: 20px;
text: "Quit";
clicked => {
root.exit-app();
}
}
} }
Rectangle { Rectangle {
@@ -61,7 +79,7 @@ export component MainWindow inherits Window {
width: root.width - side-bar.width; width: root.width - side-bar.width;
} }
if(side-bar.current-item == 4): PageGpu { if(side-bar.current-item == 4): PageAppSettings {
width: root.width - side-bar.width; width: root.width - side-bar.width;
} }
@@ -85,10 +103,33 @@ export component MainWindow inherits Window {
// toolbar-dropdown.close(); // toolbar-dropdown.close();
if (show-notif) { if (show-notif) {
show-notif = false; show-notif = false;
} }
fade-cover = false; fade-cover = false;
}
}
}
if toast: Rectangle {
x: 0px;
y: 0px;
width: root.width;
height: 32px;
opacity: 0.8;
TouchArea {
height: 100%;
width: 100%;
clicked => {
toast = false;
}
}
Rectangle {
height: 100%;
width: 100%;
background: #1a043d;
Text {
color: Theme.text-foreground-color;
text: root.toast_text;
} }
} }
} }
@@ -105,7 +146,6 @@ export component MainWindow inherits Window {
clicked => { clicked => {
show-notif = false; show-notif = false;
exit-app(); exit-app();
} }
} }

View File

@@ -3,16 +3,18 @@ import { Theme } from "../globals.slint";
import { AboutSlint } from "std-widgets.slint"; import { AboutSlint } from "std-widgets.slint";
export component PageAbout inherits VerticalLayout { export component PageAbout inherits VerticalLayout {
Rectangle { padding: 10px;
clip: true; spacing: 10px;
// TODO: slow with border-radius Text {
padding: 8px; vertical-alignment: TextVerticalAlignment.center;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2; horizontal-alignment: TextHorizontalAlignment.center;
// TODO: border-radius: 8px; text: "A UI for asusctl made with slint";
mainview := VerticalLayout { font-size: 22px;
padding: 10px; }
spacing: 10px; Text {
AboutSlint {} vertical-alignment: TextVerticalAlignment.center;
} horizontal-alignment: TextHorizontalAlignment.center;
text: "Work in progress";
font-size: 22px;
} }
} }

View File

@@ -1,49 +1,273 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint"; import { Theme } from "../globals.slint";
import { SystemDropdown, SystemToggle } from "../common_widgets.slint";
import { GroupBox, VerticalBox, Button, HorizontalBox } from "std-widgets.slint";
export component PageAnime inherits VerticalLayout { export global AnimePageData {
Rectangle { in-out property <[string]> brightness_names: [
clip: true; @tr("Anime Brightness" => "Off"),
// TODO: slow with border-radius @tr("Anime Brightness" => "Low"),
@tr("Anime Brightness" => "Med"),
@tr("Anime Brightness" => "High"),
];
in-out property <int> brightness;
callback set_brightness(int);
in-out property <bool> builtins_enabled;
callback set_builtins_enabled(bool);
in-out property <bool> enable_display;
callback set_enable_display(bool);
in-out property <bool> off_when_lid_closed;
callback set_off_when_lid_closed(bool);
in-out property <bool> off_when_suspended;
callback set_off_when_suspended(bool);
in-out property <bool> off_when_unplugged;
callback set_off_when_unplugged(bool);
in-out property <[string]> boot_anim_choices: [@tr("Glitch Construction"), @tr("Static Emergence")];
in property <int> boot_anim: 0;
in-out property <[string]> awake_anim_choices: [@tr("Binary Banner Scroll"), @tr("Rog Logo Glitch")];
in property <int> awake_anim: 0;
in-out property <[string]> sleep_anim_choices: [@tr("Banner Swipe"), @tr("Starfield")];
in property <int> sleep_anim: 0;
in-out property <[string]> shutdown_anim_choices: [@tr("Glitch Out"), @tr("See Ya")];
in property <int> shutdown_anim: 0;
callback set_builtin_animations(int, int, int, int);
}
export component PageAnime inherits Rectangle {
property <bool> show_fade_cover: false;
property <bool> show_display_advanced: false;
property <bool> show_builtin_advanced: false;
clip: true;
// TODO: slow with border-radius
padding: 8px; padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2; // height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px; // TODO: border-radius: 8px;
mainview := VerticalLayout { VerticalLayout {
padding: 10px; padding: 10px;
spacing: 10px;
HorizontalLayout {
spacing: 10px; spacing: 10px;
ValueBar { max-height: 32px;
height: 40px; SystemDropdown {
value: 10.5; text: @tr("Anime Brightness" => "Brightness");
min: 0.0; current_index <=> AnimePageData.brightness;
max: 100.0; current_value: AnimePageData.brightness_names[AnimePageData.brightness];
model <=> AnimePageData.brightness_names;
selected => {
self.current_value = AnimePageData.brightness_names[AnimePageData.brightness];
AnimePageData.set_brightness(AnimePageData.brightness)
}
}
}
HorizontalLayout {
spacing: 10px;
max-height: 32px;
alignment: LayoutAlignment.stretch;
SystemToggle {
text: @tr("Enable display");
checked <=> AnimePageData.enable_display;
toggled => {
AnimePageData.set_enable_display(AnimePageData.enable_display)
}
} }
ValueBar { Button {
height: 40px; text: @tr("Advanced");
value: -70; width: 20%;
min: -100; enabled <=> AnimePageData.enable_display;
max: 0; clicked => {
root.show_fade_cover = true;
root.show_display_advanced = true;
}
}
}
HorizontalLayout {
spacing: 10px;
max-height: 32px;
alignment: LayoutAlignment.stretch;
SystemToggle {
text: @tr("Use built-in animations");
checked <=> AnimePageData.builtins_enabled;
toggled => {
AnimePageData.set_builtins_enabled(AnimePageData.builtins_enabled)
}
} }
ValueBar { Button {
height: 80px; text: @tr("Advanced");
value: 40; width: 20%;
min: -50; enabled <=> AnimePageData.builtins_enabled;
max: 50; clicked => {
root.show_fade_cover = true;
root.show_builtin_advanced = true;
}
} }
}
}
ValueBar { if root.show_fade_cover: Rectangle {
height: 80px; width: 100%;
value: -40; height: 100%;
min: -50; background: Theme.background-color;
max: 50; opacity: 0.8;
TouchArea {
height: 100%;
width: 100%;
// clicked => {
// // toolbar-dropdown.close();
// if (root.show_display_advanced) {
// root.show_display_advanced = false;
// }
// if (root.show_builtin_advanced) {
// root.show_builtin_advanced = false;
// }
// root.show_fade_cover = false;
// }
}
}
if root.show_builtin_advanced: Rectangle {
x: 0;
width: 100%;
height: 100%;
opacity: 1;
VerticalLayout {
padding: 50px;
spacing: 10px;
GroupBox {
height: 100px;
VerticalBox {
spacing: 10px;
alignment: LayoutAlignment.start;
Text {
font-size: 18px;
color: Theme.text-foreground-color;
horizontal-alignment: TextHorizontalAlignment.center;
text: @tr("Advanced Anime Display : TODO!");
}
SystemDropdown {
text: @tr("Anime built-in selection" => "Boot Animation");
current_index <=> AnimePageData.boot_anim;
current_value: AnimePageData.boot_anim_choices[AnimePageData.boot_anim];
model <=> AnimePageData.boot_anim_choices;
selected => {
AnimePageData.set_builtin_animations(AnimePageData.boot_anim, AnimePageData.awake_anim, AnimePageData.sleep_anim, AnimePageData.shutdown_anim)
}
}
SystemDropdown {
text: @tr("Anime built-in selection" => "Running Animation");
current_index <=> AnimePageData.awake_anim;
current_value: AnimePageData.awake_anim_choices[AnimePageData.awake_anim];
model <=> AnimePageData.awake_anim_choices;
selected => {
AnimePageData.set_builtin_animations(AnimePageData.boot_anim, AnimePageData.awake_anim, AnimePageData.sleep_anim, AnimePageData.shutdown_anim)
}
}
SystemDropdown {
text: @tr("Anime built-in selection" => "Sleep Animation");
current_index <=> AnimePageData.sleep_anim;
current_value: AnimePageData.sleep_anim_choices[AnimePageData.sleep_anim];
model <=> AnimePageData.sleep_anim_choices;
selected => {
AnimePageData.set_builtin_animations(AnimePageData.boot_anim, AnimePageData.awake_anim, AnimePageData.sleep_anim, AnimePageData.shutdown_anim)
}
}
SystemDropdown {
text: @tr("Anime built-in selection" => "Shutdown Animation");
current_index <=> AnimePageData.shutdown_anim;
current_value: AnimePageData.shutdown_anim_choices[AnimePageData.shutdown_anim];
model <=> AnimePageData.shutdown_anim_choices;
selected => {
AnimePageData.set_builtin_animations(AnimePageData.boot_anim, AnimePageData.awake_anim, AnimePageData.sleep_anim, AnimePageData.shutdown_anim)
}
}
}
} }
}
ValueBar { Button {
height: 80px; x: root.width - self.width - 6px;
value: -40; y: 6px;
min: -50; text: "X";
max: 50; height: 40px;
clicked => {
root.show_builtin_advanced = false;
root.show_fade_cover = false;
}
}
}
if root.show_display_advanced: Rectangle {
width: 100%;
height: 100%;
opacity: 1;
VerticalLayout {
padding: 50px;
spacing: 10px;
GroupBox {
height: 100px;
VerticalBox {
spacing: 10px;
alignment: LayoutAlignment.start;
Text {
font-size: 18px;
color: Theme.text-foreground-color;
horizontal-alignment: TextHorizontalAlignment.center;
text: @tr("Advanced Display Settings");
}
SystemToggle {
max-height: 42px;
text: @tr("Off when lid closed");
checked <=> AnimePageData.off_when_lid_closed;
toggled => {
AnimePageData.set_off_when_lid_closed(AnimePageData.off_when_lid_closed)
}
}
SystemToggle {
max-height: 42px;
text: @tr("Off when suspended");
checked <=> AnimePageData.off_when_suspended;
toggled => {
AnimePageData.set_off_when_suspended(AnimePageData.off_when_suspended)
}
}
SystemToggle {
max-height: 42px;
text: @tr("Off when on battery");
checked <=> AnimePageData.off_when_unplugged;
toggled => {
AnimePageData.set_off_when_unplugged(AnimePageData.off_when_unplugged)
}
}
}
}
}
Button {
x: root.width - self.width - 6px;
y: 6px;
text: "X";
height: 40px;
clicked => {
root.show_display_advanced = false;
root.show_fade_cover = false;
} }
} }
} }

View File

@@ -0,0 +1,75 @@
import { Theme } from "../globals.slint";
import { SystemToggle } from "../common_widgets.slint";
export global AppSettingsPageData {
in-out property <bool> run_in_background;
callback set_run_in_background(bool);
in-out property <bool> startup_in_background;
callback set_startup_in_background(bool);
in-out property <bool> enable_tray_icon;
callback set_enable_tray_icon(bool);
in-out property <bool> enable_notifications;
callback set_enable_notifications(bool);
}
export component PageAppSettings inherits VerticalLayout {
Rectangle {
clip: true;
// TODO: slow with border-radius
padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px;
mainview := VerticalLayout {
padding: 10px;
spacing: 10px;
HorizontalLayout {
spacing: 10px;
max-height: 32px;
SystemToggle {
text: @tr("Run in background after closing");
checked <=> AppSettingsPageData.run_in_background;
toggled => {
AppSettingsPageData.set_run_in_background(AppSettingsPageData.run_in_background)
}
}
SystemToggle {
width: parent.width * 1px / 2px;
text: @tr("Start app in background (UI closed)");
checked <=> AppSettingsPageData.startup_in_background;
toggled => {
AppSettingsPageData.set_run_in_background(AppSettingsPageData.startup_in_background)
}
}
}
HorizontalLayout {
max-height: 32px;
spacing: 10px;
SystemToggle {
text: @tr("Enable system tray icon");
checked <=> AppSettingsPageData.enable_tray_icon;
toggled => {
AppSettingsPageData.set_enable_tray_icon(AppSettingsPageData.enable_tray_icon)
}
}
SystemToggle {
width: parent.width * 1px / 2px;
text: @tr("Enable change notifications");
checked <=> AppSettingsPageData.enable_notifications;
toggled => {
AppSettingsPageData.set_enable_notifications(AppSettingsPageData.enable_notifications)
}
}
}
Text {
text: "TODO";
}
}
}
}

View File

@@ -1,50 +1,290 @@
import { ValueBar } from "../common_widgets.slint"; import { SystemDropdown, RogItem } from "../common_widgets.slint";
import { Button, ComboBox, VerticalBox, GroupBox } from "std-widgets.slint";
import { StyleMetrics, Slider, HorizontalBox, TextEdit, SpinBox, LineEdit } from "std-widgets.slint";
import { ColorPicker, ColourSlider } from "../widgets/colour_picker.slint";
import { Theme } from "../globals.slint"; import { Theme } from "../globals.slint";
export struct AuraEffect {
/// The effect type
mode: int,
/// `AuraZone::None` for no zone or zoneless keyboards
zone: int,
/// Primary colour for all modes
colour1: color,
/// Secondary colour in some modes like Breathing or Stars
colour2: color,
/// One of three speeds for modes that support speed (most that animate)
speed: int,
/// Up, down, left, right. Only Rainbow mode seems to use this
direction: int,
}
export global AuraPageData {
in-out property <[string]> brightness_names: [
@tr("Aura brightness" => "Off"),
@tr("Aura brightness" => "Low"),
@tr("Aura brightness" => "Med"),
@tr("Aura brightness" => "High"),
];
in-out property <int> brightness;
callback set_brightness(int);
in-out property <[string]> mode_names: [
@tr("Basic aura mode" => "Static"),
@tr("Basic aura mode" => "Breathe"),
@tr("Basic aura mode" => "Strobe"),
@tr("Basic aura mode" => "Rainbow"),
@tr("Basic aura mode" => "Star"),
@tr("Basic aura mode" => "Rain"),
@tr("Basic aura mode" => "Highlight"),
@tr("Basic aura mode" => "Laser"),
@tr("Basic aura mode" => "Ripple"),
@tr("Basic aura mode" => "Nothing"),
@tr("Basic aura mode" => "Pulse"),
@tr("Basic aura mode" => "Comet"),
@tr("Basic aura mode" => "Flash"),
];
in-out property <[string]> available_mode_names: [
@tr("Basic aura mode" => "Static"),
@tr("Basic aura mode" => "Breathe"),
@tr("Basic aura mode" => "Strobe"),
];
in-out property <int> current_available_mode: 0;
in-out property <[int]> supported_basic_modes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12];
in-out property <int> led_mode;
callback set_led_mode(int);
in-out property <[string]> zone_names: [
@tr("Aura zone" => "None"),
@tr("Aura zone" => "Key1"),
@tr("Aura zone" => "Key2"),
@tr("Aura zone" => "Key3"),
@tr("Aura zone" => "Key4"),
@tr("Aura zone" => "Logo"),
@tr("Aura zone" => "Lightbar Left"),
@tr("Aura zone" => "Lightbar Right"),
];
in-out property <int> zone;
in-out property <[string]> direction_names: [
@tr("Aura direction" => "Right"),
@tr("Aura direction" => "Left"),
@tr("Aura direction" => "Up"),
@tr("Aura direction" => "Down"),
];
in-out property <int> direction;
in-out property <[string]> speed_names: [
@tr("Aura speed" => "Low"),
@tr("Aura speed" => "Medium"),
@tr("Aura speed" => "High"),
];
in-out property <int> speed;
in-out property <AuraEffect> led_mode_data: {
mode: 0,
zone: 0,
colour1: Colors.aquamarine,
colourbox1: Colors.aquamarine,
colour2: Colors.hotpink,
colourbox2: Colors.hotpink,
speed: 0,
direction: 0,
};
callback set_led_mode_data(AuraEffect);
in-out property <color> color1;
in-out property <brush> colorbox1;
in-out property <color> color2;
in-out property <brush> colorbox2;
callback update_led_mode_data(AuraEffect);
update_led_mode_data(data) => {
led_mode_data = data;
current_available_mode = data.mode;
zone = data.zone;
speed = data.speed;
direction = data.direction;
color1 = data.colour1;
color2 = data.colour2;
colorbox1 = data.colour1;
colorbox2 = data.colour2;
}
callback blend_colour(color, color, float) -> color;
callback blend_lightness(color, float) -> color;
callback set_hex_from_colour(color) -> string;
callback set_hex_to_colour(string) -> color;
}
export component PageAura inherits VerticalLayout { export component PageAura inherits VerticalLayout {
Rectangle { padding: 10px;
clip: true; spacing: 10px;
// TODO: slow with border-radius alignment: LayoutAlignment.start;
padding: 8px; HorizontalLayout {
// height: parent.height - infobar.height - mainview.padding - self.padding * 2; spacing: 10px;
// TODO: border-radius: 8px; SystemDropdown {
mainview := VerticalLayout { text: @tr("Brightness");
padding: 10px; current_index <=> AuraPageData.brightness;
spacing: 10px; current_value: AuraPageData.brightness_names[self.current-index];
ValueBar { model <=> AuraPageData.brightness_names;
height: 40px; selected => {
value: 10.5; AuraPageData.set_brightness(AuraPageData.brightness)
min: 0.0;
max: 100.0;
} }
}
ValueBar { SystemDropdown {
height: 40px; width: parent.width * 1px / 2px;
value: -70; text: @tr("Aura mode");
min: -100; current_index <=> AuraPageData.current_available_mode;
max: 0; current_value: AuraPageData.available_mode_names[self.current-index];
} model <=> AuraPageData.available_mode_names;
selected => {
ValueBar { AuraPageData.led_mode_data.mode = AuraPageData.current_available_mode;
height: 80px; self.current_value = AuraPageData.available_mode_names[self.current-index];
value: 40; AuraPageData.set_led_mode(AuraPageData.current_available_mode);
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
} }
} }
} }
RogItem {
HorizontalLayout {
spacing: 10px;
VerticalBox {
Text {
text: @tr("Colour 1");
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
}
HorizontalBox {
ColourSlider {
final_colour <=> AuraPageData.color1;
colourbox <=> AuraPageData.colorbox1;
set_hex_from_colour(c1) => {
return AuraPageData.set_hex_from_colour(c1);
}
blend_colour(c1, c2, f) => {
return AuraPageData.blend_colour(c1, c2, f);
}
blend_lightness(c1, f) => {
return AuraPageData.blend_lightness(c1, f);
}
hex_to_colour(s) => {
return AuraPageData.set_hex_to_colour(s);
}
init => {
self.colourbox = AuraPageData.led_mode_data.colour1;
self.final_colour = AuraPageData.led_mode_data.colour1;
}
}
}
}
VerticalBox {
Text {
text: @tr("Colour 2");
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
}
HorizontalBox {
ColourSlider {
final_colour <=> AuraPageData.color2;
colourbox <=> AuraPageData.colorbox2;
set_hex_from_colour(c1) => {
return AuraPageData.set_hex_from_colour(c1);
}
blend_colour(c1, c2, f) => {
return AuraPageData.blend_colour(c1, c2, f);
}
blend_lightness(c1, f) => {
return AuraPageData.blend_lightness(c1, f);
}
hex_to_colour(s) => {
return AuraPageData.set_hex_to_colour(s);
}
init => {
self.colourbox = AuraPageData.led_mode_data.colour2;
self.final_colour = AuraPageData.led_mode_data.colour2;
}
}
}
}
}
}
HorizontalLayout {
spacing: 10px;
RogItem {
padding: 0px;
VerticalBox {
Text {
text: @tr("Zone");
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
}
ComboBox {
current_index <=> AuraPageData.zone;
current_value: AuraPageData.zone_names[self.current-index];
model <=> AuraPageData.zone_names;
selected => {
AuraPageData.led_mode_data.zone = self.current-index;
}
}
}
}
RogItem {
padding: 0px;
VerticalBox {
Text {
text: @tr("Direction");
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
}
ComboBox {
current_index <=> AuraPageData.direction;
current_value: AuraPageData.direction_names[self.current-index];
model <=> AuraPageData.direction_names;
selected => {
AuraPageData.led_mode_data.direction = self.current-index;
}
}
}
}
RogItem {
padding: 0px;
VerticalBox {
Text {
text: @tr("Speed");
vertical-alignment: TextVerticalAlignment.center;
horizontal-alignment: TextHorizontalAlignment.center;
}
ComboBox {
current_index <=> AuraPageData.speed;
current_value: AuraPageData.speed_names[self.current-index];
model <=> AuraPageData.speed_names;
selected => {
AuraPageData.led_mode_data.speed = self.current-index;
}
}
}
}
}
Button {
text: @tr("Apply");
clicked => {
AuraPageData.led_mode_data.mode = AuraPageData.led_mode;
AuraPageData.led_mode_data.colour1 = AuraPageData.color1;
AuraPageData.led_mode_data.colour2 = AuraPageData.color2;
AuraPageData.set_led_mode_data(AuraPageData.led_mode_data);
}
}
} }

View File

@@ -1,4 +1,3 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint"; import { Theme } from "../globals.slint";
export component PageFans inherits VerticalLayout { export component PageFans inherits VerticalLayout {
@@ -11,39 +10,8 @@ export component PageFans inherits VerticalLayout {
mainview := VerticalLayout { mainview := VerticalLayout {
padding: 10px; padding: 10px;
spacing: 10px; spacing: 10px;
ValueBar { Text {
height: 40px; text: "TODO";
value: 10.5;
min: 0.0;
max: 100.0;
}
ValueBar {
height: 40px;
value: -70;
min: -100;
max: 0;
}
ValueBar {
height: 80px;
value: 40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
} }
} }
} }

View File

@@ -1,50 +0,0 @@
import { ValueBar } from "../common_widgets.slint";
import { Theme } from "../globals.slint";
export component PageGpu inherits VerticalLayout {
Rectangle {
clip: true;
// TODO: slow with border-radius
padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px;
mainview := VerticalLayout {
padding: 10px;
spacing: 10px;
ValueBar {
height: 40px;
value: 10.5;
min: 0.0;
max: 100.0;
}
ValueBar {
height: 40px;
value: -70;
min: -100;
max: 0;
}
ValueBar {
height: 80px;
value: 40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
ValueBar {
height: 80px;
value: -40;
min: -50;
max: 50;
}
}
}
}

View File

@@ -1,15 +1,15 @@
import { ValueBar, SquareCharButton } from "../common_widgets.slint"; import { SystemSlider, SystemDropdown, SystemToggle } from "../common_widgets.slint";
import { Theme } from "../globals.slint"; import { Theme } from "../globals.slint";
import { HorizontalBox , VerticalBox, ScrollView, Slider, Button, Switch} from "std-widgets.slint"; import { HorizontalBox , VerticalBox, ScrollView, Slider, Button, Switch, ComboBox, GroupBox} from "std-widgets.slint";
export struct AvailableSystemProperties { export struct AvailableSystemProperties {
charge_limit: bool, charge_control_end_threshold: bool,
panel_od: bool, panel_od: bool,
mini_led_mode: bool, mini_led_mode: bool,
disable_nvidia_powerd_on_battery: bool, disable_nvidia_powerd_on_battery: bool,
ac_command: bool, ac_command: bool,
bat_command: bool, bat_command: bool,
throttle_policy: bool, throttle_thermal_policy: bool,
ppt_pl1_spl: bool, ppt_pl1_spl: bool,
ppt_pl2_sppt: bool, ppt_pl2_sppt: bool,
ppt_fppt: bool, ppt_fppt: bool,
@@ -19,186 +19,360 @@ export struct AvailableSystemProperties {
nv_temp_target: bool, nv_temp_target: bool,
} }
export struct SystemValues { export global SystemPageData {
charge_limit: int, in-out property <float> charge_control_end_threshold: 30;
last_charge_limit: int, callback set_charge_control_end_threshold(/* charge limit */ int);
panel_od: bool,
mini_led_mode: bool,
disable_nvidia_powerd_on_battery: bool,
}
export global SystemPage { in-out property <int> throttle_thermal_policy: 0;
in-out property <float> charge_limit; in-out property <[string]> throttle_policy_choices: [@tr("Balanced"), @tr("Performance"), @tr("Quiet")];
in-out property <int> last_charge_limit; callback set_throttle_thermal_policy(int);
callback set_charge_limit(/* charge limit */ int);
in-out property <[string]> energy_performance_choices: [
@tr("Default"),
@tr("Performance"),
@tr("BalancePerformance"),
@tr("BalancePower"),
@tr("Power")
];
in-out property <int> throttle_balanced_epp: 0;
callback set_throttle_balanced_epp(int);
in-out property <int> throttle_performance_epp: 0;
callback set_throttle_performance_epp(int);
in-out property <int> throttle_quiet_epp: 0;
callback set_throttle_quiet_epp(int);
// if the EPP should change with throttle
in-out property <bool> throttle_policy_linked_epp: true;
callback set_throttle_policy_linked_epp(bool);
in-out property <int> throttle_policy_on_ac: 0;
callback set_throttle_policy_on_ac(int);
in-out property <int> throttle_policy_on_battery: 0;
callback set_throttle_policy_on_battery(int);
in-out property <bool> panel_od; in-out property <bool> panel_od;
in-out property <bool> last_panel_od; callback set_panel_od(bool);
callback set_panel_od(/* panel_od */ bool);
callback applied(); in-out property <bool> mini_led_mode;
callback cancelled(); callback set_mini_led_mode(bool);
in-out property <AvailableSystemProperties> available; in-out property <float> ppt_pl1_spl: 5;
callback set_ppt_pl1_spl(int);
in-out property <float> ppt_pl2_sppt: 5;
callback set_ppt_pl2_sppt(int);
in-out property <float> ppt_fppt: 5;
callback set_ppt_fppt(int);
in-out property <float> ppt_apu_sppt: 5;
callback set_ppt_apu_sppt(int);
in-out property <float> ppt_platform_sppt: 5;
callback set_ppt_platform_sppt(int);
in-out property <float> nv_dynamic_boost: 5;
callback set_nv_dynamic_boost(int);
in-out property <float> nv_temp_target: 75;
callback set_nv_temp_target(int);
in-out property <AvailableSystemProperties> available: {
charge_control_end_threshold: true,
panel_od: true,
mini_led_mode: true,
disable_nvidia_powerd_on_battery: true,
ac_command: true,
bat_command: true,
throttle_thermal_policy: true,
ppt_pl1_spl: true,
ppt_pl2_sppt: true,
ppt_fppt: true,
ppt_apu_sppt: true,
ppt_platform_sppt: true,
nv_dynamic_boost: true,
nv_temp_target: true,
};
} }
export component PageSystem inherits Rectangle { export component PageSystem inherits Rectangle {
background: Theme.background-color; property <bool> show_fade_cover: false;
property <bool> show_throttle_advanced: false;
VerticalLayout { clip: true;
ScrollView { padding: 8px;
VerticalLayout { ScrollView {
// padding: 10px; VerticalLayout {
padding: 10px;
spacing: 10px; spacing: 10px;
min-height: root.height;
if SystemPage.available.charge-limit: Rectangle { Rectangle {
background: Theme.background-color; background: Theme.background-color;
VerticalBox { border-color: Colors.black;
border-width: 6px;
border-radius: 10px;
height: 40px;
Text {
font-size: 18px;
color: Theme.text-foreground-color;
horizontal-alignment: TextHorizontalAlignment.center;
text: @tr("Base system settings");
}
}
HorizontalBox { if SystemPageData.available.charge-control-end-threshold: SystemSlider {
alignment: LayoutAlignment.start; text: @tr("Charge limit");
Text { minimum: 20;
color: Theme.text-foreground-color; maximum: 100;
text: @tr("ChargeLimit" => "Charge limit"); value <=> SystemPageData.charge_control_end_threshold;
}
Text {
color: Theme.text-foreground-color;
text: "\{Math.floor(SystemPage.charge_limit)}";
}
}
HorizontalBox {
TouchArea { }
charge_slider := Slider {
maximum: 100;
minimum: 20;
value <=> SystemPage.charge_limit;
released => { released => {
SystemPage.set_charge_limit(SystemPage.charge_limit) SystemPageData.set_charge_control_end_threshold(Math.round(SystemPageData.charge_control_end_threshold))
}
}
}
}
}
if SystemPage.available.panel-od: Rectangle {
background: Theme.background-color;
VerticalBox {
HorizontalBox {
alignment: LayoutAlignment.start;
Text {
color: Theme.text-foreground-color;
text: @tr("PanelOverdrive" => "Panel Overdrive");
}
Switch {
checked <=> SystemPage.panel_od;
toggled => {
SystemPage.set_panel_od(SystemPage.panel_od)
}
}
}
Text {
color: Theme.text-foreground-color;
text: @tr("PerformanceProfile" => "Performance Profile");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("nv_dynamic_boost" => "nv_dynamic_boost");
}
Text {
color: Theme.text-foreground-color;
text: @tr("nv_temp_target" => "nv_temp_target");
}
Text {
color: Theme.text-foreground-color;
text: @tr("ppt_pl1_spl" => "ppt_pl1_spl");
}
Text {
color: Theme.text-foreground-color;
text: @tr("ppt_pl2_sppt" => "ppt_pl2_sppt");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("PanelOverdrive" => "Panel Overdrive");
}
Text {
color: Theme.text-foreground-color;
text: @tr("PerformanceProfile" => "Performance Profile");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("PanelOverdrive" => "Panel Overdrive");
}
Text {
color: Theme.text-foreground-color;
text: @tr("PerformanceProfile" => "Performance Profile");
}
}
}
Rectangle {
background: Theme.background-color;
VerticalBox {
Text {
color: Theme.text-foreground-color;
text: @tr("PanelOverdrive" => "Panel Overdrive");
}
Text {
color: Theme.text-foreground-color;
text: @tr("PerformanceProfile" => "Performance Profile");
}
}
}
}
}
HorizontalLayout {
Button {
text: "Apply";
clicked => {
if SystemPage.last_charge_limit != Math.floor(SystemPage.charge_limit) {
SystemPage.set_charge_limit(SystemPage.charge_limit);
SystemPage.last_charge_limit = Math.floor(SystemPage.charge_limit);
}
SystemPage.applied();
} }
} }
Button { if SystemPageData.available.throttle-thermal-policy: HorizontalLayout {
text: "Cancel"; spacing: 10px;
clicked => { SystemDropdown {
SystemPage.charge_limit = SystemPage.last_charge_limit; text: @tr("Throttle Policy");
SystemPage.cancelled(); current_index <=> SystemPageData.throttle_thermal_policy;
current_value: SystemPageData.throttle_policy_choices[SystemPageData.throttle_thermal_policy];
model <=> SystemPageData.throttle_policy_choices;
selected => {
SystemPageData.set_throttle_thermal_policy(SystemPageData.throttle_thermal_policy)
}
}
Button {
text: @tr("Advanced");
clicked => {
root.show_fade_cover = true;
root.show_throttle_advanced = true;
}
}
}
HorizontalBox {
padding: 0px;
spacing: 10px;
if SystemPageData.available.panel-od: SystemToggle {
text: @tr("Panel Overdrive");
checked <=> SystemPageData.panel_od;
toggled => {
SystemPageData.set_panel_od(SystemPageData.panel_od)
}
}
if SystemPageData.available.mini-led-mode: SystemToggle {
text: @tr("MiniLED Mode");
checked <=> SystemPageData.mini_led_mode;
toggled => {
SystemPageData.set_mini_led_mode(SystemPageData.mini_led_mode)
}
}
}
Rectangle {
background: Theme.background-color;
border-color: Colors.black;
border-width: 6px;
border-radius: 10px;
height: 40px;
Text {
font-size: 18px;
color: Theme.text-foreground-color;
horizontal-alignment: TextHorizontalAlignment.center;
text: @tr("System performance settings");
}
}
if SystemPageData.available.ppt-pl1-spl: SystemSlider {
text: @tr("ppt_pl1_spl" => "ppt_pl1_spl");
minimum: 5;
maximum: 250;
value <=> SystemPageData.ppt_pl1_spl;
released => {
SystemPageData.set_ppt_pl1_spl(Math.round(SystemPageData.ppt_pl1_spl))
}
}
if SystemPageData.available.ppt-pl2-sppt: SystemSlider {
text: @tr("ppt_pl2_sppt" => "ppt_pl2_sppt");
minimum: 5;
maximum: 250;
value <=> SystemPageData.ppt_pl2_sppt;
released => {
SystemPageData.set_ppt_pl2_sppt(Math.round(SystemPageData.ppt_pl2_sppt))
}
}
if SystemPageData.available.ppt-fppt: SystemSlider {
text: @tr("ppt_fppt" => "ppt_fppt");
minimum: 5;
maximum: 250;
value <=> SystemPageData.ppt_fppt;
released => {
SystemPageData.set_ppt_fppt(Math.round(SystemPageData.ppt_fppt))
}
}
if SystemPageData.available.ppt-apu-sppt: SystemSlider {
text: @tr("ppt_apu_sppt" => "ppt_apu_sppt");
minimum: 5;
maximum: 130;
value <=> SystemPageData.ppt_apu_sppt;
released => {
SystemPageData.set_ppt_apu_sppt(Math.round(SystemPageData.ppt_apu_sppt))
}
}
if SystemPageData.available.ppt-platform-sppt: SystemSlider {
text: @tr("ppt_platform_sppt" => "ppt_platform_sppt");
maximum: 130;
minimum: 5;
value <=> SystemPageData.ppt_platform_sppt;
released => {
SystemPageData.set_ppt_platform_sppt(Math.round(SystemPageData.ppt_platform_sppt))
}
}
if SystemPageData.available.nv-dynamic-boost: SystemSlider {
text: @tr("nv_dynamic_boost" => "nv_dynamic_boost");
minimum: 5;
maximum: 25;
value <=> SystemPageData.nv_dynamic_boost;
released => {
SystemPageData.set_nv_dynamic_boost(Math.round(SystemPageData.nv_dynamic_boost))
}
}
if SystemPageData.available.nv-temp-target: SystemSlider {
text: @tr("nv_temp_target" => "nv_temp_target");
minimum: 75;
maximum: 87;
value <=> SystemPageData.nv_temp_target;
released => {
SystemPageData.set_nv_temp_target(Math.round(SystemPageData.nv_temp_target))
} }
} }
} }
} }
if root.show_fade_cover: Rectangle {
width: 100%;
height: 100%;
background: Theme.background-color;
opacity: 0.8;
TouchArea {
height: 100%;
width: 100%;
clicked => {
// toolbar-dropdown.close();
if (root.show_throttle_advanced) {
root.show_throttle_advanced = false;
}
root.show_fade_cover = false;
}
}
}
if root.show_throttle_advanced: Rectangle {
width: 100%;
height: 100%;
opacity: 1;
ScrollView {
VerticalLayout {
padding: 50px;
padding-top: 5px;
spacing: 10px;
GroupBox {
VerticalBox {
spacing: 10px;
Text {
font-size: 18px;
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
text: @tr("Energy Performance Preference linked to Throttle Policy");
}
SystemToggle {
text: @tr("Change EPP based on Throttle Policy");
checked <=> SystemPageData.throttle_policy_linked_epp;
toggled => {
SystemPageData.set_throttle_policy_linked_epp(SystemPageData.throttle_policy_linked_epp)
}
}
SystemDropdown {
text: @tr("EPP for Balanced Policy");
current_index <=> SystemPageData.throttle_balanced_epp;
current_value: SystemPageData.energy_performance_choices[SystemPageData.throttle_balanced_epp];
model <=> SystemPageData.energy_performance_choices;
selected => {
SystemPageData.set_throttle_balanced_epp(SystemPageData.throttle_balanced_epp)
}
}
SystemDropdown {
text: @tr("EPP for Performance Policy");
current_index <=> SystemPageData.throttle_performance_epp;
current_value: SystemPageData.energy_performance_choices[SystemPageData.throttle_performance_epp];
model <=> SystemPageData.energy_performance_choices;
selected => {
SystemPageData.set_throttle_performance_epp(SystemPageData.throttle_performance_epp)
}
}
SystemDropdown {
text: @tr("EPP for Quiet Policy");
current_index <=> SystemPageData.throttle_quiet_epp;
current_value: SystemPageData.energy_performance_choices[SystemPageData.throttle_quiet_epp];
model <=> SystemPageData.energy_performance_choices;
selected => {
SystemPageData.set_throttle_quiet_epp(SystemPageData.throttle_quiet_epp)
}
}
}
}
GroupBox {
VerticalBox {
spacing: 10px;
Text {
font-size: 18px;
horizontal-alignment: TextHorizontalAlignment.center;
vertical-alignment: TextVerticalAlignment.center;
text: @tr("Throttle Policy for power state");
}
SystemDropdown {
text: @tr("Throttle Policy on Battery");
current_index <=> SystemPageData.throttle_policy_on_battery;
current_value: SystemPageData.throttle_policy_choices[SystemPageData.throttle_policy_on_battery];
model <=> SystemPageData.throttle_policy_choices;
selected => {
SystemPageData.set_throttle_policy_on_battery(SystemPageData.throttle_policy_on_battery)
}
}
SystemDropdown {
text: @tr("Throttle Policy on AC");
current_index <=> SystemPageData.throttle_policy_on_ac;
current_value: SystemPageData.throttle_policy_choices[SystemPageData.throttle_policy_on_ac];
model <=> SystemPageData.throttle_policy_choices;
selected => {
SystemPageData.set_throttle_policy_on_ac(SystemPageData.throttle_policy_on_ac)
}
}
}
}
}
}
Button {
x: root.width - self.width - 6px;
y: 6px;
text: "X";
height: 40px;
clicked => {
root.show_throttle_advanced = false;
root.show_fade_cover = false;
}
}
}
} }

View File

@@ -0,0 +1,282 @@
import { Slider, HorizontalBox, Button, LineEdit } from "std-widgets.slint";
export component ColourSlider inherits VerticalLayout {
spacing: 10px;
property <string> hex: "#FF0000";
property <color> base_colour: Colors.red;
in-out property <color> final_colour: Colors.red;
in-out property <brush> colourbox: final_colour;
callback hex_to_colour(string) -> color;
// required
callback set_hex_from_colour(color) -> string;
/// This callback is required until slint adds direct acces to color channels
callback blend_colour(color, color, float) -> color;
callback blend_lightness(color, float) -> color;
property <[color]> base_colours: [
Colors.rgb( 255, 0, 0),
Colors.rgb( 255, 128, 0),
Colors.rgb( 255, 255, 0),
Colors.rgb( 128, 255, 0),
Colors.rgb( 0, 255, 0),
Colors.rgb( 0, 255, 128),
Colors.rgb( 0, 255, 255),
Colors.rgb( 0, 128, 255),
Colors.rgb( 0, 0, 255),
Colors.rgb( 127, 0, 255),
Colors.rgb( 255, 0, 255),
Colors.rgb( 255, 0, 127),
Colors.rgb( 128, 128, 128)
];
property <[color]> base_shade: [
base_colour.with-alpha(100%),
base_colour.with-alpha(90%),
base_colour.with-alpha(80%),
base_colour.with-alpha(70%),
base_colour.with-alpha(60%),
base_colour.with-alpha(50%),
base_colour.with-alpha(40%),
base_colour.with-alpha(30%),
base_colour.with-alpha(20%),
base_colour.with-alpha(10%),
base_colour.with-alpha(0%)
];
function set_base_colour() {
// base_colour = base_colours[c1.value].mix(base_colours[c1.value+1], _index_rem);
root.base_colour = blend_colour(base_colours[c1.value], base_colours[c1.value + 1], c1.value - Math.floor(c1.value));
root.final_colour = blend_lightness(base_colour, (base_shade.length - c2.value) / base_shade.length);
root.colourbox = root.final_colour;
}
Rectangle {
height: 32px;
// 13 colours
background: @linear-gradient(90deg, base_colours[0], base_colours[1], base_colours[2], base_colours[3], base_colours[4], base_colours[5], base_colours[6], base_colours[7], base_colours[8], base_colours[9], base_colours[10], base_colours[11], base_colours[12]);
clip: true;
border-radius: 6px;
c1 := Slider {
width: parent.width;
height: parent.height;
minimum: 0;
maximum: 12;
changed => {
set_base_colour();
hex = set_hex_from_colour(final_colour);
}
}
}
Rectangle {
height: 32px;
// 11 colours
background: @linear-gradient(90deg, base_shade[0], base_shade[1], base_shade[2], base_shade[3], base_shade[4], base_shade[5], base_shade[6], base_shade[7], base_shade[8], base_shade[9], base_shade[10]);
clip: true;
border-radius: 6px;
c2 := Slider {
width: parent.width;
height: parent.height;
minimum: 0;
maximum: 11;
changed => {
set_base_colour();
hex = set_hex_from_colour(final_colour);
}
}
}
HorizontalLayout {
LineEdit {
// width: 50%;
text <=> root.hex;
edited => {
base_colour = hex_to_colour(self.text);
root.colourbox = base_colour;
}
}
Rectangle {
width: self.height;
background <=> root.colourbox;
}
}
}
component ColorButton {
callback select<=>i_touch_area.clicked;
in property <brush> color<=> i_container.background;
in property <bool> selected;
height: self.width;
i_container := Rectangle {
border_width: 2px;
}
i_touch_area := TouchArea { }
states [
selected when selected: {
i_container.border_color: Colors.black;
}
]
}
export component ColorPicker {
height: palette.length * 1px / colors_per_row / 1px * color_size;
private property <int> selected_color_index;
in-out property <float> colors_per_row: 13.0;
private property <length> color_size: self.width / colors_per_row;
out property <color> selected_color: palette[selected_color_index];
callback selected(color);
in property <[color]> palette: [
Colors.rgb(51,0,0),
Colors.rgb(51,25,0),
Colors.rgb(51,51,0),
Colors.rgb(25,51,0),
Colors.rgb(0,51,0),
Colors.rgb(0,51,25),
Colors.rgb(0,51,51),
Colors.rgb(0,25,51),
Colors.rgb(0,0,51),
Colors.rgb(25,0,51),
Colors.rgb(51,0,51),
Colors.rgb(51,0,25),
Colors.rgb(0,0,0),
//
Colors.rgb(102,0,0),
Colors.rgb(102,51,0),
Colors.rgb(102,102,0),
Colors.rgb(51,102,0),
Colors.rgb(0,102,0),
Colors.rgb(0,102,51),
Colors.rgb(0,102,102),
Colors.rgb(0,51,102),
Colors.rgb(0,0,102),
Colors.rgb(51,0,102),
Colors.rgb(102,0,102),
Colors.rgb(102,0,51),
Colors.rgb(32,32,32),
//
Colors.rgb(153,0,0),
Colors.rgb(153,76,0),
Colors.rgb(153,153,0),
Colors.rgb(76,153,0),
Colors.rgb(0,153,0),
Colors.rgb(0,153,76),
Colors.rgb(0,153,153),
Colors.rgb(0,76,153),
Colors.rgb(0,0,153),
Colors.rgb(76,0,153),
Colors.rgb(153,0,153),
Colors.rgb(153,0,76),
Colors.rgb(64,64,64),
//
Colors.rgb(204,0,0),
Colors.rgb(204,102,0),
Colors.rgb(204,204,0),
Colors.rgb(102,204,0),
Colors.rgb(0,204,0),
Colors.rgb(0,204,102),
Colors.rgb(0,204,204),
Colors.rgb(0,102,204),
Colors.rgb(0,0,204),
Colors.rgb(102,0,204),
Colors.rgb(204,0,204),
Colors.rgb(204,0,102),
Colors.rgb(96,96,96),
//
Colors.rgb(255,0,0),
Colors.rgb(255,128,0),
Colors.rgb(255,255,0),
Colors.rgb(128,255,0),
Colors.rgb(0,255,0),
Colors.rgb(0,255,128),
Colors.rgb(0,255,255),
Colors.rgb(0,128,255),
Colors.rgb(0,0,255),
Colors.rgb(128,0,255),
Colors.rgb(255,0,255),
Colors.rgb(255,0,128),
Colors.rgb(128,128,128),
//
Colors.rgb(255,51,51),
Colors.rgb(255,153,51),
Colors.rgb(255,255,51),
Colors.rgb(153,255,51),
Colors.rgb(51,255,51),
Colors.rgb(51,255,153),
Colors.rgb(51,255,255),
Colors.rgb(51,153,255),
Colors.rgb(51,51,255),
Colors.rgb(153,51,255),
Colors.rgb(255,51,255),
Colors.rgb(255,51,153),
Colors.rgb(160,160,160),
//
Colors.rgb(255,102,102),
Colors.rgb(255,178,102),
Colors.rgb(255,255,102),
Colors.rgb(178,255,102),
Colors.rgb(102,255,102),
Colors.rgb(102,255,178),
Colors.rgb(102,255,255),
Colors.rgb(102,178,255),
Colors.rgb(102,102,255),
Colors.rgb(178,102,255),
Colors.rgb(255,102,255),
Colors.rgb(255,102,178),
Colors.rgb(192,192,192),
//
Colors.rgb(255,153,153),
Colors.rgb(255,204,153),
Colors.rgb(255,255,153),
Colors.rgb(204,255,153),
Colors.rgb(153,255,153),
Colors.rgb(153,255,204),
Colors.rgb(153,255,255),
Colors.rgb(153,204,255),
Colors.rgb(153,153,255),
Colors.rgb(204,153,255),
Colors.rgb(255,153,255),
Colors.rgb(255,153,204),
Colors.rgb(224,224,224),
//
Colors.rgb(255,204,204),
Colors.rgb(255,229,204),
Colors.rgb(255,255,204),
Colors.rgb(229,255,204),
Colors.rgb(204,255,204),
Colors.rgb(204,255,229),
Colors.rgb(204,255,255),
Colors.rgb(204,229,255),
Colors.rgb(204,204,255),
Colors.rgb(229,204,255),
Colors.rgb(255,204,255),
Colors.rgb(255,204,229),
Colors.rgb(224,224,224),
];
Rectangle {
border_width: 1px;
border_color: Colors.black;
for color[index] in palette: ColorButton {
x: color_size * mod(index, colors_per_row);
y: color_size * floor(index / colors_per_row);
width: color_size;
color: color;
selected: index == selected_color_index;
select => {
selected_color_index = index;
// debug(Math.mod(selected_color_index, colors_per_row)); // X pos
// debug(Math.floor(selected_color_index / colors_per_row)); // Y pos
return selected(Math.mod(selected_color_index, colors_per_row) == colors_per_row - 1 ? Colors.rgb(255 / (palette.length / colors_per_row - 1) * Math.floor(selected_color_index / colors_per_row),0,0) : selected_color);
}
}
}
}

View File

@@ -8,10 +8,10 @@ component SideBarItem inherits Rectangle {
in property <bool> has-focus; in property <bool> has-focus;
in-out property <string> text<=> label.text; in-out property <string> text<=> label.text;
callback clicked<=>touch.clicked; callback clicked<=>touch.clicked;
min-height: l.preferred-height; min-height: self.visible ? l.preferred-height : 0px;
states [ states [
pressed when touch.pressed: { pressed when touch.pressed: {
state.opacity: 0.8; state.opacity: 0.8;
} }
hover when touch.has-hover: { hover when touch.has-hover: {
state.opacity: 0.6; state.opacity: 0.6;
@@ -22,14 +22,14 @@ component SideBarItem inherits Rectangle {
focused when root.has-focus: { focused when root.has-focus: {
state.opacity: 0.8; state.opacity: 0.8;
} }
] ]state := Rectangle {
state := Rectangle {
opacity: 0; opacity: 0;
border-width: 2px;
border-radius: 10px;
border-color: StyleMetrics.default-text-color;
background: StyleMetrics.window-background; background: StyleMetrics.window-background;
animate opacity{ duration: 150ms; animate opacity { duration: 150ms; }
} animate border-width { duration: 150ms; }
} }
l := HorizontalLayout { l := HorizontalLayout {
@@ -50,6 +50,7 @@ component SideBarItem inherits Rectangle {
export component SideBar inherits Rectangle { export component SideBar inherits Rectangle {
in property <[string]> model: []; in property <[string]> model: [];
in property <[bool]> available: [];
in property <string> title<=> label.text; in property <string> title<=> label.text;
out property <int> current-item: 0; out property <int> current-item: 0;
out property <int> current-focused: fs.has-focus ? fs.focused-tab : -1; out property <int> current-focused: fs.has-focus ? fs.focused-tab : -1;
@@ -65,22 +66,22 @@ export component SideBar inherits Rectangle {
key-pressed(event) => { key-pressed(event) => {
if (event.text == "\n") { if (event.text == "\n") {
root.current-item = root.current-focused; root.current-item = root.current-focused;
return accept; return accept;
} }
if (event.text == Key.UpArrow) { if (event.text == Key.UpArrow) {
self.focused-tab = Math.max(self.focused-tab - 1, 0); self.focused-tab = Math.max(self.focused-tab - 1, 0);
return accept; return accept;
} }
if (event.text == Key.DownArrow) { if (event.text == Key.DownArrow) {
self.focused-tab = Math.min(self.focused-tab + 1, root.model.length - 1); self.focused-tab = Math.min(self.focused-tab + 1, root.model.length - 1);
return accept; return accept;
} }
return reject; return reject;
} }
key-released(event) => { key-released(event) => {
if (event.text == " ") { if (event.text == " ") {
root.current-item = root.current-focused; root.current-item = root.current-focused;
return accept; return accept;
} }
return reject; return reject;
} }
@@ -92,8 +93,7 @@ export component SideBar inherits Rectangle {
} }
VerticalLayout { VerticalLayout {
padding-top: StyleMetrics.layout-padding; padding: StyleMetrics.layout-padding;
padding-bottom: StyleMetrics.layout-padding;
spacing: StyleMetrics.layout-spacing; spacing: StyleMetrics.layout-spacing;
alignment: start; alignment: start;
label := Text { label := Text {
@@ -102,15 +102,17 @@ export component SideBar inherits Rectangle {
} }
navigation := VerticalLayout { navigation := VerticalLayout {
spacing: 10px;
alignment: start; alignment: start;
vertical-stretch: 0; vertical-stretch: 0;
for item [index] in root.model: SideBarItem { for item[index] in root.model: SideBarItem {
clicked => { visible: root.available[index];
root.current-item = index; clicked => {
} root.current-item = index;
has-focus: index == root.current-focused; }
text: item; has-focus: index == root.current-focused;
selected: index == root.current-item; text: item;
selected: index == root.current-item;
} }
} }

View File

@@ -20,6 +20,7 @@
//! //!
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces. //! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
use rog_platform::cpu::CPUEPP;
use rog_platform::platform::{GpuMode, Properties, ThrottlePolicy}; use rog_platform::platform::{GpuMode, Properties, ThrottlePolicy};
use zbus::proxy; use zbus::proxy;
@@ -118,9 +119,45 @@ trait Platform {
#[zbus(property)] #[zbus(property)]
fn set_ppt_platform_sppt(&self, value: u8) -> zbus::Result<()>; fn set_ppt_platform_sppt(&self, value: u8) -> zbus::Result<()>;
/// ThrottleBalancedEpp property
#[zbus(property)]
fn throttle_balanced_epp(&self) -> zbus::Result<CPUEPP>;
#[zbus(property)]
fn set_throttle_balanced_epp(&self, epp: CPUEPP) -> zbus::Result<()>;
/// ThrottlePerformanceEpp property
#[zbus(property)]
fn throttle_performance_epp(&self) -> zbus::Result<CPUEPP>;
#[zbus(property)]
fn set_throttle_performance_epp(&self, epp: CPUEPP) -> zbus::Result<()>;
/// ThrottlePolicyLinkedEpp property
#[zbus(property)]
fn throttle_policy_linked_epp(&self) -> zbus::Result<bool>;
#[zbus(property)]
fn set_throttle_policy_linked_epp(&self, value: bool) -> zbus::Result<()>;
/// ThrottlePolicyOnAc property
#[zbus(property)]
fn throttle_policy_on_ac(&self) -> zbus::Result<ThrottlePolicy>;
#[zbus(property)]
fn set_throttle_policy_on_ac(&self, throttle_policy: ThrottlePolicy) -> zbus::Result<()>;
/// ThrottlePolicyOnBattery property
#[zbus(property)]
fn throttle_policy_on_battery(&self) -> zbus::Result<ThrottlePolicy>;
#[zbus(property)]
fn set_throttle_policy_on_battery(&self, throttle_policy: ThrottlePolicy) -> zbus::Result<()>;
/// ThrottleQuietEpp property
#[zbus(property)]
fn throttle_quiet_epp(&self) -> zbus::Result<CPUEPP>;
#[zbus(property)]
fn set_throttle_quiet_epp(&self, epp: CPUEPP) -> zbus::Result<()>;
/// ThrottlePolicy property /// ThrottlePolicy property
#[zbus(property)] #[zbus(property)]
fn throttle_thermal_policy(&self) -> zbus::Result<ThrottlePolicy>; fn throttle_thermal_policy(&self) -> zbus::Result<ThrottlePolicy>;
#[zbus(property)] #[zbus(property)]
fn set_throttle_thermal_policy(&self, value: ThrottlePolicy) -> zbus::Result<()>; fn set_throttle_thermal_policy(&self, throttle_policy: ThrottlePolicy) -> zbus::Result<()>;
} }

View File

@@ -239,6 +239,25 @@ impl From<CPUEPP> for String {
} }
} }
impl From<i32> for CPUEPP {
fn from(value: i32) -> Self {
match value {
0 => Self::Default,
1 => Self::Performance,
2 => Self::BalancePerformance,
3 => Self::BalancePower,
4 => Self::Power,
_ => Self::Default,
}
}
}
impl From<CPUEPP> for i32 {
fn from(value: CPUEPP) -> Self {
value as i32
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::CPUControl; use super::CPUControl;

View File

@@ -29,12 +29,12 @@ impl RogPlatform {
attr_bool!("egpu_enable", path); attr_bool!("egpu_enable", path);
attr_u8!("gpu_mux_mode", path);
attr_bool!("panel_od", path); attr_bool!("panel_od", path);
attr_bool!("mini_led_mode", path); attr_bool!("mini_led_mode", path);
attr_u8!("gpu_mux_mode", path);
attr_u8!( attr_u8!(
/// This is technically the same as `platform_profile` since both are /// This is technically the same as `platform_profile` since both are
/// tied in-kernel /// tied in-kernel
@@ -303,6 +303,12 @@ impl From<u8> for ThrottlePolicy {
} }
} }
impl From<i32> for ThrottlePolicy {
fn from(num: i32) -> Self {
(num as u8).into()
}
}
impl From<ThrottlePolicy> for u8 { impl From<ThrottlePolicy> for u8 {
fn from(p: ThrottlePolicy) -> Self { fn from(p: ThrottlePolicy) -> Self {
match p { match p {
@@ -313,6 +319,12 @@ impl From<ThrottlePolicy> for u8 {
} }
} }
impl From<ThrottlePolicy> for i32 {
fn from(p: ThrottlePolicy) -> Self {
<u8>::from(p) as i32
}
}
impl From<ThrottlePolicy> for &str { impl From<ThrottlePolicy> for &str {
fn from(profile: ThrottlePolicy) -> &'static str { fn from(profile: ThrottlePolicy) -> &'static str {
match profile { match profile {

View File

@@ -0,0 +1,49 @@
// TODO: macro
// let conn = zbus::blocking::Connection::system().unwrap();
// let proxy = PlatformProxyBlocking::new(&conn).unwrap();
// //
// let proxy2 = proxy.clone();
// let handle = ui.as_weak();
// ui.global::<SystemPageData>().on_set_charge_limit(move |limit| {
// if let Some(handle) = handle.upgrade() {
// match proxy2.set_charge_control_end_threshold(limit as u8) {
// Ok(_) => handle
// .invoke_show_toast(format!("Charge limit successfully set to {limit}").into()),
// Err(e) => handle.invoke_show_toast(format!("Charge limit failed: {e}").into()),
// }
// }
// });
// let proxy2 = proxy.clone();
// let handle = ui.as_weak();
// ui.global::<SystemPageData>().on_set_panel_od(move |od| {
// if let Some(handle) = handle.upgrade() {
// match proxy2.set_panel_od(od) {
// Ok(_) => handle
// .invoke_show_toast(format!("Panel Overdrive successfully set to {od}").into()),
// Err(e) => handle.invoke_show_toast(format!("Panel Overdrive failed: {e}").into()),
// }
// }
// });
// or
// let handle = ui.as_weak();
// ui.global::<SystemPageData>().on_applied(move || {
// handle
// .upgrade_in_event_loop(|handle| {
// let data = handle.global::<SystemPageData>();
// let charge_changed = data.get_charge_limit() as i32 !=
// data.get_last_charge_limit(); let charge =
// data.get_charge_limit() as u8; tokio::spawn(async move {
// let conn = zbus::Connection::system().await.unwrap();
// let proxy = PlatformProxy::new(&conn).await.unwrap();
// if charge_changed {
// proxy
// .set_charge_control_end_threshold(charge)
// .await
// .unwrap();
// }
// });
// })
// .ok();
// });