diff --git a/Cargo.lock b/Cargo.lock index 81befae..0e7079a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,9 +265,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" dependencies = [ "serde", ] @@ -309,7 +309,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "cairo-sys-rs", "glib", "libc", @@ -330,11 +330,11 @@ dependencies = [ [[package]] name = "calloop" -version = "0.13.0" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "log", "polling", "rustix 0.38.44", @@ -344,9 +344,9 @@ dependencies = [ [[package]] name = "calloop-wayland-source" -version = "0.3.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" dependencies = [ "calloop", "rustix 0.38.44", @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.42" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -420,9 +420,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.42" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -432,18 +432,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.55" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5abde44486daf70c5be8b8f8f1b66c49f86236edf6fa2abadb4d961c4c6229a" +checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -821,11 +821,11 @@ dependencies = [ [[package]] name = "evdev-rs" -version = "0.6.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b9cb6084eed4e72c0306e1cbcd3fd4c8acb613044e66810f9f5d3c7896bfb7" +checksum = "9812d5790fb6fcce449333eb6713dad335e8c979225ed98755c84a3987e06dba" dependencies = [ - "bitflags 2.9.1", + "bitflags 1.3.2", "evdev-sys", "libc", "log", @@ -833,9 +833,9 @@ dependencies = [ [[package]] name = "evdev-sys" -version = "0.2.6" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdcf0d489f4d9a80ac2b3b35b92fdd8fcf68d33bb67f947afe5cd36e482de576" +checksum = "14ead42b547b15d47089c1243d907bcf0eb94e457046d3b315a26ac9c9e9ea6d" dependencies = [ "cc", "libc", @@ -1203,7 +1203,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "futures-channel", "futures-core", "futures-executor", @@ -1303,7 +1303,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc759b3184830a547b31549ab40c4b54450ab702bba79ba23f049bc1d1e3ca98" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "gdk", "glib", "glib-sys 0.18.1", @@ -1525,7 +1525,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2", "tokio", "tower-service", "tracing", @@ -1755,7 +1755,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "inotify-sys", "libc", ] @@ -1775,7 +1775,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "cfg-if", "libc", ] @@ -1824,7 +1824,7 @@ dependencies = [ "notify", "regex", "reqwest", - "rustix 1.0.8", + "rustix 1.0.7", "schemars", "serde", "serde_json", @@ -1842,7 +1842,7 @@ dependencies = [ "universal-config", "walkdir", "wayland-client", - "wayland-protocols-wlr", + "wayland-protocols-wlr 0.3.8", "zbus", ] @@ -1896,9 +1896,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" [[package]] name = "libcorn" @@ -1929,7 +1929,7 @@ version = "2.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "909eb3049e16e373680fe65afe6e2a722ace06b671250cc4849557bc57d6a397" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "libc", "libpulse-sys", "num-derive", @@ -1956,7 +1956,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "libc", ] @@ -1990,9 +1990,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "lua-src" @@ -2065,9 +2065,9 @@ dependencies = [ [[package]] name = "mlua" -version = "0.11.1" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de25fc513588ac1273aa8c6dc0fffee6d32c12f38dc75f5cdc74547121a107ef" +checksum = "c1f5f8fbebc7db5f671671134b9321c4b9aa9adeafccfd9a8c020ae45c6a35d0" dependencies = [ "bstr", "either", @@ -2080,9 +2080,9 @@ dependencies = [ [[package]] name = "mlua-sys" -version = "0.8.2" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcdf7c9e260ca82aaa32ac11148941952b856bb8c69aa5a9e65962f21fcb8637" +checksum = "380c1f7e2099cafcf40e51d3a9f20a346977587aa4d012eae1f043149a728a93" dependencies = [ "cc", "cfg-if", @@ -2163,7 +2163,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "cfg-if", "cfg_aliases", "libc", @@ -2182,11 +2182,11 @@ dependencies = [ [[package]] name = "notify" -version = "8.2.0" +version = "8.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" +checksum = "3163f59cd3fa0e9ef8c32f242966a7b9994fd7378366099593e0e73077cd8c97" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "inotify", "kqueue", "libc", @@ -2254,7 +2254,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", ] [[package]] @@ -2288,7 +2288,7 @@ version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -2658,7 +2658,7 @@ version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", ] [[package]] @@ -2672,26 +2672,6 @@ dependencies = [ "thiserror 2.0.12", ] -[[package]] -name = "ref-cast" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" -dependencies = [ - "proc-macro2", - "quote 1.0.39", - "syn 2.0.99", -] - [[package]] name = "regex" version = "1.11.1" @@ -2795,7 +2775,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ "base64", - "bitflags 2.9.1", + "bitflags 2.9.0", "serde", "serde_derive", "unicode-ident", @@ -2828,7 +2808,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -2837,15 +2817,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.9.3", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -2910,13 +2890,11 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.4" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" dependencies = [ "dyn-clone", - "indexmap", - "ref-cast", "schemars_derive", "serde", "serde_json", @@ -2924,9 +2902,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.0.4" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d020396d1d138dc19f1165df7545479dcd58d93810dc5d646a16e55abefa80" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" dependencies = [ "proc-macro2", "quote 1.0.39", @@ -2946,7 +2924,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "core-foundation", "core-foundation-sys", "libc", @@ -3002,9 +2980,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -3115,11 +3093,11 @@ checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "smithay-client-toolkit" -version = "0.19.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "calloop", "calloop-wayland-source", "cursor-icon", @@ -3132,8 +3110,8 @@ dependencies = [ "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols", - "wayland-protocols-wlr", + "wayland-protocols 0.31.2", + "wayland-protocols-wlr 0.2.0", "wayland-scanner", "xkeysym", ] @@ -3148,16 +3126,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "socket2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -3286,9 +3254,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.36.1" +version = "0.35.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d" +checksum = "3c3ffa3e4ff2b324a57f7aeb3c349656c7b127c3c189520251a648102a92496e" dependencies = [ "libc", "memchr", @@ -3326,11 +3294,10 @@ dependencies = [ [[package]] name = "system-tray" -version = "0.8.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90d5d024b1573d22079347055d817863c21ea0903df404668095499c08800e4a" +checksum = "c3397841ed755bf361606a845779e0f7333d35fb4e39627ef6f656d7cdad4c73" dependencies = [ - "cfg-if", "dbusmenu-gtk3-sys", "futures-lite", "gtk", @@ -3454,9 +3421,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.47.1" +version = "1.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" dependencies = [ "backtrace", "bytes", @@ -3466,10 +3433,10 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "slab", - "socket2 0.6.0", + "socket2", "tokio-macros", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3604,7 +3571,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cc2d9e086a412a451384326f521c8123a99a466b329941a9403696bff9b0da2" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "bytes", "futures-util", "http", @@ -3962,25 +3929,25 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.11" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" +checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" dependencies = [ "cc", "downcast-rs", - "rustix 1.0.8", + "rustix 0.38.44", "smallvec", "wayland-sys", ] [[package]] name = "wayland-client" -version = "0.31.11" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" +checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" dependencies = [ - "bitflags 2.9.1", - "rustix 1.0.8", + "bitflags 2.9.0", + "rustix 0.38.44", "wayland-backend", "wayland-scanner", ] @@ -3991,7 +3958,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "cursor-icon", "wayland-backend", ] @@ -4009,11 +3976,23 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.9" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" +dependencies = [ + "bitflags 2.9.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4021,22 +4000,35 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.9" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "wayland-backend", "wayland-client", - "wayland-protocols", + "wayland-protocols 0.31.2", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" +dependencies = [ + "bitflags 2.9.0", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.8", "wayland-scanner", ] [[package]] name = "wayland-scanner" -version = "0.31.7" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" +checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" dependencies = [ "proc-macro2", "quick-xml", @@ -4045,9 +4037,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.7" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" +checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" dependencies = [ "pkg-config", ] @@ -4382,7 +4374,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", ] [[package]] @@ -4435,9 +4427,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.9.0" +version = "5.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb4f9a464286d42851d18a605f7193b8febaf5b0919d71c6399b7b26e5b0aad" +checksum = "d3a7c7cee313d044fca3f48fa782cb750c79e4ca76ba7bc7718cd4024cdf6f68" dependencies = [ "async-broadcast", "async-recursion", @@ -4463,9 +4455,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.9.0" +version = "5.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef9859f68ee0c4ee2e8cde84737c78e3f4c54f946f2a38645d0d4c7a95327659" +checksum = "a17e7e5eec1550f747e71a058df81a9a83813ba0f6a95f39c4e218bdc7ba366a" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 366d3b3..5fcc87e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,7 +115,7 @@ schema = ["dep:schemars"] gtk = "0.18.2" gtk-layer-shell = "0.8.2" glib = "0.18.5" -tokio = { version = "1.47.1", features = [ +tokio = { version = "1.46.1", features = [ "macros", "rt-multi-thread", "time", @@ -132,13 +132,13 @@ tracing-appender = "0.2.3" strip-ansi-escapes = "0.2.0" color-eyre = "0.6.5" serde = { version = "1.0.219", features = ["derive"] } -indexmap = { version = "2.10.0", features = ["serde"] } +indexmap = "2.10.0" dirs = "6.0.0" walkdir = "2.5.0" -notify = { version = "8.2.0", default-features = false } +notify = { version = "8.1.0", default-features = false } wayland-client = "0.31.1" -wayland-protocols-wlr = { version = "0.3.9", features = ["client"] } -smithay-client-toolkit = { version = "0.19.2", default-features = false, features = [ +wayland-protocols-wlr = { version = "0.3.8", features = ["client"] } +smithay-client-toolkit = { version = "0.18.1", default-features = false, features = [ "calloop", ] } universal-config = { version = "0.5.1", default-features = false } @@ -146,14 +146,14 @@ ctrlc = "3.4.7" cfg-if = "1.0.1" # cli -clap = { version = "4.5.42", optional = true, features = ["derive"] } +clap = { version = "4.5.40", optional = true, features = ["derive"] } # http reqwest = { version = "0.12.22", default-features = false, features = ["default-tls", "http2"], optional = true } # cairo lua-src = { version = "548.1.1", optional = true } -mlua = { version = "0.11.1", optional = true, features = ["luajit", "send"] } +mlua = { version = "0.10.5", optional = true, features = ["luajit", "send"] } cairo-rs = { version = "0.18.5", optional = true, features = ["png"] } # clock @@ -161,7 +161,7 @@ chrono = { version = "0.4.41", optional = true, default-features = false, featur # keyboard colpetto = { version = "0.6.0", features = ["tokio", "tracing"], optional = true } -evdev-rs = { version = "0.6.2", optional = true } +evdev-rs = { version = "0.6.1", optional = true } # music mpd-utils = { version = "0.2.1", optional = true } @@ -174,28 +174,27 @@ regex = { version = "1.11.1", default-features = false, features = [ tokio-stream = { version = "0.1.17", optional = true } # sys_info -sysinfo = { version = "0.36.1", optional = true } +sysinfo = { version = "0.35.2", optional = true } # tray -system-tray = { version = "0.8.1", features = ["dbusmenu-gtk3"], optional = true } +system-tray = { version = "0.7.0", features = ["dbusmenu-gtk3"], optional = true } # volume libpulse-binding = { version = "2.30.1", optional = true } # shared futures-lite = { version = "2.6.0", optional = true } # network_manager, upower, workspaces, keyboard -zbus = { version = "5.9.0", default-features = false, features = ["tokio"], optional = true } # network_manager, notifications, upower +zbus = { version = "5.7.1", default-features = false, features = ["blocking-api", "tokio"], optional = true } # network_manager, notifications, upower swayipc-async = { version = "2.1.0", optional = true } # workspaces, keyboard hyprland = { version = "0.4.0-beta.2", optional = true } # workspaces, keyboard -rustix = { version = "1.0.8", default-features = false, features = ["std", "fs", "pipe", "event"], optional = true } # clipboard, input -serde_json = { version = "1.0.142", optional = true } # ipc, niri +rustix = { version = "1.0.7", default-features = false, features = ["std", "fs", "pipe", "event"], optional = true } # clipboard, input +serde_json = { version = "1.0.140", optional = true } # ipc, niri # schema - -schemars = { version = "1.0.4", optional = true, features = ["indexmap2"] } +schemars = { version = "0.8.22", optional = true } [build-dependencies] -clap = { version = "4.5.42", features = ["derive"] } -clap_complete = "4.5.55" +clap = { version = "4.5.40", features = ["derive"] } +clap_complete = "4.5.54" serde = { version = "1.0.219", features = ["derive"] } -serde_json = "1.0.142" \ No newline at end of file +serde_json = "1.0.140" \ No newline at end of file diff --git a/docs/Controlling Ironbar.md b/docs/Controlling Ironbar.md index a3e2662..49d1f8c 100644 --- a/docs/Controlling Ironbar.md +++ b/docs/Controlling Ironbar.md @@ -35,11 +35,13 @@ All error responses will cause the CLI to exit code 3. The server listens on a Unix socket. The path is printed on startup, and can usually be found at `/run/user/$UID/ironbar-ipc.sock`. -Commands and responses are sent as JSON objects. -The JSON should be minified and must NOT contain any `\n` characters. +Commands and responses are sent as JSON objects. Commands will have a `command` key, and a `subcommand` key when part of a sub-command. +The message buffer is currently limited to `1024` bytes. +Particularly large messages will be truncated or cause an error. + The full spec can be found below. ## Libraries diff --git a/docs/modules/Keyboard.md b/docs/modules/Keyboard.md index 5afe07d..3dbdebf 100644 --- a/docs/modules/Keyboard.md +++ b/docs/modules/Keyboard.md @@ -25,7 +25,7 @@ Displays the toggle state of the capslock, num lock and scroll lock keys, and th | `icons.num_off` | `string` or [image](images) | `''` | Icon to show for disabled num lock indicator. | | `icons.scroll_on` | `string` or [image](images) | `` | Icon to show for enabled scroll lock indicator. | | `icons.scroll_off` | `string` or [image](images) | `''` | Icon to show for disabled scroll lock indicator. | -| `icons.layout_map` | `Map` | `{}` | Map of icons or labels to show for a particular keyboard layout. Layouts use their actual name if not present in the map. Layouts are matched in the order they appear in the map. If a pattern to match ends with a `*`, it acts as a wildcard, matching any layout name that begins with the part before the `*`. | +| `icons.layout_map` | `Map` | `{}` | Map of icons or labels to show for a particular keyboard layout. Layouts use their actual name if not present in the map. | | `seat` | `string` | `seat0` | ID of the Wayland seat to attach to. |
diff --git a/docs/modules/Sys-Info.md b/docs/modules/Sys-Info.md index 18cc1b2..d26364d 100644 --- a/docs/modules/Sys-Info.md +++ b/docs/modules/Sys-Info.md @@ -194,12 +194,12 @@ The list of available functions is shown below: It is also possible to get only a single value from the set by specifying a name instead of a function. -| Token category | Valid name | -|----------------|------------------------------------------| -| CPU | A CPU thread, eg `cpu0`, `cpu1`, ... | -| Temperature | A sensor name, eg `CPUTIN`. | -| Disk | A disk mountpoint, eg `/`, `/home`, ... | -| Network | An adapter name, eg `eth0` or `enp30s0`. | +| Token category | Valid name | +|----------------|-------------------------------------------------------------------------| +| CPU | A CPU thread, eg `cpu0`, `cpu1`, ... | +| Temperature | A sensor name, eg `CPUTIN`. These line up with the output of `sensors`. | +| Disk | A disk mountpoint, eg `/`, `/home`, ... | +| Network | An adapter name, eg `eth0` or `enp30s0`. | To specify a name or function, use a `@`. For example, to show disk percent for `/home`: @@ -214,22 +214,6 @@ To show total CPU utilization where each core represents 100% (like `htop` etc): "{cpu_percent@sum}%" ``` -> [!TIP] -> Available values can be queried over IPC using the CLI. -> This can be particularly useful for sensors, which tend not to have obvious names. -> -> ```shell -> ironbar var list sysinfo.temp_c -> ``` -> -> Some usual cases to look out for: -> -> - `k10temp` is an AMD CPU internal sensor -> - Motherboard chipsets tend to prefix their sensors accordingly. For example, `CPUTIN`, `nct6687 CPU`, `asusec AMD`. -> - `amdgpu` is as it suggests. -> -> Sensor names are pulled from `hwmon` and should vaguely line up with the output of `sensors` - #### Prefixes and units For tokens which return an appropriate unit, you can specify the SI prefix (or unit in some special cases). diff --git a/flake.lock b/flake.lock index 8c4c1ce..bd7abc9 100644 --- a/flake.lock +++ b/flake.lock @@ -1,27 +1,5 @@ { "nodes": { - "fenix": { - "inputs": { - "nixpkgs": [ - "naersk", - "nixpkgs" - ], - "rust-analyzer-src": "rust-analyzer-src" - }, - "locked": { - "lastModified": 1752475459, - "narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=", - "owner": "nix-community", - "repo": "fenix", - "rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "fenix", - "type": "github" - } - }, "flake-compat": { "locked": { "lastModified": 1747046372, @@ -39,15 +17,14 @@ }, "naersk": { "inputs": { - "fenix": "fenix", "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1752689277, - "narHash": "sha256-uldUBFkZe/E7qbvxa3mH1ItrWZyT6w1dBKJQF/3ZSsc=", + "lastModified": 1745925850, + "narHash": "sha256-cyAAMal0aPrlb1NgzMxZqeN1mAJ2pJseDhm2m6Um8T0=", "owner": "nix-community", "repo": "naersk", - "rev": "0e72363d0938b0208d6c646d10649164c43f4d64", + "rev": "38bc60bbc157ae266d4a0c96671c6c742ee17a5f", "type": "github" }, "original": { @@ -73,11 +50,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1752077645, - "narHash": "sha256-HM791ZQtXV93xtCY+ZxG1REzhQenSQO020cu6rHtAPk=", + "lastModified": 1751251929, + "narHash": "sha256-IJWIzZSkBsDzS7iS/iwSwur+xFkWqeLYC4kdf8ObtOM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "be9e214982e20b8310878ac2baa063a961c1bdf6", + "rev": "b95255df2360a45ddbb03817a68869d5cb01bf96", "type": "github" }, "original": { @@ -89,11 +66,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1753694789, - "narHash": "sha256-cKgvtz6fKuK1Xr5LQW/zOUiAC0oSQoA9nOISB0pJZqM=", + "lastModified": 1751011381, + "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "dc9637876d0dcc8c9e5e22986b857632effeb727", + "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", "type": "github" }, "original": { @@ -110,23 +87,6 @@ "nix-systems": "nix-systems", "nixpkgs": "nixpkgs_2" } - }, - "rust-analyzer-src": { - "flake": false, - "locked": { - "lastModified": 1752428706, - "narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "591e3b7624be97e4443ea7b5542c191311aa141d", - "type": "github" - }, - "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", - "type": "github" - } } }, "root": "root", diff --git a/src/clients/networkmanager/mod.rs b/src/clients/networkmanager/mod.rs index 94cb82d..1a25183 100644 --- a/src/clients/networkmanager/mod.rs +++ b/src/clients/networkmanager/mod.rs @@ -44,7 +44,7 @@ impl Client { spawn(watch_device(added_device.to_owned(), tx.clone())); } - let _removed_devices = devices.difference(&new_devices); + let removed_devices = devices.difference(&new_devices); // TODO: Cook up some way to notify closures for removed devices to exit devices = new_devices; diff --git a/src/clients/networkmanager/state.rs b/src/clients/networkmanager/state.rs new file mode 100644 index 0000000..9e5c4e4 --- /dev/null +++ b/src/clients/networkmanager/state.rs @@ -0,0 +1,165 @@ +use crate::clients::networkmanager::dbus::{ + ActiveConnectionDbusProxy, DeviceDbusProxy, DeviceState, DeviceType, +}; +use color_eyre::Result; +use std::collections::HashMap; +use zbus::zvariant::ObjectPath; + +type PathMap<'l, ValueType> = HashMap, ValueType>; + +#[derive(Clone, Debug)] +pub struct State { + pub wired: WiredState, + pub wifi: WifiState, + pub cellular: CellularState, + pub vpn: VpnState, +} + +#[derive(Clone, Debug)] +pub enum WiredState { + Connected, + Disconnected, + NotPresent, + Unknown, +} + +#[derive(Clone, Debug)] +pub enum WifiState { + Connected(WifiConnectedState), + Disconnected, + Disabled, + NotPresent, + Unknown, +} + +#[derive(Clone, Debug)] +pub struct WifiConnectedState { + pub ssid: String, +} + +#[derive(Clone, Debug)] +pub enum CellularState { + Connected, + Disconnected, + Disabled, + NotPresent, + Unknown, +} + +#[derive(Clone, Debug)] +pub enum VpnState { + Connected(VpnConnectedState), + Disconnected, + Unknown, +} + +#[derive(Clone, Debug)] +pub struct VpnConnectedState { + pub name: String, +} + +pub(super) async fn determine_wired_state( + devices: &PathMap<'_, DeviceDbusProxy<'_>>, +) -> Result { + let mut present = false; + let mut connected = false; + + for device in devices.values() { + if device.device_type().await? == DeviceType::Ethernet { + present = true; + if device.state().await?.is_enabled() { + connected = true; + break; + } + } + } + + if connected { + Ok(WiredState::Connected) + } else if present { + Ok(WiredState::Disconnected) + } else { + Ok(WiredState::NotPresent) + } +} + +pub(super) async fn determine_wifi_state( + devices: &PathMap<'_, DeviceDbusProxy<'_>>, +) -> Result { + let mut present = false; + let mut enabled = false; + let mut connected = false; + + for device in devices.values() { + if device.device_type().await? == DeviceType::Wifi { + present = true; + if device.state().await?.is_enabled() { + enabled = true; + if device.state().await? == DeviceState::Activated { + connected = true; + break; + } + } + } + } + + if connected { + Ok(WifiState::Connected(WifiConnectedState { + // TODO: Implement obtaining SSID + ssid: "unknown".into(), + })) + } else if enabled { + Ok(WifiState::Disconnected) + } else if present { + Ok(WifiState::Disabled) + } else { + Ok(WifiState::NotPresent) + } +} + +pub(super) async fn determine_cellular_state( + devices: &PathMap<'_, DeviceDbusProxy<'_>>, +) -> Result { + let mut present = false; + let mut enabled = false; + let mut connected = false; + + for device in devices.values() { + if device.device_type().await? == DeviceType::Modem { + present = true; + if device.state().await?.is_enabled() { + enabled = true; + if device.state().await? == DeviceState::Activated { + connected = true; + break; + } + } + } + } + + if connected { + Ok(CellularState::Connected) + } else if enabled { + Ok(CellularState::Disconnected) + } else if present { + Ok(CellularState::Disabled) + } else { + Ok(CellularState::NotPresent) + } +} + +pub(super) async fn determine_vpn_state( + active_connections: &PathMap<'_, ActiveConnectionDbusProxy<'_>>, +) -> Result { + for connection in active_connections.values() { + match connection.type_().await?.as_str() { + "vpn" | "wireguard" => { + return Ok(VpnState::Connected(VpnConnectedState { + name: "unknown".into(), + })); + } + _ => {} + } + } + Ok(VpnState::Disconnected) +} diff --git a/src/config/impl.rs b/src/config/impl.rs index 2f13c16..dd64599 100644 --- a/src/config/impl.rs +++ b/src/config/impl.rs @@ -52,11 +52,16 @@ where } #[cfg(feature = "schema")] -pub fn schema_layer(_generator: &mut schemars::SchemaGenerator) -> schemars::Schema { - schemars::json_schema!({ - "type": "string", - "enum": ["background", "bottom", "top", "overlay"], - }) +pub fn schema_layer(generator: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema { + use schemars::JsonSchema; + let mut schema: schemars::schema::SchemaObject = ::json_schema(generator).into(); + schema.enum_values = Some(vec![ + "background".into(), + "bottom".into(), + "top".into(), + "overlay".into(), + ]); + schema.into() } impl BarPosition { diff --git a/src/desktop_file.rs b/src/desktop_file.rs index f6e9d61..8b0a509 100644 --- a/src/desktop_file.rs +++ b/src/desktop_file.rs @@ -3,10 +3,9 @@ use color_eyre::{Help, Report, Result}; use std::collections::HashMap; use std::env; use std::path::{Path, PathBuf}; -use std::process::Stdio; +use std::process::{Command, Stdio}; use std::sync::Arc; use tokio::io::{AsyncBufReadExt, BufReader}; -use tokio::process::Command; use tokio::sync::Mutex; use tracing::{debug, error}; use walkdir::{DirEntry, WalkDir}; @@ -239,7 +238,6 @@ impl DesktopFiles { /// Checks file contents for an exact or partial match of the provided input. async fn find_by_file_contents(&self, app_id: &str) -> Result> { let mut files = self.files.lock().await; - let app_id_lower = app_id.to_lowercase(); // first pass - check name for exact match for (_, file_ref) in files.iter_mut() { @@ -255,7 +253,7 @@ impl DesktopFiles { for (_, file_ref) in files.iter_mut() { let file = file_ref.get().await?; if let Some(name) = &file.name { - if name.to_lowercase().contains(&app_id_lower) { + if name.to_lowercase().contains(app_id) { return Ok(Some(file)); } } @@ -266,19 +264,19 @@ impl DesktopFiles { let file = file_ref.get().await?; if let Some(name) = &file.exec { - if name.to_lowercase().contains(&app_id_lower) { + if name.to_lowercase().contains(app_id) { return Ok(Some(file)); } } if let Some(name) = &file.startup_wm_class { - if name.to_lowercase().contains(&app_id_lower) { + if name.to_lowercase().contains(app_id) { return Ok(Some(file)); } } if let Some(name) = &file.icon { - if name.to_lowercase().contains(&app_id_lower) { + if name.to_lowercase().contains(app_id) { return Ok(Some(file)); } } @@ -327,37 +325,21 @@ fn files(dir: &Path) -> Vec { } /// Starts a `.desktop` file with the provided formatted command. -pub async fn open_program(file_name: &str, launch_command: &str) { - let expanded = launch_command.replace("{app_name}", file_name); +pub fn open_program(file_name: &str, str: &str) { + let expanded = str.replace("{app_name}", file_name); let launch_command_parts: Vec<&str> = expanded.split_whitespace().collect(); - - debug!("running {launch_command_parts:?}"); - let exit_status = match Command::new(launch_command_parts[0]) + if let Err(err) = Command::new(&launch_command_parts[0]) .args(&launch_command_parts[1..]) - .stdin(Stdio::null()) .stdout(Stdio::null()) .stderr(Stdio::null()) - .kill_on_drop(true) .spawn() { - Ok(mut child) => Some(child.wait().await), - Err(err) => { - error!( - "{:?}", - Report::new(err) - .wrap_err("Failed to run launch command.") - .suggestion("Perhaps the desktop file is invalid or orphaned?") - ); - None - } - }; - - match exit_status { - Some(Ok(exit_status)) if !exit_status.success() => { - error!("received non-success exit status running {launch_command_parts:?}") - } - Some(Err(err)) => error!("{err:?}"), - _ => {} + error!( + "{:?}", + Report::new(err) + .wrap_err("Failed to run launch command.") + .suggestion("Perhaps the applications file is invalid?") + ); } } diff --git a/src/ipc/client.rs b/src/ipc/client.rs index 6abf6d4..820ace5 100644 --- a/src/ipc/client.rs +++ b/src/ipc/client.rs @@ -2,7 +2,7 @@ use super::Ipc; use crate::ipc::{Command, Response}; use color_eyre::Result; use color_eyre::{Help, Report}; -use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::UnixStream; impl Ipc { @@ -16,20 +16,18 @@ impl Ipc { .suggestion("Is Ironbar running?")), }?; - let mut write_buffer = serde_json::to_vec(&command)?; + let write_buffer = serde_json::to_vec(&command)?; if debug { eprintln!("REQUEST JSON: {}", serde_json::to_string(&command)?); } - write_buffer.push(b'\n'); stream.write_all(&write_buffer).await?; - let mut read_buffer = String::new(); - let mut reader = BufReader::new(stream); - let bytes = reader.read_line(&mut read_buffer).await?; + let mut read_buffer = vec![0; 1024]; + let bytes = stream.read(&mut read_buffer).await?; - let response = serde_json::from_str(&read_buffer[..bytes])?; + let response = serde_json::from_slice(&read_buffer[..bytes])?; Ok(response) } } diff --git a/src/ipc/server/mod.rs b/src/ipc/server/mod.rs index 6e20404..0f944b7 100644 --- a/src/ipc/server/mod.rs +++ b/src/ipc/server/mod.rs @@ -8,10 +8,10 @@ use std::rc::Rc; use color_eyre::{Report, Result}; use gtk::Application; use gtk::prelude::*; -use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::{UnixListener, UnixStream}; use tokio::sync::mpsc::{self, Receiver, Sender}; -use tracing::{debug, error, info, trace, warn}; +use tracing::{debug, error, info, warn}; use super::Ipc; use crate::channels::{AsyncSenderExt, MpscReceiverExt}; @@ -52,13 +52,11 @@ impl Ipc { loop { match listener.accept().await { Ok((stream, _addr)) => { - debug!("handling incoming connection"); if let Err(err) = Self::handle_connection(stream, &cmd_tx, &mut res_rx).await { error!("{err:?}"); } - debug!("done"); } Err(err) => { error!("{err:?}"); @@ -82,16 +80,10 @@ impl Ipc { cmd_tx: &Sender, res_rx: &mut Receiver, ) -> Result<()> { - trace!("awaiting readable state"); - stream.readable().await?; + let (mut stream_read, mut stream_write) = stream.split(); - let mut read_buffer = Vec::with_capacity(1024); - - let mut reader = BufReader::new(&mut stream); - - trace!("reading bytes"); - let bytes = reader.read_until(b'\n', &mut read_buffer).await?; - debug!("read {} bytes", bytes); + let mut read_buffer = vec![0; 1024]; + let bytes = stream_read.read(&mut read_buffer).await?; // FIXME: Error on invalid command let command = serde_json::from_slice::(&read_buffer[..bytes])?; @@ -103,18 +95,10 @@ impl Ipc { .recv() .await .unwrap_or(Response::Err { message: None }); + let res = serde_json::to_vec(&res)?; - let mut res = serde_json::to_vec(&res)?; - res.push(b'\n'); - - trace!("awaiting writable state"); - stream.writable().await?; - - debug!("writing {} bytes", res.len()); - stream.write_all(&res).await?; - - trace!("bytes written, shutting down stream"); - stream.shutdown().await?; + stream_write.write_all(&res).await?; + stream_write.shutdown().await?; Ok(()) } diff --git a/src/modules/keyboard.rs b/src/modules/keyboard.rs index 2f1971f..145422f 100644 --- a/src/modules/keyboard.rs +++ b/src/modules/keyboard.rs @@ -1,7 +1,8 @@ +use std::collections::HashMap; + use color_eyre::Result; use color_eyre::eyre::Report; use gtk::prelude::*; -use indexmap::IndexMap; use serde::Deserialize; use tokio::sync::mpsc; use tracing::{debug, trace}; @@ -128,7 +129,7 @@ struct Icons { /// } /// ``` #[serde(default)] - layout_map: IndexMap, + layout_map: HashMap, } impl Default for Icons { @@ -140,7 +141,7 @@ impl Default for Icons { num_off: String::new(), scroll_on: default_icon_scroll(), scroll_off: String::new(), - layout_map: IndexMap::new(), + layout_map: HashMap::new(), } } } @@ -337,19 +338,7 @@ impl Module for KeyboardModule { } } KeyboardUpdate::Layout(KeyboardLayoutUpdate(language)) => { - let text = icons - .layout_map - .iter() - .find_map(|(pattern, display_text)| { - let is_match = if pattern.ends_with("*") { - language.starts_with(&pattern[..pattern.len() - 1]) - } else { - pattern == &language - }; - - is_match.then(|| display_text) - }) - .unwrap_or(&language); + let text = icons.layout_map.get(&language).unwrap_or(&language); layout_button.set_label(text); } }); diff --git a/src/modules/launcher/mod.rs b/src/modules/launcher/mod.rs index 7c38100..0bdfbb2 100644 --- a/src/modules/launcher/mod.rs +++ b/src/modules/launcher/mod.rs @@ -244,43 +244,21 @@ impl Module for LauncherModule { let tx2 = context.tx.clone(); let wl = context.client::(); - let desktop_files = context.ironbar.desktop_files(); spawn(async move { let items = items2; let tx = tx2; - // Build app_id mapping once at startup - let mut app_id_map = IndexMap::::new(); - { - let favorites: Vec<_> = lock!(items).keys().cloned().collect(); - for fav in favorites { - if let Ok(Some(file)) = desktop_files.find(&fav).await { - if let Some(wm_class) = file.startup_wm_class { - app_id_map.insert(wm_class, fav); - } - } - } - } - - let resolve_app_id = |app_id: &str| { - app_id_map - .get(app_id) - .cloned() - .unwrap_or_else(|| app_id.to_string()) - }; - let mut wlrx = wl.subscribe_toplevels(); let handles = wl.toplevel_info_all(); for info in handles { let mut items = lock!(items); - let app_id = resolve_app_id(&info.app_id); - if let Some(item) = items.get_mut(&app_id) { + let item = items.get_mut(&info.app_id); + if let Some(item) = item { item.merge_toplevel(info.clone()); } else { - let mut item = Item::from(info.clone()); - item.app_id = app_id.clone(); - items.insert(app_id, item); + let item = Item::from(info.clone()); + items.insert(info.app_id.clone(), item); } } @@ -306,14 +284,14 @@ impl Module for LauncherModule { match event { ToplevelEvent::New(info) => { - let app_id = resolve_app_id(&info.app_id); + let app_id = info.app_id.clone(); let new_item = { let mut items = lock!(items); - match items.get_mut(&app_id) { + let item = items.get_mut(&info.app_id); + match item { None => { - let mut item: Item = info.into(); - item.app_id = app_id.clone(); + let item: Item = info.into(); items.insert(app_id.clone(), item.clone()); ItemOrWindow::Item(item) @@ -335,10 +313,9 @@ impl Module for LauncherModule { }?; } ToplevelEvent::Update(info) => { - let app_id = resolve_app_id(&info.app_id); // check if open, as updates can be sent as program closes // if it's a focused favourite closing, it otherwise incorrectly re-focuses. - let is_open = if let Some(item) = lock!(items).get_mut(&app_id) { + let is_open = if let Some(item) = lock!(items).get_mut(&info.app_id) { item.set_window_focused(info.id, info.focused); item.set_window_name(info.id, info.title.clone()); @@ -348,27 +325,27 @@ impl Module for LauncherModule { }; send_update(LauncherUpdate::Focus( - app_id.clone(), + info.app_id.clone(), is_open && info.focused, )) .await?; send_update(LauncherUpdate::Title( - app_id.clone(), + info.app_id.clone(), info.id, info.title.clone(), )) .await?; } ToplevelEvent::Remove(info) => { - let app_id = resolve_app_id(&info.app_id); let remove_item = { let mut items = lock!(items); - match items.get_mut(&app_id) { + let item = items.get_mut(&info.app_id); + match item { Some(item) => { item.unmerge_toplevel(&info); if item.windows.is_empty() { - items.shift_remove(&app_id); + items.shift_remove(&info.app_id); Some(ItemOrWindowId::Item) } else { Some(ItemOrWindowId::Window) @@ -380,11 +357,15 @@ impl Module for LauncherModule { match remove_item { Some(ItemOrWindowId::Item) => { - send_update(LauncherUpdate::RemoveItem(app_id.clone())).await?; + send_update(LauncherUpdate::RemoveItem(info.app_id.clone())) + .await?; } Some(ItemOrWindowId::Window) => { - send_update(LauncherUpdate::RemoveWindow(app_id.clone(), info.id)) - .await?; + send_update(LauncherUpdate::RemoveWindow( + info.app_id.clone(), + info.id, + )) + .await?; } None => {} } @@ -407,7 +388,7 @@ impl Module for LauncherModule { if let ItemEvent::OpenItem(app_id) = event { match desktop_files.find(&app_id).await { Ok(Some(file)) => { - open_program(&file.file_name, &launch_command_str).await; + open_program(&file.file_name, &launch_command_str); } Ok(None) => warn!("Could not find applications file for {}", app_id), Err(err) => error!("Failed to find parse file for {}: {}", app_id, err), diff --git a/src/modules/menu/ui.rs b/src/modules/menu/ui.rs index ce47a7c..7c7cb1e 100644 --- a/src/modules/menu/ui.rs +++ b/src/modules/menu/ui.rs @@ -100,11 +100,7 @@ where let tx = tx.clone(); button.connect_clicked(move |_button| { - // TODO: this needs refactoring to call open from the controller - let file_name = file_name.clone(); - let command = command.clone(); - - spawn(async move { open_program(&file_name, &command).await }); + open_program(&file_name, &command); sub_menu.hide(); tx.send_spawn(ModuleUpdateEvent::ClosePopup); diff --git a/src/modules/networkmanager.rs b/src/modules/networkmanager.rs index ea8b8d9..8ca128b 100644 --- a/src/modules/networkmanager.rs +++ b/src/modules/networkmanager.rs @@ -122,34 +122,38 @@ async fn handle_update_events( fn get_icon_for_device_state(r#type: &DeviceType, state: &DeviceState) -> Option<&'static str> { match r#type { DeviceType::Ethernet => match state { - DeviceState::Unavailable - | DeviceState::Disconnected - | DeviceState::Prepare - | DeviceState::Config - | DeviceState::NeedAuth - | DeviceState::IpConfig - | DeviceState::IpCheck - | DeviceState::Secondaries - | DeviceState::Deactivating - | DeviceState::Failed => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::Unavailable => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::Disconnected => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::Prepare => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::Config => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::NeedAuth => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::IpConfig => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::IpCheck => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::Secondaries => Some("icon:network-wired-disconnected-symbolic"), DeviceState::Activated => Some("icon:network-wired-symbolic"), + DeviceState::Deactivating => Some("icon:network-wired-disconnected-symbolic"), + DeviceState::Failed => Some("icon:network-wired-disconnected-symbolic"), _ => None, }, DeviceType::Wifi => match state { DeviceState::Unavailable => Some("icon:network-wireless-hardware-disabled-symbolic"), - DeviceState::Disconnected - | DeviceState::Prepare - | DeviceState::Config - | DeviceState::NeedAuth - | DeviceState::IpConfig - | DeviceState::IpCheck - | DeviceState::Secondaries - | DeviceState::Deactivating - | DeviceState::Failed => Some("icon:network-wireless-offline-symbolic"), + DeviceState::Disconnected => Some("icon:network-wireless-offline-symbolic"), + DeviceState::Prepare => Some("icon:network-wireless-offline-symbolic"), + DeviceState::Config => Some("icon:network-wireless-offline-symbolic"), + DeviceState::NeedAuth => Some("icon:network-wireless-offline-symbolic"), + DeviceState::IpConfig => Some("icon:network-wireless-offline-symbolic"), + DeviceState::IpCheck => Some("icon:network-wireless-offline-symbolic"), + DeviceState::Secondaries => Some("icon:network-wireless-offline-symbolic"), DeviceState::Activated => Some("icon:network-wireless-connected-symbolic"), + DeviceState::Deactivating => Some("icon:network-wireless-offline-symbolic"), + DeviceState::Failed => Some("icon:network-wireless-offline-symbolic"), _ => None, }, - DeviceType::Tun | DeviceType::Wireguard => match state { + DeviceType::Tun => match state { + DeviceState::Activated => Some("icon:network-vpn-symbolic"), + _ => None, + }, + DeviceType::Wireguard => match state { DeviceState::Activated => Some("icon:network-vpn-symbolic"), _ => None, }, diff --git a/src/modules/tray/icon.rs b/src/modules/tray/icon.rs index e7932dd..4586f23 100644 --- a/src/modules/tray/icon.rs +++ b/src/modules/tray/icon.rs @@ -11,7 +11,6 @@ use std::collections::HashSet; use std::ffi::CStr; use std::os::raw::{c_char, c_int}; use std::ptr; -use system_tray::item::IconPixmap; /// Gets the GTK icon theme search paths by calling the FFI function. /// Conveniently returns the result as a `HashSet`. @@ -46,10 +45,10 @@ pub fn get_image( icon_theme: &IconTheme, ) -> Result { if !prefer_icons && item.icon_pixmap.is_some() { - get_image_from_pixmap(item.icon_pixmap.as_deref(), size) + get_image_from_pixmap(item, size) } else { get_image_from_icon_name(item, size, icon_theme) - .or_else(|_| get_image_from_pixmap(item.icon_pixmap.as_deref(), size)) + .or_else(|_| get_image_from_pixmap(item, size)) } } @@ -82,10 +81,12 @@ fn get_image_from_icon_name(item: &TrayMenu, size: u32, icon_theme: &IconTheme) /// which has 8 bits per sample and a bit stride of `4*width`. /// The Pixbuf expects RGBA32 format, so some channel shuffling /// is required. -fn get_image_from_pixmap(item: Option<&[IconPixmap]>, size: u32) -> Result { +fn get_image_from_pixmap(item: &TrayMenu, size: u32) -> Result { const BITS_PER_SAMPLE: i32 = 8; let pixmap = item + .icon_pixmap + .as_ref() .and_then(|pixmap| pixmap.first()) .ok_or_else(|| Report::msg("Failed to get pixmap from tray icon"))?; diff --git a/src/modules/tray/mod.rs b/src/modules/tray/mod.rs index 64893af..b0159f1 100644 --- a/src/modules/tray/mod.rs +++ b/src/modules/tray/mod.rs @@ -181,14 +181,9 @@ fn on_update( UpdateEvent::AttentionIcon(_icon) => { warn!("received unimplemented NewAttentionIcon event"); } - UpdateEvent::Icon { - icon_name, - icon_pixmap, - } => { - menu_item.icon_pixmap = icon_pixmap; - - if icon_name.as_ref() != menu_item.icon_name() { - menu_item.set_icon_name(icon_name); + UpdateEvent::Icon(icon) => { + if icon.as_ref() != menu_item.icon_name() { + menu_item.set_icon_name(icon); match icon::get_image(menu_item, icon_size, prefer_icons, icon_theme) { Ok(image) => menu_item.set_image(&image), Err(_) => menu_item.show_label(),