diff --git a/Cargo.lock b/Cargo.lock index 3ac7d230..26a5a99f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -249,7 +249,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -278,13 +278,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -318,9 +318,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" @@ -349,6 +349,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -403,9 +409,9 @@ dependencies = [ [[package]] name = "brotli" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -430,9 +436,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "byteorder" @@ -518,9 +524,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.30" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "jobserver", "libc", @@ -593,9 +599,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -603,9 +609,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -615,14 +621,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -718,6 +724,12 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colorchoice" version = "1.0.2" @@ -951,6 +963,12 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -985,7 +1003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -995,7 +1013,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1029,7 +1047,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1040,7 +1058,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1080,7 +1098,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1126,7 +1144,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.5", + "libloading", ] [[package]] @@ -1160,7 +1178,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1213,9 +1231,9 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "embed-resource" -version = "2.5.0" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e24052d7be71f0efb50c201557f6fe7d237cfd5a64fd5bcd7fd8fe32dbbffa" +checksum = "4edcacde9351c33139a41e3c97eb2334351a81a2791bebb0b243df837128f602" dependencies = [ "cc", "memchr", @@ -1264,7 +1282,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1314,6 +1332,21 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide 0.8.0", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "eyre" version = "0.6.12" @@ -1332,9 +1365,9 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fdeflate" -version = "0.3.5" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ "simd-adler32", ] @@ -1372,9 +1405,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", "miniz_oxide 0.8.0", @@ -1422,7 +1455,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1467,24 +1500,24 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1493,9 +1526,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -1512,32 +1545,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-io", @@ -1699,7 +1732,17 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", ] [[package]] @@ -1787,7 +1830,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1866,7 +1909,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -1881,7 +1924,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.6.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -1900,13 +1943,23 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.6.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if 1.0.0", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1915,9 +1968,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -2058,9 +2111,9 @@ checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" [[package]] name = "httparse" -version = "1.9.5" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -2070,9 +2123,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.31" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -2094,9 +2147,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", @@ -2120,7 +2173,7 @@ checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.5.0", + "hyper 1.4.1", "hyper-util", "rustls", "rustls-pki-types", @@ -2137,7 +2190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.31", + "hyper 0.14.30", "native-tls", "tokio", "tokio-native-tls", @@ -2145,19 +2198,20 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.5.0", + "hyper 1.4.1", "pin-project-lite", "socket2", "tokio", + "tower", "tower-service", "tracing", ] @@ -2221,6 +2275,24 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "qoi", + "tiff", +] + [[package]] name = "indenter" version = "0.3.3" @@ -2240,12 +2312,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.14.5", "serde", ] @@ -2289,9 +2361,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.10.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "is-docker" @@ -2399,11 +2471,20 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -2414,7 +2495,19 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc" dependencies = [ - "jsonptr", + "jsonptr 0.4.7", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "json-patch" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +dependencies = [ + "jsonptr 0.6.3", "serde", "serde_json", "thiserror", @@ -2431,6 +2524,16 @@ dependencies = [ "serde_json", ] +[[package]] +name = "jsonptr" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "keyboard-types" version = "0.7.0" @@ -2559,6 +2662,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libappindicator" version = "0.9.0" @@ -2579,15 +2688,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" dependencies = [ "gtk-sys", - "libloading 0.7.4", + "libloading", "once_cell", ] [[package]] name = "libc" -version = "0.2.161" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libgit2-sys" @@ -2611,16 +2720,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "libloading" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if 1.0.0", - "windows-targets 0.52.6", -] - [[package]] name = "libredox" version = "0.1.3" @@ -2753,6 +2852,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", + "simd-adler32", ] [[package]] @@ -2762,7 +2862,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ "adler2", - "simd-adler32", ] [[package]] @@ -2800,9 +2899,9 @@ dependencies = [ [[package]] name = "muda" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8123dfd4996055ac9b15a60ad263b44b01e539007523ad7a4a533a3d93b0591" +checksum = "b18047edf23933de40835403d4b9211ffd1dcc65c0eec569df38a1fb8aebd719" dependencies = [ "crossbeam-channel", "dpi", @@ -3082,7 +3181,7 @@ dependencies = [ "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -3333,9 +3432,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "open" @@ -3350,9 +3449,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.6.0", "cfg-if 1.0.0", @@ -3371,7 +3470,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -3382,9 +3481,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -3503,9 +3602,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "percent-encoding" @@ -3617,7 +3716,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -3647,6 +3746,26 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -3672,9 +3791,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plist" @@ -3683,7 +3802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.6.0", + "indexmap 2.5.0", "quick-xml 0.32.0", "serde", "time", @@ -3691,15 +3810,15 @@ dependencies = [ [[package]] name = "png" -version = "0.17.14" +version = "0.17.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" dependencies = [ "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.8.0", + "miniz_oxide 0.7.4", ] [[package]] @@ -3801,7 +3920,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -3812,9 +3931,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -3835,6 +3954,15 @@ dependencies = [ "psl-types", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + [[package]] name = "quick-xml" version = "0.32.0" @@ -4019,9 +4147,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ "bitflags 2.6.0", ] @@ -4039,14 +4167,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -4060,13 +4188,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax 0.8.4", ] [[package]] @@ -4077,9 +4205,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" @@ -4095,7 +4223,7 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.31", + "hyper 0.14.30", "hyper-tls", "ipnet", "js-sys", @@ -4123,9 +4251,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.8" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ "base64 0.22.1", "bytes", @@ -4138,7 +4266,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.4.1", "hyper-rustls", "hyper-util", "ipnet", @@ -4150,7 +4278,7 @@ dependencies = [ "pin-project-lite", "quinn", "rustls", - "rustls-pemfile 2.2.0", + "rustls-pemfile 2.1.3", "rustls-pki-types", "serde", "serde_json", @@ -4244,9 +4372,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.15" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "once_cell", "ring", @@ -4267,18 +4395,19 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.2.0" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ + "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" @@ -4293,9 +4422,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" @@ -4314,9 +4443,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ "windows-sys 0.59.0", ] @@ -4345,7 +4474,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -4375,9 +4504,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -4440,7 +4569,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -4451,14 +4580,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.129" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbcf9b78a125ee667ae19388837dd12294b858d101fdd393cb9d5501ef09eb2" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa 1.0.11", "memchr", @@ -4485,14 +4614,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -4511,15 +4640,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.11.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.5.0", "serde", "serde_derive", "serde_json", @@ -4529,14 +4658,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.11.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -4545,7 +4674,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.5.0", "itoa 1.0.11", "ryu", "serde", @@ -4824,7 +4953,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -4857,9 +4986,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -4953,9 +5082,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.30.3" +version = "0.30.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0dbbebe82d02044dfa481adca1550d6dd7bd16e086bc34fa0fbecceb5a63751" +checksum = "63f1f6b2017cc33d7f6fc9c6186a2c0f5dfc985899a7b4fe9e64985c17533db3" dependencies = [ "bitflags 2.6.0", "cocoa 0.26.0", @@ -4998,7 +5127,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -5009,9 +5138,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.0.4" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44438500b50708bfc1e6083844e135d1b516325aae58710dcd8fb67e050ae87c" +checksum = "d3889b392db6d32a105d3757230ea0220090b8f94c90d3e60b6c5eb91178ab1b" dependencies = [ "anyhow", "bytes", @@ -5036,7 +5165,7 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest 0.12.8", + "reqwest 0.12.7", "serde", "serde_json", "serde_repr", @@ -5060,16 +5189,16 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "935f9b3c49b22b3e2e485a57f46d61cd1ae07b1cbb2ba87387a387caf2d8c4e7" +checksum = "9f96827ccfb1aa40d55d0ded79562d18ba18566657a553f992a982d755148376" dependencies = [ "anyhow", "cargo_toml", "dirs", "glob", "heck 0.5.0", - "json-patch", + "json-patch 3.0.1", "schemars", "semver", "serde", @@ -5082,14 +5211,14 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95d7443dd4f0b597704b6a14b964ee2ed16e99928d8e6292ae9825f09fbcd30e" +checksum = "8947f16f47becd9e9cd39b74ee337fd1981574d78819be18e4384d85e5a0b82f" dependencies = [ "base64 0.22.1", "brotli", "ico", - "json-patch", + "json-patch 2.0.0", "plist", "png", "proc-macro2", @@ -5098,7 +5227,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "syn 2.0.79", + "syn 2.0.77", "tauri-utils", "thiserror", "time", @@ -5109,23 +5238,23 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2c0963ccfc3f5194415f2cce7acc975942a8797fbabfb0aa1ed6f59326ae7f" +checksum = "8bd1c8d4a66799d3438747c3a79705cd665a95d6f24cb5f315413ff7a981fe2a" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", "tauri-codegen", "tauri-utils", ] [[package]] name = "tauri-plugin" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e6660a409963e4d57b9bfab4addd141eeff41bd3a7fb14e13004a832cf7ef6" +checksum = "6fa4e6c94cb1d635f65a770c69e23de1bc054b0e4c554fa037a7cc7676333d39" dependencies = [ "anyhow", "glob", @@ -5140,9 +5269,9 @@ dependencies = [ [[package]] name = "tauri-plugin-dialog" -version = "2.0.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddb2fe88b602461c118722c574e2775ab26a4e68886680583874b2f6520608b7" +checksum = "4307310e1d2c09ab110235834722e7c2b85099b683e1eb7342ab351b0be5ada3" dependencies = [ "log", "raw-window-handle", @@ -5158,9 +5287,9 @@ dependencies = [ [[package]] name = "tauri-plugin-fs" -version = "2.0.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab300488ebec3487ca5f56289692e7e45feb07eea8d5e1dba497f7dc9dd9c407" +checksum = "96ba7d46e86db8c830d143ef90ab5a453328365b0cc834c24edea4267b16aba0" dependencies = [ "anyhow", "dunce", @@ -5179,14 +5308,14 @@ dependencies = [ [[package]] name = "tauri-plugin-http" -version = "2.0.1" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784333f1632d96c94346e8145bfe52970923a38a0e6eacd3dccaa12289275acf" +checksum = "c752aee1b00ec3c4d4f440095995d9bd2c640b478f2067d1fba388900b82eb96" dependencies = [ "data-url", "http 1.1.0", "regex", - "reqwest 0.12.8", + "reqwest 0.12.7", "schemars", "serde", "serde_json", @@ -5201,9 +5330,9 @@ dependencies = [ [[package]] name = "tauri-plugin-shell" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "371fb9aca2823990a2d0db7970573be5fdf07881fcaa2b835b29631feb84aec1" +checksum = "0ad7880c5586b6b2104be451e3d7fc0f3800c84bda69e9ba81c828f87cb34267" dependencies = [ "encoding_rs", "log", @@ -5237,9 +5366,9 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8f437293d6f5e5dce829250f4dbdce4e0b52905e297a6689cc2963eb53ac728" +checksum = "a1ef7363e7229ac8d04e8a5d405670dbd43dde8fc4bc3bc56105c35452d03784" dependencies = [ "dpi", "gtk", @@ -5256,9 +5385,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1431602bcc71f2f840ad623915c9842ecc32999b867c4a787d975a17a9625cc6" +checksum = "62fa2068e8498ad007b54d5773d03d57c3ff6dd96f8c8ce58beff44d0d5e0d30" dependencies = [ "gtk", "http 1.1.0", @@ -5282,9 +5411,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38b0230d6880cf6dd07b6d7dd7789a0869f98ac12146e0d18d1c1049215a045" +checksum = "1fc65d6f5c54e56b66258948a6d9e47a82ea41f4b5a7612bfbdd1634c2913ed0" dependencies = [ "brotli", "cargo_metadata", @@ -5293,7 +5422,7 @@ dependencies = [ "glob", "html5ever", "infer", - "json-patch", + "json-patch 2.0.0", "kuchikiki", "log", "memchr", @@ -5328,9 +5457,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.13.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if 1.0.0", "fastrand", @@ -5358,22 +5487,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -5386,6 +5515,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.36" @@ -5461,7 +5601,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -5537,7 +5677,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", @@ -5550,13 +5690,34 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" version = "0.3.3" @@ -5594,7 +5755,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -5768,9 +5929,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.17" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -5859,9 +6020,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.11.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom 0.2.15", "serde", @@ -5944,9 +6105,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if 1.0.0", "once_cell", @@ -5955,24 +6116,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -5982,9 +6143,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5992,28 +6153,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-streams" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" dependencies = [ "futures-util", "js-sys", @@ -6038,9 +6199,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f45d1222915ef1fd2057220c1d9d9624b7654443ea35c3877f7a52bd0a5a2d" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" dependencies = [ "bitflags 2.6.0", "rustix", @@ -6050,9 +6211,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.4" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5755d77ae9040bb872a25026555ce4cb0ae75fd923e90d25fba07d81057de0" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -6084,9 +6245,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -6167,7 +6328,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -6181,6 +6342,12 @@ dependencies = [ "windows-core 0.58.0", ] +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "which" version = "6.0.3" @@ -6326,7 +6493,7 @@ checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -6337,7 +6504,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -6348,7 +6515,7 @@ checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -6359,7 +6526,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -6670,9 +6837,9 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "wry" -version = "0.46.2" +version = "0.46.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa1c8c760041c64ce6be99f83d6cb55fe3fcd85a1ad46d32895f6e65cee87ba" +checksum = "cd5cdf57c66813d97601181349c63b96994b3074fc3d7a31a8cce96e968e3bbd" dependencies = [ "base64 0.22.1", "block2", @@ -6811,9 +6978,11 @@ version = "0.0.0" dependencies = [ "anyhow", "async-trait", + "base64 0.22.1", "clap", "cocoa 0.25.0", "crossbeam", + "image", "komorebi-client", "netdev", "regex", @@ -6853,7 +7022,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.77", ] [[package]] @@ -6862,6 +7031,15 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + [[package]] name = "zvariant" version = "4.0.0" diff --git a/README.md b/README.md index 8abe1b12..7f20d3f7 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ Through the `zebar` NPM package, Zebar exposes various system information via re - [cpu](#CPU) - [date](#Date) - [disk](#Disk) +- [focusedWindow](#focused-window) - [glazewm](#GlazeWM) - [host](#Host) - [ip](#IP) @@ -195,6 +196,23 @@ No config options. | `iecValue` | Bytes converted in according to the IEC standard. 1024 bytes in a kibibyte. | `number` | | `iecUnit` | Unit of the converted bytes in according to the IEC standard. KiB, MiB, ... | `string` | + + +## Focused Window + +#### Config + +No config options. + +#### Outputs + +| Variable | Description | Return type | Supported OS | +| --------------------- | ----------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| `title` | Title of the current focused window. | `string` | microsoft icon | +| `icon` | Icon of the current focused window, encoded as base64 | `string` | microsoft icon | + + + ### GlazeWM #### Config diff --git a/examples/boilerplate-solid-ts/dist/index.html b/examples/boilerplate-solid-ts/dist/index.html index 5c6c9a50..cce97149 100644 --- a/examples/boilerplate-solid-ts/dist/index.html +++ b/examples/boilerplate-solid-ts/dist/index.html @@ -3,13 +3,13 @@ + Zebar + + -

- Boilerplate for SolidJS with TypeScript. Run npm i and - npm run dev in the solid-ts directory to - run this example. -

+ +
diff --git a/examples/boilerplate-solid-ts/src/index.tsx b/examples/boilerplate-solid-ts/src/index.tsx index 1a6ce453..9110971d 100644 --- a/examples/boilerplate-solid-ts/src/index.tsx +++ b/examples/boilerplate-solid-ts/src/index.tsx @@ -1,12 +1,13 @@ -/* @refresh reload */ import './index.css'; import { render } from 'solid-js/web'; import { createStore } from 'solid-js/store'; import * as zebar from 'zebar'; +import { createSignal, createEffect } from 'solid-js'; const providers = zebar.createProviderGroup({ audio: { type: 'audio' }, cpu: { type: 'cpu' }, + focusedWindow: { type: 'focusedWindow' }, battery: { type: 'battery' }, memory: { type: 'memory' }, weather: { type: 'weather' }, @@ -17,8 +18,42 @@ render(() => , document.getElementById('root')!); function App() { const [output, setOutput] = createStore(providers.outputMap); + const [iconUrl, setIconUrl] = createSignal(null); + const [lastTitle, setLastTitle] = createSignal(null); - providers.onOutput(outputMap => setOutput(outputMap)); + providers.onOutput(outputMap => { + setOutput(outputMap); + + // Only process icon if window title has changed + if (outputMap.focusedWindow?.title !== lastTitle()) { + setLastTitle(outputMap.focusedWindow?.title || null); + + const icon = outputMap.focusedWindow?.icon; + if (icon) { + try { + const binary = atob(icon); + const array = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + array[i] = binary.charCodeAt(i); + } + const blob = new Blob([array], { type: 'image/png' }); + + // Clean up old URL if it exists + if (iconUrl()) { + URL.revokeObjectURL(iconUrl()!); + } + + const url = URL.createObjectURL(blob); + setIconUrl(url); + } catch (error) { + console.error('Error decoding icon data:', error); + setIconUrl(null); + } + } else { + setIconUrl(null); + } + } + }); return (
@@ -31,6 +66,10 @@ function App() { {output.media?.session?.artist}
CPU usage: {output.cpu?.usage}
+ {iconUrl() && ( + icon + )} +
Focused window: {output.focusedWindow?.title}
Battery charge: {output.battery?.chargePercent}
diff --git a/packages/client-api/src/providers/create-provider.ts b/packages/client-api/src/providers/create-provider.ts index 577fc0e6..b07c748e 100644 --- a/packages/client-api/src/providers/create-provider.ts +++ b/packages/client-api/src/providers/create-provider.ts @@ -18,6 +18,11 @@ import type { DateProviderConfig, DateProvider, } from './date/date-provider-types'; +import { createFocusedWindowProvider } from './focused-window/create-focused-window-provider'; +import type { + FocusedWindowProviderConfig, + FocusedWindowProvider, +} from './focused-window/focused-window-provider-types'; import { createGlazeWmProvider } from './glazewm/create-glazewm-provider'; import type { GlazeWmProviderConfig, @@ -71,6 +76,7 @@ export interface ProviderConfigMap { battery: BatteryProviderConfig; cpu: CpuProviderConfig; date: DateProviderConfig; + focusedWindow: FocusedWindowProviderConfig; glazewm: GlazeWmProviderConfig; host: HostProviderConfig; ip: IpProviderConfig; @@ -88,6 +94,7 @@ export interface ProviderMap { battery: BatteryProvider; cpu: CpuProvider; date: DateProvider; + focusedWindow: FocusedWindowProvider; glazewm: GlazeWmProvider; host: HostProvider; ip: IpProvider; @@ -129,6 +136,8 @@ export function createProvider( return createCpuProvider(config) as any; case 'date': return createDateProvider(config) as any; + case 'focusedWindow': + return createFocusedWindowProvider(config) as any; case 'glazewm': return createGlazeWmProvider(config) as any; case 'host': diff --git a/packages/client-api/src/providers/focused-window/create-focused-window-provider.ts b/packages/client-api/src/providers/focused-window/create-focused-window-provider.ts new file mode 100644 index 00000000..836a6979 --- /dev/null +++ b/packages/client-api/src/providers/focused-window/create-focused-window-provider.ts @@ -0,0 +1,31 @@ +import { z } from 'zod'; +import { createBaseProvider } from '../create-base-provider'; +import { onProviderEmit } from '~/desktop'; +import type { + FocusedWindowOutput, + FocusedWindowProvider, + FocusedWindowProviderConfig, +} from './focused-window-provider-types'; + +const focusedWindowProviderConfigSchema = z.object({ + type: z.literal('focusedWindow'), +}); + +export function createFocusedWindowProvider( + config: FocusedWindowProviderConfig, +): FocusedWindowProvider { + const mergedConfig = focusedWindowProviderConfigSchema.parse(config); + + return createBaseProvider(mergedConfig, async queue => { + return onProviderEmit( + mergedConfig, + ({ result }) => { + if ('error' in result) { + queue.error(result.error); + } else { + queue.output(result.output); + } + }, + ); + }); +} diff --git a/packages/client-api/src/providers/focused-window/focused-window-provider-types.ts b/packages/client-api/src/providers/focused-window/focused-window-provider-types.ts new file mode 100644 index 00000000..139b3566 --- /dev/null +++ b/packages/client-api/src/providers/focused-window/focused-window-provider-types.ts @@ -0,0 +1,15 @@ +import type { Provider } from '../create-base-provider'; + +export interface FocusedWindowProviderConfig { + type: 'focusedWindow'; +} + +export interface FocusedWindowOutput { + title: string; + icon: string; +} + +export type FocusedWindowProvider = Provider< + FocusedWindowProviderConfig, + FocusedWindowOutput +>; diff --git a/packages/client-api/src/providers/index.ts b/packages/client-api/src/providers/index.ts index 2a05e447..086d335f 100644 --- a/packages/client-api/src/providers/index.ts +++ b/packages/client-api/src/providers/index.ts @@ -1,6 +1,7 @@ export * from './battery/battery-provider-types'; export * from './cpu/cpu-provider-types'; export * from './date/date-provider-types'; +export * from './focused-window/focused-window-provider-types'; export * from './glazewm/glazewm-provider-types'; export * from './host/host-provider-types'; export * from './ip/ip-provider-types'; diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml index 086fe7ad..e1ab1d29 100644 --- a/packages/desktop/Cargo.toml +++ b/packages/desktop/Cargo.toml @@ -15,8 +15,10 @@ tauri-build = { version = "2.0", features = [] } [dependencies] anyhow = "1" async-trait = "0.1" +base64 = "0.22.1" clap = { version = "4", features = ["derive"] } crossbeam = "0.8" +image = "0.24" reqwest = { version = "0.11", features = ["json"] } tauri = { version = "2.0", features = [ "devtools", @@ -37,7 +39,6 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } netdev = "0.24" regex = "1" - [target.'cfg(target_os = "windows")'.dependencies] komorebi-client = { git = "https://github.com/LGUG2Z/komorebi", tag = "v0.1.28" } windows-core = "0.58" @@ -50,6 +51,9 @@ windows = { version = "0.58", features = [ "Win32_Media", "Win32_Media_Audio", "Win32_Media_Audio_Endpoints", + "Win32_Storage", + "Win32_Storage_Packaging", + "Win32_Storage_Packaging_Appx", "Win32_System_Console", "Win32_System_SystemServices", "Win32_UI_Input_KeyboardAndMouse", diff --git a/packages/desktop/src/providers/focused_window/focused_window_provider.rs b/packages/desktop/src/providers/focused_window/focused_window_provider.rs new file mode 100644 index 00000000..8665b1ce --- /dev/null +++ b/packages/desktop/src/providers/focused_window/focused_window_provider.rs @@ -0,0 +1,450 @@ +use std::{ffi::c_void, io::Cursor, sync::OnceLock}; + +use async_trait::async_trait; +use base64::{prelude::BASE64_STANDARD, Engine as _}; +use image::{ImageBuffer, ImageFormat, Rgba}; +use serde::{Deserialize, Serialize}; +use windows::{ + core::{Error, Interface, HSTRING, PWSTR}, + Win32::{ + Foundation::{BOOL, E_FAIL, HWND, LPARAM, SIZE, WPARAM}, + Graphics::Gdi::{ + DeleteObject, GetDC, GetDIBits, ReleaseDC, BITMAPINFO, + BITMAPINFOHEADER, DIB_RGB_COLORS, HBITMAP, RGBQUAD, + }, + Storage::Packaging::Appx::GetApplicationUserModelId, + System::{ + Com::{CoInitializeEx, COINIT_APARTMENTTHREADED}, + Threading::{OpenProcess, PROCESS_QUERY_LIMITED_INFORMATION}, + }, + UI::{ + Accessibility::{SetWinEventHook, HWINEVENTHOOK}, + Shell::{ + IShellItem, IShellItemImageFactory, SHCreateItemFromParsingName, + SIIGBF_BIGGERSIZEOK, + }, + WindowsAndMessaging::{ + DestroyIcon, DispatchMessageW, EnumChildWindows, GetClassLongPtrW, + GetForegroundWindow, GetIconInfo, GetMessageW, + GetWindowTextLengthW, GetWindowTextW, GetWindowThreadProcessId, + IsWindow, SendMessageW, TranslateMessage, EVENT_OBJECT_CREATE, + EVENT_OBJECT_NAMECHANGE, EVENT_SYSTEM_FOREGROUND, + EVENT_SYSTEM_SWITCHSTART, GCLP_HICONSM, HICON, ICONINFO, ICON_BIG, + ICON_SMALL, MSG, WINEVENT_OUTOFCONTEXT, WM_GETICON, + }, + }, + }, +}; + +use crate::providers::{ + CommonProviderState, Provider, ProviderEmitter, RuntimeType, +}; + +static PROVIDER_TX: OnceLock = OnceLock::new(); + +// This doesn't always work.. +const ICON_SIZE: i32 = 32; + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct FocusedWindowProviderConfig {} + +#[derive(Debug, Clone, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct FocusedWindowOutput { + pub title: String, + pub icon: String, +} + +pub struct FocusedWindowProvider { + common: CommonProviderState, +} + +impl FocusedWindowProvider { + pub fn new( + _config: FocusedWindowProviderConfig, + common: CommonProviderState, + ) -> FocusedWindowProvider { + FocusedWindowProvider { common } + } + + unsafe fn get_foreground_window_icon( + hwnd: HWND, + ) -> Result { + // Try standard window icon first + if let Some(b64) = Self::extract_standard_icon(hwnd) { + return Ok(b64); + } + + // Try UWP icon + if let Some(aumid) = Self::find_uwp_app_id(hwnd) { + if let Some(b64) = Self::extract_uwp_icon(&aumid) { + return Ok(b64); + } + } + + Err(Error::new(E_FAIL, "Failed to extract icon")) + } + + unsafe fn extract_standard_icon(hwnd: HWND) -> Option { + let hicon = + SendMessageW(hwnd, WM_GETICON, WPARAM(ICON_BIG as usize), LPARAM(0)); + let hicon = if hicon.0 != 0 { + HICON(hicon.0 as *mut _) + } else { + let hicon = SendMessageW( + hwnd, + WM_GETICON, + WPARAM(ICON_SMALL as usize), + LPARAM(0), + ); + if hicon.0 != 0 { + HICON(hicon.0 as *mut _) + } else { + let hicon = GetClassLongPtrW(hwnd, GCLP_HICONSM); + if hicon != 0 { + HICON(hicon as *mut _) + } else { + return None; + } + } + }; + + let mut icon_info = ICONINFO::default(); + if GetIconInfo(hicon, &mut icon_info).is_ok() { + let bitmap = icon_info.hbmColor; + // TODO (check the docs more) + let width = icon_info.xHotspot * 2; + let height = icon_info.yHotspot * 2; + let b64 = + Self::bitmap_to_base64(bitmap, width as u32, height as u32); + let _ = DeleteObject(icon_info.hbmColor); + let _ = DeleteObject(icon_info.hbmMask); + let _ = DestroyIcon(hicon); + b64 + } else { + let _ = DestroyIcon(hicon); + None + } + } + + unsafe fn extract_uwp_icon(aumid: &str) -> Option { + let _ = CoInitializeEx(None, COINIT_APARTMENTTHREADED); + let shell_path = format!("shell:AppsFolder\\{}", aumid); + + let shell_item: IShellItem = + SHCreateItemFromParsingName(&HSTRING::from(shell_path), None) + .ok()?; + let image_factory: IShellItemImageFactory = shell_item.cast().ok()?; + + let size = SIZE { + cx: ICON_SIZE, + cy: ICON_SIZE, + }; + + let hbitmap = + image_factory.GetImage(size, SIIGBF_BIGGERSIZEOK).ok()?; + let hbmp = HBITMAP(hbitmap.0); + + if !hbmp.is_invalid() { + let result = + Self::bitmap_to_base64(hbmp, ICON_SIZE as u32, ICON_SIZE as u32); + let _ = DeleteObject(hbmp); + result + } else { + let _ = DeleteObject(hbmp); + None + } + } + + unsafe fn find_uwp_app_id(hwnd: HWND) -> Option { + let mut process_id = 0; + GetWindowThreadProcessId(hwnd, Some(&mut process_id)); + + // Try the main window's process + if let Ok(handle) = + OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, process_id) + { + let mut len = 0u32; + let _ = GetApplicationUserModelId(handle, &mut len, PWSTR::null()); + if len > 0 { + let mut buffer = vec![0u16; len as usize]; + if GetApplicationUserModelId( + handle, + &mut len, + PWSTR(buffer.as_mut_ptr()), + ) + .is_ok() + { + return Some(String::from_utf16_lossy( + &buffer[..len as usize - 1], + )); + } + } + } + + // Try child windows + let mut uwp_app_id = None; + let _ = EnumChildWindows( + hwnd, + Some(enum_child_proc), + LPARAM(&mut uwp_app_id as *mut _ as isize), + ); + uwp_app_id + } + + unsafe fn get_foreground_window_title(hwnd: HWND) -> Option { + if hwnd.0 == std::ptr::null_mut() { + return None; + } + + let length = GetWindowTextLengthW(hwnd); + if length == 0 { + return None; + } + + let mut buffer: Vec = vec![0; (length + 1) as usize]; + GetWindowTextW(hwnd, &mut buffer); + let title = String::from_utf16_lossy(&buffer[..length as usize]); + Some(title) + } + + unsafe fn bitmap_to_base64( + bitmap: HBITMAP, + width: u32, + height: u32, + ) -> Option { + // Get bitmap data + let mut bmi = BITMAPINFO { + bmiHeader: BITMAPINFOHEADER { + biSize: size_of::() as u32, + biWidth: width as i32, + biHeight: -(height as i32), // Negative height for top-down DIB + biPlanes: 1, + biBitCount: 32, + biCompression: 0, + biSizeImage: 0, + biXPelsPerMeter: 0, + biYPelsPerMeter: 0, + biClrUsed: 0, + biClrImportant: 0, + }, + bmiColors: [RGBQUAD::default()], + }; + + let mut pixels: Vec = vec![0; (width * height * 4) as usize]; + let hdc = GetDC(None); + + let result = GetDIBits( + hdc, + bitmap, + 0, + height, + Some(pixels.as_mut_ptr() as *mut c_void), + &mut bmi, + DIB_RGB_COLORS, + ); + + ReleaseDC(None, hdc); + + if result == 0 { + return None; + } + + // Convert BGR to RGB + for pixel in pixels.chunks_exact_mut(4) { + // Swap B and R channels, leaving A and G unchanged + pixel.swap(0, 2); + } + + // Convert to PNG and then base64 + let mut png_data = Vec::new(); + let mut cursor = Cursor::new(&mut png_data); + + let image_buffer = + ImageBuffer::, _>::from_raw(width, height, pixels)?; + image_buffer.write_to(&mut cursor, ImageFormat::Png).ok()?; + + Some(BASE64_STANDARD.encode(&png_data)) + } + + unsafe fn emit_window_info(hwnd: HWND, emitter: &ProviderEmitter) { + println!("Emitting window info"); + if !IsWindow(hwnd).as_bool() { + return; + } + let output = Self::focused_window_output(hwnd); + emitter.emit_output(output); + } + + unsafe fn focused_window_output( + hwnd: HWND, + ) -> anyhow::Result { + if let Some(title) = Self::get_foreground_window_title(hwnd) { + if title.trim().is_empty() { + return Err(anyhow::Error::msg("Empty title")); + } + + if let Ok(icon) = Self::get_foreground_window_icon(hwnd) { + Ok(FocusedWindowOutput { title, icon }) + } else { + Err(anyhow::Error::msg("Failed to extract icon")) + } + } else { + Err(anyhow::Error::msg("Failed to get window title")) + } + } + + fn create_focused_window_hook(&self) -> anyhow::Result<()> { + PROVIDER_TX + .set(self.common.emitter.clone()) + .expect("Error setting provider tx in focused window provider"); + + unsafe { + let focus_hook = SetWinEventHook( + EVENT_SYSTEM_FOREGROUND, + EVENT_SYSTEM_FOREGROUND, + None, + Some(win_event_proc), + 0, + 0, + WINEVENT_OUTOFCONTEXT, + ); + + let title_hook = SetWinEventHook( + EVENT_OBJECT_NAMECHANGE, + EVENT_OBJECT_NAMECHANGE, + None, + Some(win_event_proc), + 0, + 0, + WINEVENT_OUTOFCONTEXT, + ); + + let create_hook = SetWinEventHook( + EVENT_OBJECT_CREATE, + EVENT_OBJECT_CREATE, + None, + Some(win_event_proc), + 0, + 0, + WINEVENT_OUTOFCONTEXT, + ); + + let switch_hook = SetWinEventHook( + EVENT_SYSTEM_SWITCHSTART, + EVENT_SYSTEM_SWITCHSTART, + None, + Some(win_event_proc), + 0, + 0, + WINEVENT_OUTOFCONTEXT, + ); + + if focus_hook.is_invalid() || title_hook.is_invalid() { + return Err(anyhow::Error::msg("Failed to set event hooks")); + } + + // Initialize with current foreground window + if let Some(current_hwnd) = Some(GetForegroundWindow()) { + Self::emit_window_info(current_hwnd, &self.common.emitter); + } + + let mut msg = MSG::default(); + while GetMessageW(&mut msg, HWND::default(), 0, 0).as_bool() { + let _ = TranslateMessage(&msg); + let _ = DispatchMessageW(&msg); + } + + Ok(()) + } + } +} + +unsafe extern "system" fn win_event_proc( + hook: HWINEVENTHOOK, + event: u32, + hwnd: HWND, + id_object: i32, + id_child: i32, + thread_id: u32, + time: u32, +) { + if !IsWindow(hwnd).as_bool() { + return; + } + if let Some(emitter) = PROVIDER_TX.get() { + match event { + EVENT_SYSTEM_FOREGROUND => { + FocusedWindowProvider::emit_window_info(hwnd, emitter); + } + EVENT_OBJECT_CREATE => { + let foreground = GetForegroundWindow(); + if hwnd == foreground { + FocusedWindowProvider::emit_window_info(hwnd, emitter); + } + } + EVENT_OBJECT_NAMECHANGE => { + if id_object == 0 && hwnd == GetForegroundWindow() { + FocusedWindowProvider::emit_window_info(hwnd, emitter); + } + } + EVENT_SYSTEM_SWITCHSTART => { + let hwnd = GetForegroundWindow(); + if !hwnd.is_invalid() { + FocusedWindowProvider::emit_window_info(hwnd, emitter); + } + } + _ => {} + } + } +} + +unsafe extern "system" fn enum_child_proc( + child_hwnd: HWND, + lparam: LPARAM, +) -> BOOL { + let result = lparam.0 as *mut Option; + let mut child_process_id = 0; + GetWindowThreadProcessId(child_hwnd, Some(&mut child_process_id)); + + if let Ok(handle) = + OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, child_process_id) + { + let mut len = 0u32; + let _ = GetApplicationUserModelId(handle, &mut len, PWSTR::null()); + if len > 0 { + let mut buffer = vec![0u16; len as usize]; + if GetApplicationUserModelId( + handle, + &mut len, + PWSTR(buffer.as_mut_ptr()), + ) + .is_ok() + { + unsafe { + *result = + Some(String::from_utf16_lossy(&buffer[..len as usize - 1])); + } + return BOOL(0); + } + } + } + BOOL(1) +} + +#[async_trait] +impl Provider for FocusedWindowProvider { + fn runtime_type(&self) -> RuntimeType { + RuntimeType::Sync + } + + fn start_sync(&mut self) { + if let Err(err) = self.create_focused_window_hook() { + self + .common + .emitter + .emit_output::(Err(err)); + } + } +} diff --git a/packages/desktop/src/providers/focused_window/mod.rs b/packages/desktop/src/providers/focused_window/mod.rs new file mode 100644 index 00000000..2e3fe5ad --- /dev/null +++ b/packages/desktop/src/providers/focused_window/mod.rs @@ -0,0 +1,3 @@ +mod focused_window_provider; + +pub use focused_window_provider::*; diff --git a/packages/desktop/src/providers/mod.rs b/packages/desktop/src/providers/mod.rs index 0900643a..338ec610 100644 --- a/packages/desktop/src/providers/mod.rs +++ b/packages/desktop/src/providers/mod.rs @@ -3,6 +3,7 @@ mod audio; mod battery; mod cpu; mod disk; +mod focused_window; mod host; mod ip; #[cfg(windows)] diff --git a/packages/desktop/src/providers/provider_config.rs b/packages/desktop/src/providers/provider_config.rs index 2a35a1f5..634fd6bc 100644 --- a/packages/desktop/src/providers/provider_config.rs +++ b/packages/desktop/src/providers/provider_config.rs @@ -2,8 +2,9 @@ use serde::Deserialize; #[cfg(windows)] use super::{ - audio::AudioProviderConfig, keyboard::KeyboardProviderConfig, - komorebi::KomorebiProviderConfig, media::MediaProviderConfig, + audio::AudioProviderConfig, focused_window::FocusedWindowProviderConfig, + keyboard::KeyboardProviderConfig, komorebi::KomorebiProviderConfig, + media::MediaProviderConfig, }; use super::{ battery::BatteryProviderConfig, cpu::CpuProviderConfig, @@ -13,12 +14,14 @@ use super::{ }; #[derive(Deserialize, Debug)] -#[serde(tag = "type", rename_all = "snake_case")] +#[serde(tag = "type", rename_all = "camelCase")] pub enum ProviderConfig { #[cfg(windows)] Audio(AudioProviderConfig), Battery(BatteryProviderConfig), Cpu(CpuProviderConfig), + #[cfg(windows)] + FocusedWindow(FocusedWindowProviderConfig), Host(HostProviderConfig), Ip(IpProviderConfig), #[cfg(windows)] diff --git a/packages/desktop/src/providers/provider_manager.rs b/packages/desktop/src/providers/provider_manager.rs index 67aa541d..e888f218 100644 --- a/packages/desktop/src/providers/provider_manager.rs +++ b/packages/desktop/src/providers/provider_manager.rs @@ -11,8 +11,9 @@ use tracing::info; #[cfg(windows)] use super::{ - audio::AudioProvider, keyboard::KeyboardProvider, - komorebi::KomorebiProvider, media::MediaProvider, + audio::AudioProvider, focused_window::FocusedWindowProvider, + keyboard::KeyboardProvider, komorebi::KomorebiProvider, + media::MediaProvider, }; use super::{ battery::BatteryProvider, cpu::CpuProvider, disk::DiskProvider, @@ -227,6 +228,10 @@ impl ProviderManager { ProviderConfig::Cpu(config) => { Box::new(CpuProvider::new(config, common)) } + #[cfg(windows)] + ProviderConfig::FocusedWindow(config) => { + Box::new(FocusedWindowProvider::new(config, common)) + } ProviderConfig::Host(config) => { Box::new(HostProvider::new(config, common)) } diff --git a/packages/desktop/src/providers/provider_output.rs b/packages/desktop/src/providers/provider_output.rs index b10d96e1..da772c01 100644 --- a/packages/desktop/src/providers/provider_output.rs +++ b/packages/desktop/src/providers/provider_output.rs @@ -2,8 +2,8 @@ use serde::Serialize; #[cfg(windows)] use super::{ - audio::AudioOutput, keyboard::KeyboardOutput, komorebi::KomorebiOutput, - media::MediaOutput, + audio::AudioOutput, focused_window::FocusedWindowOutput, + keyboard::KeyboardOutput, komorebi::KomorebiOutput, media::MediaOutput, }; use super::{ battery::BatteryOutput, cpu::CpuOutput, disk::DiskOutput, @@ -31,6 +31,8 @@ pub enum ProviderOutput { Audio(AudioOutput), Battery(BatteryOutput), Cpu(CpuOutput), + #[cfg(windows)] + FocusedWindow(FocusedWindowOutput), Host(HostOutput), Ip(IpOutput), #[cfg(windows)] @@ -59,6 +61,7 @@ impl_provider_output! { #[cfg(windows)] impl_provider_output! { Audio(AudioOutput), + FocusedWindow(FocusedWindowOutput), Komorebi(KomorebiOutput), Media(MediaOutput), Keyboard(KeyboardOutput)