diff --git a/CHANGELOG.md b/CHANGELOG.md index bd1831a0..99529315 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - ROG Arion external driver LED support - Add GA605W LED layout +- Add GA605 + GU605 Slash support ### Changed - Fix attribute writes. At some point the kernel API seems to have changed. diff --git a/Cargo.lock b/Cargo.lock index 39502dbc..e85cc619 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,9 +117,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "arbitrary" @@ -135,7 +135,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -239,9 +239,9 @@ dependencies = [ [[package]] name = "async-broadcast" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ "event-listener", "event-listener-strategy", @@ -353,7 +353,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -393,7 +393,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -410,7 +410,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -428,7 +428,7 @@ dependencies = [ "derive_utils", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -553,7 +553,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.90", + "syn 2.0.91", "which", ] @@ -574,7 +574,7 @@ dependencies = [ "regex", "rustc-hash 2.1.0", "shlex", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -685,7 +685,7 @@ checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -888,7 +888,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d" dependencies = [ "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -952,7 +952,7 @@ dependencies = [ [[package]] name = "const-field-offset" version = "0.1.5" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "const-field-offset-macro", "field-offset", @@ -961,11 +961,11 @@ dependencies = [ [[package]] name = "const-field-offset-macro" version = "0.1.5" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -1205,7 +1205,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "unicode-xid", ] @@ -1217,7 +1217,7 @@ checksum = "65f152f4b8559c4da5d574bafc7af85454d706b4c5fe8b530d508cacbb6807ea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -1285,7 +1285,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -1401,7 +1401,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -1612,7 +1612,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -1699,7 +1699,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -2173,7 +2173,7 @@ dependencies = [ [[package]] name = "i-slint-backend-linuxkms" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "calloop 0.14.2", "drm", @@ -2191,7 +2191,7 @@ dependencies = [ [[package]] name = "i-slint-backend-selector" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "cfg-if", "i-slint-backend-linuxkms", @@ -2204,7 +2204,7 @@ dependencies = [ [[package]] name = "i-slint-backend-winit" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "ashpd", "cfg-if", @@ -2235,7 +2235,7 @@ dependencies = [ [[package]] name = "i-slint-common" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "cfg-if", "derive_more", @@ -2247,7 +2247,7 @@ dependencies = [ [[package]] name = "i-slint-compiler" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "by_address", "codemap", @@ -2277,7 +2277,7 @@ dependencies = [ [[package]] name = "i-slint-core" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "auto_enums", "bitflags 2.6.0", @@ -2322,17 +2322,17 @@ dependencies = [ [[package]] name = "i-slint-core-macros" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "quote", "serde_json", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] name = "i-slint-renderer-femtovg" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "cfg-if", "const-field-offset", @@ -2362,7 +2362,7 @@ dependencies = [ [[package]] name = "i-slint-renderer-skia" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "bytemuck", "cfg-if", @@ -2530,7 +2530,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -2695,7 +2695,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -2934,9 +2934,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linked_hash_set" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" +checksum = "bae85b5be22d9843c80e5fc80e9b64c8a3b1f98f867c709956eca3efff4e92e2" dependencies = [ "linked-hash-map", ] @@ -3273,7 +3273,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -3324,7 +3324,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -3647,7 +3647,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -3769,7 +3769,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -3806,7 +3806,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -3829,7 +3829,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -4112,7 +4112,6 @@ dependencies = [ "image 0.25.5", "ksni", "log", - "nix", "notify-rust", "rog_anime", "rog_aura", @@ -4123,7 +4122,6 @@ dependencies = [ "slint", "slint-build", "supergfxctl", - "tempfile", "tokio", "versions", "zbus 5.2.0", @@ -4449,7 +4447,7 @@ checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -4472,7 +4470,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -4600,7 +4598,7 @@ dependencies = [ [[package]] name = "slint" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "const-field-offset", "i-slint-backend-selector", @@ -4617,7 +4615,7 @@ dependencies = [ [[package]] name = "slint-build" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "i-slint-compiler", "i-slint-core-macros", @@ -4629,7 +4627,7 @@ dependencies = [ [[package]] name = "slint-macros" version = "1.9.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "i-slint-compiler", "proc-macro2", @@ -4814,7 +4812,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -4855,9 +4853,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" dependencies = [ "proc-macro2", "quote", @@ -4878,7 +4876,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -4982,7 +4980,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -5114,7 +5112,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -5271,7 +5269,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -5354,7 +5352,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a615d6c2764852a2e88a4f16e9ce1ea49bb776b5872956309e170d63a042a34f" dependencies = [ "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -5590,7 +5588,7 @@ dependencies = [ [[package]] name = "vtable" version = "0.2.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "const-field-offset", "portable-atomic", @@ -5601,11 +5599,11 @@ dependencies = [ [[package]] name = "vtable-macro" version = "0.2.1" -source = "git+https://github.com/slint-ui/slint.git#e125da180d34df9e221cb925ea5c1af6e813bd8f" +source = "git+https://github.com/slint-ui/slint.git#d6f83a2af663de2128104fe4241e8b12f308db8d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -5654,7 +5652,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "wasm-bindgen-shared", ] @@ -5689,7 +5687,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5940,7 +5938,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -5951,7 +5949,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -5962,7 +5960,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -5973,7 +5971,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -6229,9 +6227,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.30.6" +version = "0.30.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3d72dfa0f47e429290cd0d236884ca02f22dbd5dd33a43ad2b8bf4d79b6c18" +checksum = "dba50bc8ef4b6f1a75c9274fb95aa9a8f63fbc66c56f391bd85cf68d51e7b1a3" dependencies = [ "ahash", "android-activity", @@ -6440,7 +6438,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "synstructure", ] @@ -6527,7 +6525,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "zvariant_utils 2.1.0", ] @@ -6540,7 +6538,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "zbus_names 4.1.0", "zvariant 5.1.0", "zvariant_utils 3.0.2", @@ -6587,7 +6585,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -6607,7 +6605,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "synstructure", ] @@ -6630,7 +6628,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -6695,7 +6693,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "zvariant_utils 2.1.0", ] @@ -6708,7 +6706,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", "zvariant_utils 3.0.2", ] @@ -6720,7 +6718,7 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.91", ] [[package]] @@ -6733,6 +6731,6 @@ dependencies = [ "quote", "serde", "static_assertions", - "syn 2.0.90", + "syn 2.0.91", "winnow", ] diff --git a/rog-control-center/Cargo.toml b/rog-control-center/Cargo.toml index cd28a581..5ba60663 100644 --- a/rog-control-center/Cargo.toml +++ b/rog-control-center/Cargo.toml @@ -18,8 +18,6 @@ tokio-debug = ["console-subscriber"] [dependencies] console-subscriber = { version = "^0.4", optional = true } -nix = { version = "^0.29.0", features = ["fs"] } -tempfile = "3.3.0" ksni = { version = "0.3", default-features = false, features = ["async-io"] } image = "0.25.5" diff --git a/rog-control-center/src/error.rs b/rog-control-center/src/error.rs index b1310d21..951d0b0f 100644 --- a/rog-control-center/src/error.rs +++ b/rog-control-center/src/error.rs @@ -5,7 +5,6 @@ pub type Result = std::result::Result; #[derive(Debug)] pub enum Error { Io(std::io::Error), - Nix(nix::Error), ConfigLoadFail, ConfigLockFail, XdgVars, @@ -18,7 +17,6 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::Io(err) => write!(f, "Failed to open: {}", err), - Error::Nix(err) => write!(f, "Error: {}", err), Error::ConfigLoadFail => write!(f, "Failed to load user config"), Error::ConfigLockFail => write!(f, "Failed to lock user config"), Error::XdgVars => write!(f, "XDG environment vars appear unset"), @@ -36,12 +34,6 @@ impl From for Error { } } -impl From for Error { - fn from(err: nix::Error) -> Self { - Error::Nix(err) - } -} - impl From for Error { fn from(err: zbus::Error) -> Self { Error::Zbus(err) diff --git a/rog-control-center/src/lib.rs b/rog-control-center/src/lib.rs index 4cce391a..28271360 100644 --- a/rog-control-center/src/lib.rs +++ b/rog-control-center/src/lib.rs @@ -2,14 +2,8 @@ #![allow(clippy::redundant_clone, clippy::cmp_owned)] slint::include_modules!(); -// Intentionally reexport slint so that GUI consumers don't need to add to -// `Cargo.toml` -use std::fs::{remove_dir_all, File, OpenOptions}; -use std::io::{Read, Write}; -use std::process::exit; -use std::thread::sleep; -use std::time::Duration; - +/// Intentionally reexport slint so that GUI consumers don't need to add to +/// `Cargo.toml` pub use slint; pub mod cli_options; @@ -21,11 +15,7 @@ pub mod notify; pub mod tray; pub mod types; pub mod ui; - -use nix::sys::stat; -use nix::unistd; -use tempfile::TempDir; -// use log::{error, info, warn}; +pub mod zbus; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const APP_ICON_PATH: &str = "/usr/share/icons/hicolor/512x512/apps/rog-control-center.png"; @@ -42,10 +32,6 @@ pub fn print_versions() { println!("rog-platform v{}", rog_platform::VERSION); } -pub const SHOWING_GUI: u8 = 1; -pub const SHOW_GUI: u8 = 2; -pub const QUIT_APP: u8 = 3; - #[derive(PartialEq, Eq, Clone, Copy)] pub enum Page { AppSettings, @@ -54,59 +40,3 @@ pub enum Page { AnimeMatrix, FanCurves, } - -/// Either exit the process, or return with a refreshed tmp-dir -pub fn on_tmp_dir_exists() -> Result { - let mut buf = [0u8; 2]; - let path = std::env::temp_dir().join("rog-gui"); - - if path.read_dir()?.next().is_none() { - std::fs::remove_dir_all(path)?; - return tempfile::Builder::new() - .prefix("rog-gui") - .rand_bytes(0) - .tempdir(); - } - - let mut ipc_file = OpenOptions::new() - .read(true) - .write(true) - .create(false) - .open(path.join("ipc.pipe"))?; - - // If the app is running this ends up stacked on top of SHOWING_GUI - ipc_file.write_all(&[SHOW_GUI, 0])?; - // tiny sleep to give the app a chance to respond - sleep(Duration::from_millis(10)); - ipc_file.read_exact(&mut buf).ok(); - - // First entry is the actual state - if buf[0] == SHOWING_GUI { - ipc_file.write_all(&[SHOWING_GUI, 0])?; // Store state again as we drained the fifo - // Early exit is not an error and we don't want to pass back a dir - #[allow(clippy::exit)] - exit(0); - } else if buf[0] == SHOW_GUI { - remove_dir_all(&path)?; - return tempfile::Builder::new() - .prefix("rog-gui") - .rand_bytes(0) - .tempdir(); - } - panic!("Invalid exit or app state"); -} - -pub fn get_ipc_file() -> Result { - let tmp_dir = std::env::temp_dir().join("rog-gui"); - let fifo_path = tmp_dir.join("ipc.pipe"); - if let Err(e) = unistd::mkfifo(&fifo_path, stat::Mode::S_IRWXU) { - if !matches!(e, nix::errno::Errno::EEXIST) { - Err(e)? - } - } - Ok(OpenOptions::new() - .read(true) - .write(true) - // .truncate(true) - .open(&fifo_path)?) -} diff --git a/rog-control-center/src/main.rs b/rog-control-center/src/main.rs index 9423b56d..c6180d56 100644 --- a/rog-control-center/src/main.rs +++ b/rog-control-center/src/main.rs @@ -1,6 +1,5 @@ use std::borrow::BorrowMut; use std::env::args; -use std::io::{Read, Write}; use std::path::{Path, PathBuf}; use std::process::exit; use std::sync::{Arc, Mutex}; @@ -10,7 +9,7 @@ use std::time::Duration; use config_traits::{StdConfig, StdConfigLoad1}; use dmi_id::DMIID; use gumdrop::Options; -use log::{info, LevelFilter}; +use log::{info, warn, LevelFilter}; use rog_control_center::cli_options::CliStart; use rog_control_center::config::Config; use rog_control_center::error::Result; @@ -18,41 +17,71 @@ use rog_control_center::notify::start_notifications; use rog_control_center::slint::ComponentHandle; use rog_control_center::tray::init_tray; use rog_control_center::ui::setup_window; -use rog_control_center::{ - get_ipc_file, on_tmp_dir_exists, print_versions, MainWindow, QUIT_APP, SHOWING_GUI, SHOW_GUI, +use rog_control_center::zbus::{ + AppState, ROGCCZbus, ROGCCZbusProxyBlocking, ZBUS_IFACE, ZBUS_PATH, }; +use rog_control_center::{print_versions, MainWindow}; use tokio::runtime::Runtime; #[tokio::main] async fn main() -> Result<()> { - #[cfg(feature = "tokio-debug")] - console_subscriber::init(); + let mut logger = env_logger::Builder::new(); + logger + .filter_level(LevelFilter::Warn) + .parse_default_env() + .target(env_logger::Target::Stdout) + .format_timestamp(None) + .init(); + // Try to open a proxy and check for app state first + { + let user_con = zbus::blocking::Connection::session()?; + if let Ok(proxy) = ROGCCZbusProxyBlocking::new(&user_con) { + if let Ok(state) = proxy.state() { + info!("App is already running: {state:?}, opening the window"); + // if there is a proxy connection assume the app is already running + proxy.set_state(AppState::MainWindowShouldOpen)?; + std::process::exit(0); + } + } + } + + // version checks let self_version = env!("CARGO_PKG_VERSION"); - let conn = zbus::blocking::Connection::system()?; - let proxy = rog_dbus::zbus_platform::PlatformProxyBlocking::new(&conn)?; - let asusd_version = proxy.version().unwrap(); + let zbus_con = zbus::blocking::Connection::system()?; + let platform_proxy = rog_dbus::zbus_platform::PlatformProxyBlocking::new(&zbus_con)?; + let asusd_version = platform_proxy.version().unwrap(); if asusd_version != self_version { println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}"); return Ok(()); } + // start tokio + let rt = Runtime::new().expect("Unable to create Runtime"); + // Enter the runtime so that `tokio::spawn` is available immediately. + let _enter = rt.enter(); + + #[cfg(feature = "tokio-debug")] + console_subscriber::init(); + + let state_zbus = ROGCCZbus::new(); + let app_state = state_zbus.clone_state(); + let _conn = zbus::connection::Builder::session()? + .name(ZBUS_IFACE)? + .serve_at(ZBUS_PATH, state_zbus)? + .build() + .await + .map_err(|err| { + warn!("{}: add_to_server {}", ZBUS_PATH, err); + err + })?; + let dmi = DMIID::new().unwrap_or_default(); let board_name = dmi.board_name; let prod_family = dmi.product_family; info!("Running on {board_name}, product: {prod_family}"); let is_rog_ally = prod_family == "RC71L"; - // tmp-dir must live to the end of program life - let _tmp_dir = match tempfile::Builder::new() - .prefix("rog-gui") - .rand_bytes(0) - .tempdir() - { - Ok(tmp) => tmp, - Err(_) => on_tmp_dir_exists().unwrap(), - }; - let args: Vec = args().skip(1).collect(); let cli_parsed = match CliStart::parse_args_default(&args) { @@ -66,15 +95,7 @@ async fn main() -> Result<()> { return Ok(()); } - let mut logger = env_logger::Builder::new(); - logger - .filter_level(LevelFilter::Warn) - .parse_default_env() - .target(env_logger::Target::Stdout) - .format_timestamp(None) - .init(); - - let supported_properties = proxy.supported_properties().unwrap_or_default(); + let supported_properties = platform_proxy.supported_properties().unwrap_or_default(); // Startup let mut config = Config::new().load(); @@ -99,8 +120,6 @@ async fn main() -> Result<()> { if config.startup_in_background { config.run_in_background = true; - } else { - get_ipc_file().unwrap().write_all(&[SHOW_GUI, 0]).unwrap(); } config.write(); @@ -108,10 +127,6 @@ async fn main() -> Result<()> { let startup_in_background = config.startup_in_background; let config = Arc::new(Mutex::new(config)); - // start tokio - let rt = Runtime::new().expect("Unable to create Runtime"); - // Enter the runtime so that `tokio::spawn` is available immediately. - let _enter = rt.enter(); start_notifications(config.clone(), &rt)?; if enable_tray_icon { @@ -121,7 +136,11 @@ async fn main() -> Result<()> { thread_local! { pub static UI: std::cell::RefCell> = Default::default()}; // i_slint_backend_selector::with_platform(|_| Ok(())).unwrap(); - let mut do_once = !startup_in_background; + if !startup_in_background { + if let Ok(mut lock) = app_state.lock() { + *lock = AppState::MainWindowShouldOpen; + } + } if std::env::var("RUST_TRANSLATIONS").is_ok() { // don't care about content @@ -133,42 +152,40 @@ async fn main() -> Result<()> { } thread::spawn(move || { - let mut buf = [0u8; 2]; - // blocks until it is read, typically the read will happen after a second - // process writes to the IPC (so there is data to actually read) + let mut state = AppState::StartingUp; loop { - if do_once { - buf[0] = SHOW_GUI; - do_once = false; - } else { - get_ipc_file().unwrap().read_exact(&mut buf).unwrap(); + // save as a var, don't hold the lock the entire time or deadlocks happen + if let Ok(lock) = app_state.lock() { + state = *lock; } - if buf[0] == SHOW_GUI { - // 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 - // read the IPC before looping - get_ipc_file() - .unwrap() - .write_all(&[SHOWING_GUI, 0]) - .unwrap(); + if state == AppState::MainWindowShouldOpen { + if let Ok(mut lock) = app_state.lock() { + *lock = AppState::MainWindowOpen; + } sleep(Duration::from_millis(50)); let config_copy = config.clone(); + let app_state_copy = app_state.clone(); slint::invoke_from_event_loop(move || { UI.with(|ui| { + let app_state_copy = app_state_copy.clone(); let mut ui = ui.borrow_mut(); if let Some(ui) = ui.as_mut() { ui.window().show().unwrap(); - ui.window().on_close_requested(|| { - get_ipc_file().unwrap().write_all(&[0, 0]).unwrap(); + ui.window().on_close_requested(move || { + if let Ok(mut lock) = app_state_copy.lock() { + *lock = AppState::MainWindowClosed; + } slint::CloseRequestResponse::HideWindow }); } else { let newui = setup_window(config_copy); newui.window().show().unwrap(); - newui.window().on_close_requested(|| { - get_ipc_file().unwrap().write_all(&[0, 0]).unwrap(); + newui.window().on_close_requested(move || { + if let Ok(mut lock) = app_state_copy.lock() { + *lock = AppState::MainWindowClosed; + } slint::CloseRequestResponse::HideWindow }); ui.replace(newui); @@ -176,29 +193,26 @@ async fn main() -> Result<()> { }); }) .unwrap(); - } else { - if buf[1] == QUIT_APP { - slint::quit_event_loop().unwrap(); - exit(0); - } - if buf[0] != SHOWING_GUI { - if let Ok(lock) = config.lock() { - if !lock.run_in_background { - slint::quit_event_loop().unwrap(); - exit(0); - } + } else if state == AppState::QuitApp { + slint::quit_event_loop().unwrap(); + exit(0); + } else if state != AppState::MainWindowOpen { + if let Ok(lock) = config.lock() { + if !lock.run_in_background { + slint::quit_event_loop().unwrap(); + exit(0); } - - slint::invoke_from_event_loop(move || { - UI.with(|ui| { - let mut ui = ui.take(); - if let Some(ui) = ui.borrow_mut() { - ui.window().hide().unwrap(); - } - }); - }) - .unwrap(); } + + slint::invoke_from_event_loop(move || { + UI.with(|ui| { + let mut ui = ui.take(); + if let Some(ui) = ui.borrow_mut() { + ui.window().hide().unwrap(); + } + }); + }) + .unwrap(); } } }); diff --git a/rog-control-center/src/tray.rs b/rog-control-center/src/tray.rs index 8d7afcce..2286513e 100644 --- a/rog-control-center/src/tray.rs +++ b/rog-control-center/src/tray.rs @@ -1,22 +1,20 @@ -//! A seld-contained tray icon with menus. The control of app<->tray is done via -//! commands over an MPSC channel. +//! A self-contained tray icon with menus. use std::fs::OpenOptions; -use std::io::{Read, Write}; +use std::io::Read; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex, OnceLock}; use std::time::Duration; use ksni::{Handle, Icon, TrayMethods}; -// use betrayer::{Icon, Menu, MenuItem, TrayEvent, TrayIcon, TrayIconBuilder}; -use log::{error, info, warn}; +use log::{info, warn}; use rog_platform::platform::Properties; use supergfxctl::pci_device::{Device, GfxMode, GfxPower}; use supergfxctl::zbus_proxy::DaemonProxy as GfxProxy; use versions::Versioning; use crate::config::Config; -use crate::{get_ipc_file, QUIT_APP, SHOW_GUI}; +use crate::zbus::{AppState, ROGCCZbusProxyBlocking}; const TRAY_LABEL: &str = "ROG Control Center"; const TRAY_ICON_PATH: &str = "/usr/share/icons/hicolor/512x512/apps/"; @@ -31,15 +29,6 @@ struct Icons { static ICONS: OnceLock = OnceLock::new(); -fn toggle_app(open: bool) { - if let Ok(mut ipc) = get_ipc_file().map_err(|e| { - error!("ROGTray: get_ipc_file: {}", e); - }) { - let action = if open { SHOW_GUI } else { QUIT_APP }; - ipc.write_all(&[action, 0]).ok(); - } -} - fn read_icon(file: &Path) -> Icon { let mut path = PathBuf::from(TRAY_ICON_PATH); path.push(file); @@ -66,6 +55,7 @@ fn read_icon(file: &Path) -> Icon { struct AsusTray { current_title: String, current_icon: Icon, + proxy: ROGCCZbusProxyBlocking<'static>, } impl ksni::Tray for AsusTray { @@ -91,7 +81,9 @@ impl ksni::Tray for AsusTray { StandardItem { label: "Open ROGCC".into(), icon_name: "rog-control-center".into(), - activate: Box::new(|_| toggle_app(true)), + activate: Box::new(move |s: &mut AsusTray| { + s.proxy.set_state(AppState::MainWindowShouldOpen).ok(); + }), ..Default::default() } .into(), @@ -163,11 +155,15 @@ fn find_dgpu() -> Option { /// The tray is controlled somewhat by `Arc>` pub fn init_tray(_supported_properties: Vec, config: Arc>) { tokio::spawn(async move { + let user_con = zbus::blocking::Connection::session().unwrap(); + let proxy = ROGCCZbusProxyBlocking::new(&user_con).unwrap(); + let rog_red = read_icon(&PathBuf::from("asus_notif_red.png")); let tray = AsusTray { current_title: TRAY_LABEL.to_string(), current_icon: rog_red.clone(), + proxy, }; let mut tray = tray diff --git a/rog-control-center/src/zbus.rs b/rog-control-center/src/zbus.rs new file mode 100644 index 00000000..32050c6a --- /dev/null +++ b/rog-control-center/src/zbus.rs @@ -0,0 +1,68 @@ +use std::sync::{Arc, Mutex}; + +use zbus::zvariant::{OwnedValue, Type, Value}; +use zbus::{interface, proxy}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Type, Value, OwnedValue)] +#[zvariant(signature = "u")] +pub enum AppState { + MainWindowOpen = 0, + /// If the app is running, open the main window + MainWindowShouldOpen = 1, + MainWindowClosed = 2, + StartingUp = 3, + QuitApp = 4, + LockFailed = 5, +} + +pub struct ROGCCZbus { + state: Arc>, +} + +impl ROGCCZbus { + pub fn new() -> Self { + Self { + state: Arc::new(Mutex::new(AppState::StartingUp)), + } + } + + pub fn clone_state(&self) -> Arc> { + self.state.clone() + } +} + +pub const ZBUS_PATH: &str = "/xyz/ljones/rogcc"; +pub const ZBUS_IFACE: &str = "xyz.ljones.rogcc"; + +#[interface(name = "xyz.ljones.rogcc")] +impl ROGCCZbus { + /// Return the device type for this Aura keyboard + #[zbus(property)] + async fn state(&self) -> AppState { + if let Ok(lock) = self.state.try_lock() { + return *lock; + } + AppState::LockFailed + } + + #[zbus(property)] + async fn set_state(&self, state: AppState) { + if let Ok(mut lock) = self.state.try_lock() { + *lock = state; + } + } +} + +#[proxy( + interface = "xyz.ljones.rogcc", + default_service = "xyz.ljones.rogcc", + default_path = "/xyz/ljones/rogcc" +)] +pub trait ROGCCZbus { + /// EnableDisplay property + #[zbus(property)] + fn state(&self) -> zbus::Result; + + #[zbus(property)] + fn set_state(&self, state: AppState) -> zbus::Result<()>; +}