diff --git a/desktop/tauri/src-tauri/Cargo.lock b/desktop/tauri/src-tauri/Cargo.lock index c3096c3a..8d938985 100644 --- a/desktop/tauri/src-tauri/Cargo.lock +++ b/desktop/tauri/src-tauri/Cargo.lock @@ -235,7 +235,7 @@ dependencies = [ "open", "reqwest", "rfd", - "rust-ini 0.20.0", + "rust-ini", "serde", "serde_json", "sha", @@ -335,6 +335,24 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "ashpd" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01992ad7774250d5b7fe214e2676cb99bf92564436d8135ab44fe815e71769a9" +dependencies = [ + "async-fs 2.1.2", + "async-net", + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.8.5", + "serde", + "serde_repr", + "url", + "zbus 3.15.2", +] + [[package]] name = "ashpd" version = "0.8.1" @@ -349,7 +367,7 @@ dependencies = [ "serde_repr", "tokio", "url", - "zbus", + "zbus 4.4.0", ] [[package]] @@ -364,13 +382,23 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener 2.5.3", + "futures-core", +] + [[package]] name = "async-broadcast" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" dependencies = [ - "event-listener", + "event-listener 5.3.1", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -396,20 +424,52 @@ checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ "async-task", "concurrent-queue", - "fastrand", - "futures-lite", + "fastrand 2.1.0", + "futures-lite 2.3.0", "slab", ] +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", +] + [[package]] name = "async-fs" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ - "async-lock", + "async-lock 3.4.0", "blocking", - "futures-lite", + "futures-lite 2.3.0", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", ] [[package]] @@ -418,30 +478,67 @@ version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" dependencies = [ - "async-lock", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite", + "futures-lite 2.3.0", "parking", - "polling", + "polling 3.7.3", "rustix 0.38.34", "slab", "tracing", "windows-sys 0.59.0", ] +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + [[package]] name = "async-lock" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener", + "event-listener 5.3.1", "event-listener-strategy", "pin-project-lite", ] +[[package]] +name = "async-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io 2.3.4", + "blocking", + "futures-lite 2.3.0", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.34", + "windows-sys 0.48.0", +] + [[package]] name = "async-process" version = "2.2.4" @@ -449,14 +546,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a07789659a4d385b79b18b9127fc27e1a59e1e89117c78c5ea3b806f016374" dependencies = [ "async-channel", - "async-io", - "async-lock", + "async-io 2.3.4", + "async-lock 3.4.0", "async-signal", "async-task", "blocking", "cfg-if", - "event-listener", - "futures-lite", + "event-listener 5.3.1", + "futures-lite 2.3.0", "rustix 0.38.34", "tracing", "windows-sys 0.59.0", @@ -479,8 +576,8 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io", - "async-lock", + "async-io 2.3.4", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", @@ -824,7 +921,7 @@ dependencies = [ "async-channel", "async-task", "futures-io", - "futures-lite", + "futures-lite 2.3.0", "piper", ] @@ -1748,7 +1845,7 @@ version = "3.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" dependencies = [ - "nix", + "nix 0.29.0", "windows-sys 0.59.0", ] @@ -1782,17 +1879,19 @@ dependencies = [ [[package]] name = "dark-light" version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a76fa97167fa740dcdbfe18e8895601e1bc36525f09b044e00916e717c03a3c" +source = "git+https://github.com/vlabo/rust-dark-light?rev=1f955c84d0ea05729bb5ecab29fb1b315b9897de#1f955c84d0ea05729bb5ecab29fb1b315b9897de" dependencies = [ + "anyhow", + "ashpd 0.7.0", "dconf_rs", "detect-desktop-environment", - "dirs 4.0.0", + "futures", "objc", - "rust-ini 0.18.0", + "rust-ini", "web-sys", - "winreg 0.10.1", - "zbus", + "winreg", + "xdg", + "zbus 3.15.2", ] [[package]] @@ -1941,6 +2040,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -2007,9 +2117,9 @@ dependencies = [ [[package]] name = "detect-desktop-environment" -version = "0.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d8ad60dd5b13a4ee6bd8fa2d5d88965c597c67bce32b5fc49c94f55cb50810" +checksum = "cf27a1bbe31ac901a2350a6316b1f7056067118abe6bf1ff015d5950ac5e3eb3" [[package]] name = "deunicode" @@ -2053,22 +2163,13 @@ dependencies = [ "winapi", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys 0.3.7", -] - [[package]] name = "dirs" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ - "dirs-sys 0.4.1", + "dirs-sys", ] [[package]] @@ -2081,17 +2182,6 @@ dependencies = [ "dirs-sys-next", ] -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users 0.4.5", - "winapi", -] - [[package]] name = "dirs-sys" version = "0.4.1" @@ -2155,12 +2245,6 @@ dependencies = [ "syn 2.0.75", ] -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - [[package]] name = "dlv-list" version = "0.5.2" @@ -2329,7 +2413,7 @@ dependencies = [ "rustc_version", "toml 0.8.19", "vswhom", - "winreg 0.52.0", + "winreg", ] [[package]] @@ -2463,6 +2547,23 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "event-listener" version = "5.3.1" @@ -2480,7 +2581,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener", + "event-listener 5.3.1", "pin-project-lite", ] @@ -2511,6 +2612,15 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.1.0" @@ -2557,7 +2667,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" dependencies = [ - "memoffset", + "memoffset 0.9.1", "rustc_version", ] @@ -2740,6 +2850,7 @@ checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", + "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -2779,13 +2890,28 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-lite" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand", + "fastrand 2.1.0", "futures-core", "futures-io", "parking", @@ -3464,7 +3590,7 @@ dependencies = [ "http-body", "hyper", "pin-project-lite", - "socket2", + "socket2 0.5.7", "tokio", "tower", "tower-service", @@ -4430,6 +4556,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -4618,6 +4753,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", +] + [[package]] name = "nix" version = "0.29.0" @@ -4628,7 +4775,7 @@ dependencies = [ "cfg-if", "cfg_aliases", "libc", - "memoffset", + "memoffset 0.9.1", ] [[package]] @@ -4699,7 +4846,7 @@ dependencies = [ "mac-notification-sys", "serde", "tauri-winrt-notification 0.2.1", - "zbus", + "zbus 4.4.0", ] [[package]] @@ -5109,23 +5256,13 @@ dependencies = [ "num-traits", ] -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list 0.3.0", - "hashbrown 0.12.3", -] - [[package]] name = "ordered-multimap" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" dependencies = [ - "dlv-list 0.5.2", + "dlv-list", "hashbrown 0.14.5", ] @@ -5725,7 +5862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand", + "fastrand 2.1.0", "futures-io", ] @@ -5782,6 +5919,22 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "polling" version = "3.7.3" @@ -6282,7 +6435,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "winreg 0.52.0", + "winreg", ] [[package]] @@ -6318,7 +6471,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251" dependencies = [ - "ashpd", + "ashpd 0.8.1", "block", "dispatch", "glib-sys", @@ -6493,16 +6646,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap 0.4.3", -] - [[package]] name = "rust-ini" version = "0.20.0" @@ -6510,7 +6653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a" dependencies = [ "cfg-if", - "ordered-multimap 0.7.3", + "ordered-multimap", ] [[package]] @@ -7173,6 +7316,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.5.7" @@ -8073,7 +8226,7 @@ dependencies = [ "tauri", "thiserror", "windows-sys 0.52.0", - "zbus", + "zbus 4.4.0", ] [[package]] @@ -8243,7 +8396,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", - "fastrand", + "fastrand 2.1.0", "once_cell", "rustix 0.38.34", "windows-sys 0.59.0", @@ -8433,7 +8586,7 @@ dependencies = [ "mio 1.0.2", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.7", "tokio-macros", "tracing", "windows-sys 0.52.0", @@ -8800,7 +8953,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "memoffset", + "memoffset 0.9.1", "tempfile", "winapi", ] @@ -9146,6 +9299,12 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "walkdir" version = "2.5.0" @@ -9842,15 +10001,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "winreg" version = "0.52.0" @@ -9996,6 +10146,12 @@ dependencies = [ "rustix 0.38.34", ] +[[package]] +name = "xdg" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" + [[package]] name = "xdg-home" version = "1.3.0" @@ -10021,29 +10177,70 @@ dependencies = [ "lzma-sys", ] +[[package]] +name = "zbus" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" +dependencies = [ + "async-broadcast 0.5.1", + "async-executor", + "async-fs 1.6.0", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process 1.8.1", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "byteorder", + "derivative", + "enumflags2", + "event-listener 2.5.3", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix 0.26.4", + "once_cell", + "ordered-stream", + "rand 0.8.5", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "xdg-home", + "zbus_macros 3.15.2", + "zbus_names 2.6.1", + "zvariant 3.15.2", +] + [[package]] name = "zbus" version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" dependencies = [ - "async-broadcast", + "async-broadcast 0.7.1", "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-process", + "async-fs 2.1.2", + "async-io 2.3.4", + "async-lock 3.4.0", + "async-process 2.2.4", "async-recursion", "async-task", "async-trait", "blocking", "enumflags2", - "event-listener", + "event-listener 5.3.1", "futures-core", "futures-sink", "futures-util", "hex", - "nix", + "nix 0.29.0", "ordered-stream", "rand 0.8.5", "serde", @@ -10055,9 +10252,23 @@ dependencies = [ "uds_windows", "windows-sys 0.52.0", "xdg-home", - "zbus_macros", - "zbus_names", - "zvariant", + "zbus_macros 4.4.0", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus_macros" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "zvariant_utils 1.0.1", ] [[package]] @@ -10070,7 +10281,18 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.75", - "zvariant_utils", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zbus_names" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" +dependencies = [ + "serde", + "static_assertions", + "zvariant 3.15.2", ] [[package]] @@ -10081,7 +10303,7 @@ checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" dependencies = [ "serde", "static_assertions", - "zvariant", + "zvariant 4.2.0", ] [[package]] @@ -10208,6 +10430,21 @@ dependencies = [ "zune-core", ] +[[package]] +name = "zvariant" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "url", + "zvariant_derive 3.15.2", +] + [[package]] name = "zvariant" version = "4.2.0" @@ -10219,7 +10456,20 @@ dependencies = [ "serde", "static_assertions", "url", - "zvariant_derive", + "zvariant_derive 4.2.0", +] + +[[package]] +name = "zvariant_derive" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils 1.0.1", ] [[package]] @@ -10232,7 +10482,18 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.75", - "zvariant_utils", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] diff --git a/desktop/tauri/src-tauri/Cargo.toml b/desktop/tauri/src-tauri/Cargo.toml index 2325c9b9..db19639b 100644 --- a/desktop/tauri/src-tauri/Cargo.toml +++ b/desktop/tauri/src-tauri/Cargo.toml @@ -53,7 +53,7 @@ reqwest = { version = "0.12" } rfd = { version = "*", default-features = false, features = [ "tokio", "gtk3", "common-controls-v6" ] } open = "5.1.3" -dark-light = "1.1.1" +dark-light = { git = "https://github.com/vlabo/rust-dark-light", rev = "1f955c84d0ea05729bb5ecab29fb1b315b9897de" } # Linux only [target.'cfg(target_os = "linux")'.dependencies] diff --git a/desktop/tauri/src-tauri/src/config.rs b/desktop/tauri/src-tauri/src/config.rs new file mode 100644 index 00000000..60005295 --- /dev/null +++ b/desktop/tauri/src-tauri/src/config.rs @@ -0,0 +1,45 @@ +use std::fs; + +use log::{debug, error}; +use serde::{Deserialize, Serialize}; +use tauri::{AppHandle, Manager}; + +#[derive(Serialize, Deserialize)] +pub enum Theme { + Light, + Dark, + System, +} + +#[derive(Serialize, Deserialize)] +pub struct Config { + pub theme: Theme, +} + +const CONFIG_FILE_NAME: &'static str = "config.json"; + +pub fn save(app: &AppHandle, config: Config) -> tauri::Result<()> { + let config_dir = app.path().app_config_dir()?; + + let config_path = config_dir.join(CONFIG_FILE_NAME); + debug!("saving config file: {:?}", config_path); + let json = serde_json::to_string_pretty(&config)?; + fs::write(config_path, json)?; + Ok(()) +} + +pub fn load(app: &AppHandle) -> tauri::Result { + let config_dir = app.path().app_config_dir()?; + + let config_path = config_dir.join(CONFIG_FILE_NAME); + if let Ok(json) = fs::read_to_string(config_path) { + if let Ok(config) = serde_json::from_str(&json) { + return Ok(config); + } + } + + error!("failed to load config file returning default config"); + Ok(Config { + theme: Theme::System, + }) +} diff --git a/desktop/tauri/src-tauri/src/main.rs b/desktop/tauri/src-tauri/src/main.rs index 17f9580c..d269c4f3 100644 --- a/desktop/tauri/src-tauri/src/main.rs +++ b/desktop/tauri/src-tauri/src/main.rs @@ -14,6 +14,7 @@ mod service; mod xdg; // App modules +mod config; mod portmaster; mod traymenu; mod window; diff --git a/desktop/tauri/src-tauri/src/traymenu.rs b/desktop/tauri/src-tauri/src/traymenu.rs index b3fef2ba..9d775475 100644 --- a/desktop/tauri/src-tauri/src/traymenu.rs +++ b/desktop/tauri/src-tauri/src/traymenu.rs @@ -1,9 +1,11 @@ +use std::ops::Deref; use std::sync::atomic::AtomicBool; -use std::sync::Mutex; +use std::sync::{Mutex, RwLock}; use std::{collections::HashMap, sync::atomic::Ordering}; use log::{debug, error}; use tauri::tray::{MouseButton, MouseButtonState}; +use tauri::Manager; use tauri::{ image::Image, menu::{MenuBuilder, MenuItem, MenuItemBuilder, PredefinedMenuItem, SubmenuBuilder}, @@ -12,6 +14,7 @@ use tauri::{ }; use tauri_plugin_window_state::{AppHandleExt, StateFlags}; +use crate::config; use crate::{ portapi::{ client::PortAPI, @@ -32,6 +35,17 @@ pub type AppIcon = TrayIcon; static SPN_STATE: AtomicBool = AtomicBool::new(false); +#[derive(Copy, Clone)] +enum IconColor { + Red, + Green, + Blue, + Yellow, +} + +static CURRENT_ICON_COLOR: RwLock = RwLock::new(IconColor::Red); +pub static USER_THEME: RwLock = RwLock::new(dark_light::Mode::Default); + lazy_static! { static ref SPN_STATUS: Mutex>> = Mutex::new(None); static ref SPN_BUTTON: Mutex>> = Mutex::new(None); @@ -42,14 +56,20 @@ const PM_TRAY_ICON_ID: &'static str = "pm_icon"; // Icons +fn get_theme_mode() -> dark_light::Mode { + if let Ok(value) = USER_THEME.read() { + return *value.deref(); + } + return dark_light::detect(); +} + fn get_green_icon() -> &'static [u8] { const LIGHT_GREEN_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_light_green_64.png"); const DARK_GREEN_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_green_64.png"); - let mode = dark_light::detect(); - match mode { + match get_theme_mode() { dark_light::Mode::Light => DARK_GREEN_ICON, _ => LIGHT_GREEN_ICON, } @@ -60,8 +80,7 @@ fn get_blue_icon() -> &'static [u8] { include_bytes!("../../../../assets/data/icons/pm_light_blue_64.png"); const DARK_BLUE_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_blue_64.png"); - let mode = dark_light::detect(); - match mode { + match get_theme_mode() { dark_light::Mode::Light => DARK_BLUE_ICON, _ => LIGHT_BLUE_ICON, } @@ -72,8 +91,7 @@ fn get_red_icon() -> &'static [u8] { include_bytes!("../../../../assets/data/icons/pm_light_red_64.png"); const DARK_RED_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_red_64.png"); - let mode = dark_light::detect(); - match mode { + match get_theme_mode() { dark_light::Mode::Light => DARK_RED_ICON, _ => LIGHT_RED_ICON, } @@ -82,20 +100,28 @@ fn get_red_icon() -> &'static [u8] { fn get_yellow_icon() -> &'static [u8] { const LIGHT_YELLOW_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_light_yellow_64.png"); - const DARK_YELLOW_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_yellow_64.png"); - let mode = dark_light::detect(); - match mode { + match get_theme_mode() { dark_light::Mode::Light => DARK_YELLOW_ICON, _ => LIGHT_YELLOW_ICON, } } +fn get_icon(icon: IconColor) -> &'static [u8] { + match icon { + IconColor::Red => get_red_icon(), + IconColor::Green => get_green_icon(), + IconColor::Blue => get_blue_icon(), + IconColor::Yellow => get_yellow_icon(), + } +} + pub fn setup_tray_menu( app: &mut tauri::App, ) -> core::result::Result> { // Tray menu + load_theme(app.handle()); let open_btn = MenuItemBuilder::with_id("open", "Open App").build(app)?; let exit_ui_btn = MenuItemBuilder::with_id("exit_ui", "Exit UI").build(app)?; let shutdown_btn = MenuItemBuilder::with_id("shutdown", "Shut Down Portmaster").build(app)?; @@ -118,6 +144,7 @@ pub fn setup_tray_menu( let mut button_ref = SPN_STATUS.lock()?; *button_ref = Some(spn_status.clone()); } + // Setup SPN button let spn = MenuItemBuilder::with_id("spn_toggle", "Enable SPN") .build(app) @@ -127,6 +154,19 @@ pub fn setup_tray_menu( *button_ref = Some(spn.clone()); } + let system_theme = MenuItemBuilder::with_id("system_theme", "System") + .build(app) + .unwrap(); + let light_theme = MenuItemBuilder::with_id("light_theme", "Light") + .build(app) + .unwrap(); + let dark_theme = MenuItemBuilder::with_id("dark_theme", "Dark") + .build(app) + .unwrap(); + let theme_menu = SubmenuBuilder::new(app, "Icon Theme") + .items(&[&system_theme, &light_theme, &dark_theme]) + .build()?; + let force_show_window = MenuItemBuilder::with_id("force-show", "Force Show UI").build(app)?; let reload_btn = MenuItemBuilder::with_id("reload", "Reload User Interface").build(app)?; let developer_menu = SubmenuBuilder::new(app, "Developer") @@ -142,6 +182,8 @@ pub fn setup_tray_menu( &spn_status, &spn, &PredefinedMenuItem::separator(app)?, + &theme_menu, + &PredefinedMenuItem::separator(app)?, &exit_ui_btn, &shutdown_btn, &developer_menu, @@ -197,6 +239,9 @@ pub fn setup_tray_menu( "shutdown" => { app.portmaster().trigger_shutdown(); } + "system_theme" => update_icon_theme(app, dark_light::Mode::Default), + "dark_theme" => update_icon_theme(app, dark_light::Mode::Dark), + "light_theme" => update_icon_theme(app, dark_light::Mode::Light), other => { error!("unknown menu event id: {}", other); } @@ -248,16 +293,15 @@ pub fn update_icon(icon: AppIcon, subsystems: HashMap, spn_st } } - let next_icon = match failure.0 { - subsystem::FAILURE_WARNING => get_yellow_icon(), - subsystem::FAILURE_ERROR => get_red_icon(), + let icon_color = match failure.0 { + subsystem::FAILURE_WARNING => IconColor::Yellow, + subsystem::FAILURE_ERROR => IconColor::Red, _ => match spn_status.as_str() { - "connected" | "connecting" => get_blue_icon(), - _ => get_green_icon(), + "connected" | "connecting" => IconColor::Blue, + _ => IconColor::Green, }, }; - - _ = icon.set_icon(Some(Image::from_bytes(next_icon).unwrap())); + update_icon_color(&icon, icon_color); } pub async fn tray_handler(cli: PortAPI, app: tauri::AppHandle) { @@ -333,7 +377,7 @@ pub async fn tray_handler(cli: PortAPI, app: tauri::AppHandle) { } }; - _ = icon.set_icon(Some(Image::from_bytes(get_blue_icon()).unwrap())); + update_icon_color(&icon, IconColor::Blue); let mut subsystems: HashMap = HashMap::new(); let mut spn_status: String = "".to_string(); @@ -439,19 +483,83 @@ pub async fn tray_handler(cli: PortAPI, app: tauri::AppHandle) { }; debug!("Shutdown request received: {:?}", msg); match msg { - Response::Ok(_, _) | Response::New(_, _) | Response::Update(_, _) => { + Response::Ok(msg, _) | Response::New(msg, _) | Response::Update(msg, _) => { if let Err(err) = app.save_window_state(StateFlags::SIZE | StateFlags::POSITION) { error!("failed to save window state: {}", err); } - app.exit(0)}, + debug!("shutting down: {}", msg); + app.exit(0) + }, _ => {}, } } } } - update_spn_ui_state(false); - _ = icon.set_icon(Some(Image::from_bytes(get_red_icon()).unwrap())); + update_icon_color(&icon, IconColor::Red); +} + +fn update_icon_color(icon: &AppIcon, new_color: IconColor) { + if let Ok(mut value) = CURRENT_ICON_COLOR.write() { + *value = new_color; + } + _ = icon.set_icon(Some(Image::from_bytes(get_icon(new_color)).unwrap())); +} + +fn update_icon_theme(app: &tauri::AppHandle, theme: dark_light::Mode) { + if let Ok(mut value) = USER_THEME.write() { + *value = theme; + } + let icon = match app.tray_by_id(PM_TRAY_ICON_ID) { + Some(icon) => icon, + None => { + error!("cancel theme update: missing try icon"); + return; + } + }; + if let Ok(value) = CURRENT_ICON_COLOR.read() { + _ = icon.set_icon(Some(Image::from_bytes(get_icon(*value)).unwrap())); + } + for (_, v) in app.webview_windows() { + super::window::set_window_icon(&v); + } + save_theme(app, theme); +} + +fn load_theme(app: &tauri::AppHandle) { + match config::load(app) { + Ok(config) => { + let theme = match config.theme { + config::Theme::Light => dark_light::Mode::Light, + config::Theme::Dark => dark_light::Mode::Dark, + config::Theme::System => dark_light::Mode::Default, + }; + + if let Ok(mut value) = USER_THEME.write() { + *value = theme; + } + } + Err(err) => error!("failed to load config file: {}", err), + } +} + +fn save_theme(app: &tauri::AppHandle, mode: dark_light::Mode) { + match config::load(app) { + Ok(mut config) => { + let theme = match mode { + dark_light::Mode::Dark => config::Theme::Dark, + dark_light::Mode::Light => config::Theme::Light, + dark_light::Mode::Default => config::Theme::System, + }; + config.theme = theme; + if let Err(err) = config::save(app, config) { + error!("failed to save config file: {}", err) + } else { + debug!("config updated"); + } + } + Err(err) => error!("failed to load config file: {}", err), + } } fn update_spn_ui_state(enabled: bool) { diff --git a/desktop/tauri/src-tauri/src/window.rs b/desktop/tauri/src-tauri/src/window.rs index 09483c09..b5e526a4 100644 --- a/desktop/tauri/src-tauri/src/window.rs +++ b/desktop/tauri/src-tauri/src/window.rs @@ -4,7 +4,7 @@ use tauri::{ WebviewWindow, WebviewWindowBuilder, }; -use crate::portmaster::PortmasterExt; +use crate::{portmaster::PortmasterExt, traymenu}; const LIGHT_PM_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_light_512.png"); @@ -51,11 +51,7 @@ pub fn create_main_window(app: &AppHandle) -> Result { // If the window is not yet navigated to the Portmaster UI, do it now. may_navigate_to_ui(&mut window, false); - - let _ = match dark_light::detect() { - dark_light::Mode::Light => window.set_icon(Image::from_bytes(DARK_PM_ICON).unwrap()), - _ => window.set_icon(Image::from_bytes(LIGHT_PM_ICON).unwrap()), - }; + set_window_icon(&window); #[cfg(debug_assertions)] if let Ok(_) = std::env::var("TAURI_SHOW_IMMEDIATELY") { @@ -83,6 +79,7 @@ pub fn create_splash_window(app: &AppHandle) -> Result { .title("Portmaster") .inner_size(600.0, 250.0) .build()?; + set_window_icon(&window); let _ = window.request_user_attention(Some(UserAttentionType::Informational)); @@ -105,6 +102,23 @@ pub fn hide_splash_window(app: &AppHandle) -> Result<()> { return Err(tauri::Error::WindowNotFound); } +pub fn set_window_icon(window: &WebviewWindow) { + let mut mode = if let Ok(value) = traymenu::USER_THEME.read() { + *value + } else { + dark_light::Mode::Default + }; + + if mode == dark_light::Mode::Default { + mode = dark_light::detect(); + } + + let _ = match mode { + dark_light::Mode::Light => window.set_icon(Image::from_bytes(DARK_PM_ICON).unwrap()), + _ => window.set_icon(Image::from_bytes(LIGHT_PM_ICON).unwrap()), + }; +} + /// Opens a window for the tauri application. /// /// If the main window has already been created, it is instructed to @@ -124,6 +138,7 @@ pub fn open_window(app: &AppHandle) -> Result { app.portmaster().show_window(); let _ = win.show(); let _ = win.set_focus(); + set_window_icon(&win); Ok(win) } None => {