diff --git a/.changes/background-color-apis.md b/.changes/background-color-apis.md new file mode 100644 index 000000000000..853a7540e87b --- /dev/null +++ b/.changes/background-color-apis.md @@ -0,0 +1,6 @@ +--- +"@tauri-apps/api": minor:feat +--- + +Added `Webview::setBackgroundColor`, `WebviewWindow::setBackgroundColor` APIs to set the window background color dynamically +and a `backgroundColor` window option to set the background color on window creation. diff --git a/.changes/background-color.md b/.changes/background-color.md new file mode 100644 index 000000000000..35d120c4ef1e --- /dev/null +++ b/.changes/background-color.md @@ -0,0 +1,8 @@ +--- +"tauri": minor:feat +"tauri-utils": minor:feat +"tauri-runtime": minor:feat +"tauri-runtime-wry": minor:feat +--- + +Added `Window::set_background_color` and `WindowBuilder::background_color`. diff --git a/Cargo.lock b/Cargo.lock index c8242e097152..7902bfd4df58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,32 +237,32 @@ dependencies = [ [[package]] name = "app-store-connect" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61321685c26bccddbeaa34d9d0108db01c7cf00bcc0fe06921fd47af26e17979" +checksum = "33fb5489b9bfcfa3aec2f68cc79eafb999b5af9b9d9d70ca8dfe36acdd1b2b05" dependencies = [ "anyhow", - "base64 0.22.1", + "base64 0.21.7", "clap", "dirs", - "env_logger 0.11.5", + "env_logger 0.10.2", "jsonwebtoken", "log", "pem", "rand 0.8.5", - "reqwest", + "reqwest 0.11.27", "rsa", "serde", "serde_json", "thiserror", - "x509-certificate 0.24.0", + "x509-certificate", ] [[package]] name = "apple-bundles" -version = "0.20.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b06f1e42dc02f590067deabd5ecb3b8fdc13c6432d72670431614de9770832b" +checksum = "abb7c27ee2ca7826adfdc84228cd4c5a84ab57b0a11d269d1d7cd0615238e5a2" dependencies = [ "anyhow", "plist", @@ -272,9 +272,9 @@ dependencies = [ [[package]] name = "apple-codesign" -version = "0.28.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256649c0fce3d8628a0957235db4276bdec01fbec8dd57f5300cdda400dfe4a7" +checksum = "329820aac7259ca0529d3cc21dd3b4c11651225dfce9e0ce25b121b23f923164" dependencies = [ "anyhow", "app-store-connect", @@ -285,7 +285,7 @@ dependencies = [ "aws-sdk-s3", "aws-smithy-http", "aws-smithy-types", - "base64 0.22.1", + "base64 0.21.7", "bcder", "bitflags 2.6.0", "bytes", @@ -298,7 +298,7 @@ dependencies = [ "digest", "dirs", "elliptic-curve 0.13.8", - "env_logger 0.11.5", + "env_logger 0.10.2", "figment", "filetime", "glob", @@ -308,7 +308,7 @@ dependencies = [ "md-5", "minicbor", "num-traits", - "object", + "object 0.32.2", "oid-registry", "once_cell", "p12", @@ -321,7 +321,7 @@ dependencies = [ "rasn", "rayon", "regex", - "reqwest", + "reqwest 0.11.27", "ring", "rsa", "scroll", @@ -340,25 +340,25 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "tungstenite", + "tungstenite 0.21.0", "uuid", "walkdir", "widestring", - "windows-sys 0.59.0", + "windows-sys 0.52.0", "x509", - "x509-certificate 0.24.0", + "x509-certificate", "xml-rs", "yasna", "zeroize", - "zip", + "zip 0.6.6", "zip_structs", ] [[package]] name = "apple-flat-package" -version = "0.19.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500b3e2ffc3e0839ef621a5a5bf8f1b5a54cee3d2a1b6fcdecdc6aba489c2f50" +checksum = "b6adc520e05304de5ec383487786fa20e9c636fe972e59719cdd93621a2db6f1" dependencies = [ "apple-xar", "cpio-archive", @@ -371,11 +371,11 @@ dependencies = [ [[package]] name = "apple-xar" -version = "0.19.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d3fc5c875778d33991009f508004f7c9e47c62e326bf9d5e4513482efc4147" +checksum = "844e00dc1e665b3cf0bba745aa9c6464292ca512db0c11384511586701eb0335" dependencies = [ - "base64 0.22.1", + "base64 0.21.7", "bcder", "bzip2", "chrono", @@ -385,7 +385,7 @@ dependencies = [ "log", "md-5", "rand 0.8.5", - "reqwest", + "reqwest 0.11.27", "scroll", "serde", "serde-xml-rs", @@ -394,7 +394,7 @@ dependencies = [ "signature 2.2.0", "thiserror", "url", - "x509-certificate 0.24.0", + "x509-certificate", "xml-rs", "xz2", ] @@ -457,9 +457,9 @@ checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" [[package]] name = "asn1-rs" -version = "0.6.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -472,25 +472,25 @@ dependencies = [ [[package]] name = "asn1-rs-derive" -version = "0.5.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", - "synstructure", + "syn 1.0.109", + "synstructure 0.12.6", ] [[package]] name = "asn1-rs-impl" -version = "0.2.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 1.0.109", ] [[package]] @@ -1020,7 +1020,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide 0.8.0", - "object", + "object 0.36.5", "rustc-demangle", "windows-targets 0.52.6", ] @@ -1504,7 +1504,7 @@ dependencies = [ "ureq", "which 6.0.3", "windows", - "x509-certificate 0.23.1", + "x509-certificate", ] [[package]] @@ -1979,9 +1979,9 @@ checksum = "80e3adec7390c7643049466136117057188edf5f23efc5c8b4fc8079c8dc34a6" [[package]] name = "cpio-archive" -version = "0.10.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11d34b07689c21889fc89bd7cc885b3244b0157bbededf4a1c159832cd0df05" +checksum = "63d5133d716d3d82da8c76367ddb0ab1733e2629f1462e4f39947e13b8b4b741" dependencies = [ "chrono", "is_executable", @@ -2099,19 +2099,19 @@ dependencies = [ [[package]] name = "cryptographic-message-syntax" -version = "0.27.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a99e58d7755c646cb3f2a138d99f90da4c495282e1700b82daff8a48759ce0" +checksum = "43c324ba1028cef7e3a71a00cbf585637bb0215dec2f6a2b566d094190a1309b" dependencies = [ "bcder", "bytes", "chrono", "hex", "pem", - "reqwest", + "reqwest 0.11.27", "ring", "signature 2.2.0", - "x509-certificate 0.24.0", + "x509-certificate", ] [[package]] @@ -2494,6 +2494,12 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "dpi" version = "0.1.1" @@ -2685,7 +2691,7 @@ dependencies = [ "rustc_version", "toml 0.8.19", "vswhom", - "winreg", + "winreg 0.52.0", ] [[package]] @@ -2757,6 +2763,19 @@ dependencies = [ "regex", ] +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "env_logger" version = "0.11.5" @@ -2949,12 +2968,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" - [[package]] name = "fontconfig-parser" version = "0.5.7" @@ -3449,9 +3462,9 @@ dependencies = [ [[package]] name = "goblin" -version = "0.9.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53ab3f32d1d77146981dea5d6b1e8fe31eedcb7013e5e00d6ccd1259a4b4d923" +checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" dependencies = [ "log", "plain", @@ -3619,9 +3632,6 @@ name = "hashbrown" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" -dependencies = [ - "foldhash", -] [[package]] name = "heck" @@ -3641,6 +3651,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -3840,12 +3856,11 @@ dependencies = [ "hyper 1.4.1", "hyper-util", "rustls 0.23.13", - "rustls-native-certs 0.8.0", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", "tower-service", - "webpki-roots", + "webpki-roots 0.26.6", ] [[package]] @@ -4274,7 +4289,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -4285,6 +4300,17 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is_executable" version = "1.0.4" @@ -4315,6 +4341,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071ed4cc1afd86650602c7b11aa2e1ce30762a1c27193201cb5cee9c6ebb1294" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -4623,7 +4658,7 @@ dependencies = [ "parking_lot", "percent-encoding", "regex", - "reqwest", + "reqwest 0.12.9", "serde", "serde_json", "time", @@ -4646,6 +4681,12 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "jzon" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ab85f84ca42c5ec520e6f3c9966ba1fd62909ce260f8837e248857d2560509" + [[package]] name = "k256" version = "0.13.4" @@ -5082,22 +5123,22 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minicbor" -version = "0.24.4" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29be4f60e41fde478b36998b88821946aafac540e53591e76db53921a0cc225b" +checksum = "9d15f4203d71fdf90903c2696e55426ac97a363c67b218488a73b534ce7aca10" dependencies = [ "minicbor-derive", ] [[package]] name = "minicbor-derive" -version = "0.15.3" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd2209fff77f705b00c737016a48e73733d7fbccb8b007194db148f03561fb70" +checksum = "1154809406efdb7982841adb6311b3d095b46f78342dd646736122fe6b19e267" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 1.0.109", ] [[package]] @@ -5154,7 +5195,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", @@ -5775,18 +5816,27 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "crc32fast", "flate2", - "hashbrown 0.15.0", + "hashbrown 0.14.5", "indexmap 2.6.0", "memchr", "ruzstd", ] +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + [[package]] name = "ocb3" version = "0.1.0" @@ -5801,9 +5851,9 @@ dependencies = [ [[package]] name = "oid-registry" -version = "0.7.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ "asn1-rs", ] @@ -7005,9 +7055,9 @@ dependencies = [ [[package]] name = "rasn" -version = "0.20.2" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e442690f86da40561d5548e7ffb4a18af90d1c1b3536090de847ca2d5a3a6426" +checksum = "cf9b0d03fbc7d2dcfdd35086c43ce30ac5ff62ed7eff4397e4f4f2995a2b0e2a" dependencies = [ "arrayvec", "bitvec", @@ -7015,7 +7065,7 @@ dependencies = [ "bytes", "chrono", "either", - "hashbrown 0.14.5", + "jzon", "konst", "nom", "num-bigint", @@ -7023,22 +7073,21 @@ dependencies = [ "num-traits", "once_cell", "rasn-derive", - "serde_json", "snafu", ] [[package]] name = "rasn-derive" -version = "0.20.2" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0d374c7e4e985e6bc97ca7e7ad1d9642a8415db2017777d6e383002edaab2" +checksum = "cbaf7105cd254b632f4732fbcc243ce750cef87d8335826125ef6df5733b5a0c" dependencies = [ "either", - "itertools 0.13.0", + "itertools 0.10.5", "proc-macro2", "quote", "rayon", - "syn 2.0.87", + "syn 1.0.109", "uuid", ] @@ -7191,6 +7240,48 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-rustls 0.24.2", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration", + "tokio", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg 0.50.0", +] + [[package]] name = "reqwest" version = "0.12.9" @@ -7202,7 +7293,6 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "http-body-util", @@ -7220,7 +7310,6 @@ dependencies = [ "pin-project-lite", "quinn", "rustls 0.23.13", - "rustls-native-certs 0.8.0", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -7237,7 +7326,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 0.26.6", "windows-registry 0.2.0", ] @@ -7527,6 +7616,20 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls" version = "0.23.13" @@ -7567,19 +7670,6 @@ dependencies = [ "security-framework", ] -[[package]] -name = "rustls-native-certs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" -dependencies = [ - "openssl-probe", - "rustls-pemfile 2.2.0", - "rustls-pki-types", - "schannel", - "security-framework", -] - [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -7663,10 +7753,12 @@ dependencies = [ [[package]] name = "ruzstd" -version = "0.7.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3938e133aac070997ddc684d4b393777d293ba170f2988c8fd5ea2ad4ce21" +checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" dependencies = [ + "byteorder", + "derive_more", "twox-hash", ] @@ -8352,23 +8444,25 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "snafu" -version = "0.8.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" dependencies = [ + "backtrace", + "doc-comment", "snafu-derive", ] [[package]] name = "snafu-derive" -version = "0.8.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.87", + "syn 1.0.109", ] [[package]] @@ -8745,6 +8839,18 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + [[package]] name = "synstructure" version = "0.13.1" @@ -8769,6 +8875,27 @@ dependencies = [ "walkdir", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -8784,9 +8911,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", @@ -8889,7 +9016,7 @@ dependencies = [ "quickcheck", "quickcheck_macros", "raw-window-handle", - "reqwest", + "reqwest 0.12.9", "serde", "serde_json", "serde_repr", @@ -8978,7 +9105,7 @@ dependencies = [ "walkdir", "windows-registry 0.3.0", "windows-sys 0.59.0", - "zip", + "zip 2.2.0", ] [[package]] @@ -9025,7 +9152,7 @@ dependencies = [ "minisign", "notify", "notify-debouncer-mini", - "object", + "object 0.36.5", "os_info", "os_pipe", "oxc_allocator", @@ -9152,7 +9279,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "x509-certificate 0.24.0", + "x509-certificate", ] [[package]] @@ -9449,6 +9576,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "terminal_size" version = "0.2.6" @@ -9686,7 +9822,7 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite", + "tungstenite 0.24.0", ] [[package]] @@ -9887,9 +10023,9 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.24.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", @@ -9898,11 +10034,30 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.23.13", + "rustls 0.22.4", "rustls-native-certs 0.7.3", "rustls-pki-types", "sha1", "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror", "utf-8", ] @@ -10089,6 +10244,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "universal-hash" version = "0.5.1" @@ -10126,7 +10287,7 @@ dependencies = [ "rustls-pki-types", "socks", "url", - "webpki-roots", + "webpki-roots 0.26.6", ] [[package]] @@ -10498,6 +10659,12 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webpki-roots" version = "0.26.6" @@ -10969,6 +11136,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winreg" version = "0.52.0" @@ -11185,25 +11362,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "x509-certificate" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57b9f8bcae7c1f36479821ae826d75050c60ce55146fd86d3553ed2573e2762" -dependencies = [ - "bcder", - "bytes", - "chrono", - "der 0.7.9", - "hex", - "pem", - "ring", - "signature 2.2.0", - "spki 0.7.3", - "thiserror", - "zeroize", -] - [[package]] name = "xattr" version = "1.3.1" @@ -11275,7 +11433,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.87", - "synstructure", + "synstructure 0.13.1", ] [[package]] @@ -11317,7 +11475,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.87", - "synstructure", + "synstructure 0.13.1", ] [[package]] @@ -11362,6 +11520,18 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] + [[package]] name = "zip" version = "2.2.0" diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index a856b35b7cfb..4bc434e06f32 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -505,6 +505,17 @@ "boolean", "null" ] + }, + "backgroundColor": { + "description": "Set the window and webview background color.\n\n ## Platform-specific:\n\n - **Windows**: alpha channel is ignored for the window layer.\n - **Windows**: On Windows 7, alpha channel is ignored for the webview layer.\n - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored for the webview layer.", + "anyOf": [ + { + "$ref": "#/definitions/Color" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false @@ -846,32 +857,96 @@ ] }, "Color": { - "description": "a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255.", - "type": "array", - "items": [ + "anyOf": [ { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Color hex string, for example: #fff, #ffffff, or #ffffffff.", + "type": "string", + "pattern": "^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$" }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Array of RGB colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Array of RGBA colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 4, + "minItems": 4 }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Object of red, green, blue, alpha color values. Each value has minimum of 0 and maximum of 255.", + "type": "object", + "required": [ + "blue", + "green", + "red" + ], + "properties": { + "red": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "green": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "blue": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "alpha": { + "default": 255, + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } } - ], - "maxItems": 4, - "minItems": 4 + ] }, "SecurityConfig": { "description": "Security configuration.\n\n See more: ", diff --git a/crates/tauri-macos-sign/Cargo.toml b/crates/tauri-macos-sign/Cargo.toml index f293263219a9..8fd33172827c 100644 --- a/crates/tauri-macos-sign/Cargo.toml +++ b/crates/tauri-macos-sign/Cargo.toml @@ -14,13 +14,13 @@ anyhow = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" tempfile = "3" -x509-certificate = "0.24" +x509-certificate = "0.23" once-cell-regex = "0.2" os_pipe = "1" plist = "1" rand = "0.8" dirs-next = "2" log = { version = "0.4.21", features = ["kv"] } -apple-codesign = "0.28" +apple-codesign = "0.27" chrono = "0.4.38" p12 = "0.6" diff --git a/crates/tauri-runtime-wry/Cargo.toml b/crates/tauri-runtime-wry/Cargo.toml index dd7ab2009b39..9633ba0987b1 100644 --- a/crates/tauri-runtime-wry/Cargo.toml +++ b/crates/tauri-runtime-wry/Cargo.toml @@ -23,7 +23,7 @@ wry = { version = "0.46.1", default-features = false, features = [ "os-webview", "linux-body", ] } -tao = { version = "0.30.2", default-features = false, features = ["rwh_06"] } +tao = { version = "0.30.5", default-features = false, features = ["rwh_06"] } tauri-runtime = { version = "2.1.0", path = "../tauri-runtime" } tauri-utils = { version = "2.0.2", path = "../tauri-utils" } raw-window-handle = "0.6" diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index cde760ba7587..bde9d3ccd7fd 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -65,7 +65,10 @@ use tao::{ }; #[cfg(target_os = "macos")] use tauri_utils::TitleBarStyle; -use tauri_utils::{config::WindowConfig, Theme}; +use tauri_utils::{ + config::{Color, WindowConfig}, + Theme, +}; use url::Url; use wry::{ DragDropEvent as WryDragDropEvent, ProxyConfig, ProxyEndpoint, WebContext as WryWebContext, @@ -842,6 +845,9 @@ impl WindowBuilder for WindowBuilderWrapper { if let Some(max_height) = config.max_height { constraints.max_height = Some(tao::dpi::LogicalUnit::new(max_height).into()); } + if let Some(color) = config.background_color { + window = window.background_color(color); + } window = window.inner_size_constraints(constraints); if let (Some(x), Some(y)) = (config.x, config.y) { @@ -1080,6 +1086,11 @@ impl WindowBuilder for WindowBuilderWrapper { Ok(self) } + fn background_color(mut self, color: Color) -> Self { + self.inner = self.inner.with_background_color(color.into()); + self + } + #[cfg(any(windows, target_os = "linux"))] fn skip_taskbar(mut self, skip: bool) -> Self { self.inner = self.inner.with_skip_taskbar(skip); @@ -1255,6 +1266,7 @@ pub enum WindowMessage { SetProgressBar(ProgressBarState), SetTitleBarStyle(tauri_utils::TitleBarStyle), SetTheme(Option), + SetBackgroundColor(Option), DragWindow, ResizeDragWindow(tauri_runtime::ResizeDirection), RequestRedraw, @@ -1296,6 +1308,7 @@ pub enum WebviewMessage { Reparent(WindowId, Sender>), SetAutoResize(bool), SetZoom(f64), + SetBackgroundColor(Option), ClearAllBrowsingData, // Getters Url(Sender>), @@ -1612,6 +1625,17 @@ impl WebviewDispatch for WryWebviewDispatcher { ), ) } + + fn set_background_color(&self, color: Option) -> Result<()> { + send_user_message( + &self.context, + Message::Webview( + *self.window_id.lock().unwrap(), + self.webview_id, + WebviewMessage::SetBackgroundColor(color), + ), + ) + } } /// The Tauri [`WindowDispatch`] for [`Wry`]. @@ -2124,6 +2148,13 @@ impl WindowDispatch for WryWindowDispatcher { Message::Window(self.window_id, WindowMessage::SetTheme(theme)), ) } + + fn set_background_color(&self, color: Option) -> Result<()> { + send_user_message( + &self.context, + Message::Window(self.window_id, WindowMessage::SetBackgroundColor(color)), + ) + } } #[derive(Clone)] @@ -2172,6 +2203,8 @@ pub struct WindowWrapper { webviews: Vec, window_event_listeners: WindowEventListeners, #[cfg(windows)] + background_color: Option, + #[cfg(windows)] is_window_transparent: bool, #[cfg(windows)] surface: Option, Arc>>, @@ -3097,6 +3130,9 @@ fn handle_user_message( _ => None, }); } + WindowMessage::SetBackgroundColor(color) => { + window.set_background_color(color.map(Into::into)) + } } } } @@ -3292,6 +3328,13 @@ fn handle_user_message( log::error!("failed to set webview zoom: {e}"); } } + WebviewMessage::SetBackgroundColor(color) => { + if let Err(e) = + webview.set_background_color(color.map(Into::into).unwrap_or((255, 255, 255, 255))) + { + log::error!("failed to set webview background color: {e}"); + } + } WebviewMessage::ClearAllBrowsingData => { if let Err(e) = webview.clear_all_browsing_data() { log::error!("failed to clear webview browsing data: {e}"); @@ -3460,6 +3503,8 @@ fn handle_user_message( Message::CreateRawWindow(window_id, handler, sender) => { let (label, builder) = handler(); + #[cfg(windows)] + let background_color = builder.window.background_color; #[cfg(windows)] let is_window_transparent = builder.window.transparent; @@ -3472,7 +3517,7 @@ fn handle_user_message( let surface = if is_window_transparent { if let Ok(context) = softbuffer::Context::new(window.clone()) { if let Ok(mut surface) = softbuffer::Surface::new(&context, window.clone()) { - window.clear_surface(&mut surface); + window.draw_surface(&mut surface, background_color); Some(surface) } else { None @@ -3493,6 +3538,8 @@ fn handle_user_message( window_event_listeners: Default::default(), webviews: Vec::new(), #[cfg(windows)] + background_color, + #[cfg(windows)] is_window_transparent, #[cfg(windows)] surface, @@ -3556,9 +3603,10 @@ fn handle_event_loop( let mut windows_ref = windows.0.borrow_mut(); if let Some(window) = windows_ref.get_mut(&window_id) { if window.is_window_transparent { + let background_color = window.background_color; if let Some(surface) = &mut window.surface { if let Some(window) = &window.inner { - window.clear_surface(surface); + window.draw_surface(surface, background_color); } } } @@ -3842,6 +3890,8 @@ fn create_window( let window_event_listeners = WindowEventListeners::default(); + #[cfg(windows)] + let background_color = window_builder.inner.window.background_color; #[cfg(windows)] let is_window_transparent = window_builder.inner.window.transparent; @@ -3973,7 +4023,7 @@ fn create_window( let surface = if is_window_transparent { if let Ok(context) = softbuffer::Context::new(window.clone()) { if let Ok(mut surface) = softbuffer::Surface::new(&context, window.clone()) { - window.clear_surface(&mut surface); + window.draw_surface(&mut surface, background_color); Some(surface) } else { None @@ -3992,6 +4042,8 @@ fn create_window( webviews, window_event_listeners, #[cfg(windows)] + background_color, + #[cfg(windows)] is_window_transparent, #[cfg(windows)] surface, @@ -4079,6 +4131,10 @@ fn create_webview( webview_builder = webview_builder.with_https_scheme(webview_attributes.use_https_scheme); } + if let Some(color) = webview_attributes.background_color { + webview_builder = webview_builder.with_background_color(color.into()); + } + if webview_attributes.drag_drop_handler_enabled { let proxy = context.proxy.clone(); let window_id_ = window_id.clone(); diff --git a/crates/tauri-runtime-wry/src/window/mod.rs b/crates/tauri-runtime-wry/src/window/mod.rs index 1c649e0764dd..c2b1b448686d 100644 --- a/crates/tauri-runtime-wry/src/window/mod.rs +++ b/crates/tauri-runtime-wry/src/window/mod.rs @@ -39,12 +39,13 @@ pub trait WindowExt { /// Clears the window sufrace. i.e make it it transparent. #[cfg(windows)] - fn clear_surface( + fn draw_surface( &self, surface: &mut softbuffer::Surface< std::sync::Arc, std::sync::Arc, >, + background_color: Option, ); } diff --git a/crates/tauri-runtime-wry/src/window/windows.rs b/crates/tauri-runtime-wry/src/window/windows.rs index f7825051f777..6c032beabda8 100644 --- a/crates/tauri-runtime-wry/src/window/windows.rs +++ b/crates/tauri-runtime-wry/src/window/windows.rs @@ -43,12 +43,13 @@ impl super::WindowExt for tao::window::Window { } } - fn clear_surface( + fn draw_surface( &self, surface: &mut softbuffer::Surface< std::sync::Arc, std::sync::Arc, >, + background_color: Option, ) { let size = self.inner_size(); if let (Some(width), Some(height)) = ( @@ -57,7 +58,10 @@ impl super::WindowExt for tao::window::Window { ) { surface.resize(width, height).unwrap(); let mut buffer = surface.buffer_mut().unwrap(); - buffer.fill(0); + let color = background_color + .map(|(r, g, b, _)| (b as u32) | ((g as u32) << 8) | ((r as u32) << 16)) + .unwrap_or(0); + buffer.fill(color); let _ = buffer.present(); } } diff --git a/crates/tauri-runtime/src/lib.rs b/crates/tauri-runtime/src/lib.rs index b1e2c7184f61..1257dab15f86 100644 --- a/crates/tauri-runtime/src/lib.rs +++ b/crates/tauri-runtime/src/lib.rs @@ -18,6 +18,7 @@ use raw_window_handle::DisplayHandle; use serde::{Deserialize, Serialize}; use std::{borrow::Cow, fmt::Debug, sync::mpsc::Sender}; +use tauri_utils::config::Color; use tauri_utils::Theme; use url::Url; use webview::{DetachedWebview, PendingWebview}; @@ -523,6 +524,9 @@ pub trait WebviewDispatch: Debug + Clone + Send + Sync + Sized + ' /// Set the webview zoom level fn set_zoom(&self, scale_factor: f64) -> Result<()>; + /// Set the webview background. + fn set_background_color(&self, color: Option) -> Result<()>; + /// Clear all browsing data for this webview. fn clear_all_browsing_data(&self) -> Result<()>; } @@ -753,6 +757,9 @@ pub trait WindowDispatch: Debug + Clone + Send + Sync + Sized + 's /// Updates the window visibleOnAllWorkspaces flag. fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>; + /// Set the window background. + fn set_background_color(&self, color: Option) -> Result<()>; + /// Prevents the window contents from being captured by other apps. fn set_content_protected(&self, protected: bool) -> Result<()>; diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index 203d97b9422e..e17b9e197396 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -7,7 +7,7 @@ use crate::{window::is_label_valid, Rect, Runtime, UserEvent}; use http::Request; -use tauri_utils::config::{WebviewUrl, WindowConfig, WindowEffectsConfig}; +use tauri_utils::config::{Color, WebviewUrl, WindowConfig, WindowEffectsConfig}; use url::Url; use std::{ @@ -212,6 +212,7 @@ pub struct WebviewAttributes { pub browser_extensions_enabled: bool, pub use_https_scheme: bool, pub devtools: Option, + pub background_color: Option, } impl From<&WindowConfig> for WebviewAttributes { @@ -243,6 +244,9 @@ impl From<&WindowConfig> for WebviewAttributes { if let Some(url) = &config.proxy_url { builder = builder.proxy_url(url.to_owned()); } + if let Some(color) = config.background_color { + builder = builder.background_color(color); + } builder } } @@ -270,6 +274,7 @@ impl WebviewAttributes { browser_extensions_enabled: false, use_https_scheme: false, devtools: None, + background_color: None, } } @@ -424,6 +429,17 @@ impl WebviewAttributes { self.devtools = enabled; self } + + /// Set the window and webview background color. + /// ## Platform-specific: + /// + /// - **Windows**: On Windows 7, alpha channel is ignored for the webview layer. + /// - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + #[must_use] + pub fn background_color(mut self, color: Color) -> Self { + self.background_color = Some(color); + self + } } /// IPC handler. diff --git a/crates/tauri-runtime/src/window.rs b/crates/tauri-runtime/src/window.rs index 69f8eaf8a5c7..dc843100da98 100644 --- a/crates/tauri-runtime/src/window.rs +++ b/crates/tauri-runtime/src/window.rs @@ -11,7 +11,10 @@ use crate::{ use dpi::PixelUnit; use serde::{Deserialize, Deserializer, Serialize}; -use tauri_utils::{config::WindowConfig, Theme}; +use tauri_utils::{ + config::{Color, WindowConfig}, + Theme, +}; #[cfg(windows)] use windows::Win32::Foundation::HWND; @@ -354,6 +357,10 @@ pub trait WindowBuilder: WindowBuilderBase { #[must_use] fn skip_taskbar(self, skip: bool) -> Self; + /// Set the window background color. + #[must_use] + fn background_color(self, color: Color) -> Self; + /// Sets whether or not the window has shadow. /// /// ## Platform-specific diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index a856b35b7cfb..4bc434e06f32 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -505,6 +505,17 @@ "boolean", "null" ] + }, + "backgroundColor": { + "description": "Set the window and webview background color.\n\n ## Platform-specific:\n\n - **Windows**: alpha channel is ignored for the window layer.\n - **Windows**: On Windows 7, alpha channel is ignored for the webview layer.\n - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored for the webview layer.", + "anyOf": [ + { + "$ref": "#/definitions/Color" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false @@ -846,32 +857,96 @@ ] }, "Color": { - "description": "a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255.", - "type": "array", - "items": [ + "anyOf": [ { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Color hex string, for example: #fff, #ffffff, or #ffffffff.", + "type": "string", + "pattern": "^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$" }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Array of RGB colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Array of RGBA colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 4, + "minItems": 4 }, { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "description": "Object of red, green, blue, alpha color values. Each value has minimum of 0 and maximum of 255.", + "type": "object", + "required": [ + "blue", + "green", + "red" + ], + "properties": { + "red": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "green": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "blue": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "alpha": { + "default": 255, + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } } - ], - "maxItems": 4, - "minItems": 4 + ] }, "SecurityConfig": { "description": "Security configuration.\n\n See more: ", diff --git a/crates/tauri-schema-worker/src/config.rs b/crates/tauri-schema-worker/src/config.rs index 41669eceb344..b4c818b910bf 100644 --- a/crates/tauri-schema-worker/src/config.rs +++ b/crates/tauri-schema-worker/src/config.rs @@ -106,7 +106,7 @@ async fn try_next_schema() -> anyhow::Result { async fn schema_file_for_version(version: Version) -> anyhow::Result { let cache = Cache::open("schema".to_string()).await; - let cache_key = format!("https://scheam.tauri.app/config/{version}"); + let cache_key = format!("https://schema.tauri.app/config/{version}"); if let Some(mut cached) = cache.get(cache_key.clone(), true).await? { console_log!("Serving schema for {version} from cache"); return cached.text().await.map_err(Into::into); diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index 85fe4c8ac537..349873126393 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -1276,9 +1276,8 @@ pub struct BundleConfig { pub android: AndroidConfig, } -/// a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255. -#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)] -#[cfg_attr(feature = "schema", derive(JsonSchema))] +/// A tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255. +#[derive(Debug, PartialEq, Eq, Serialize, Default, Clone, Copy)] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct Color(pub u8, pub u8, pub u8, pub u8); @@ -1288,6 +1287,139 @@ impl From for (u8, u8, u8, u8) { } } +impl From for (u8, u8, u8) { + fn from(value: Color) -> Self { + (value.0, value.1, value.2) + } +} + +impl From<(u8, u8, u8, u8)> for Color { + fn from(value: (u8, u8, u8, u8)) -> Self { + Color(value.0, value.1, value.2, value.3) + } +} + +impl From<(u8, u8, u8)> for Color { + fn from(value: (u8, u8, u8)) -> Self { + Color(value.0, value.1, value.2, 255) + } +} + +impl From for [u8; 4] { + fn from(value: Color) -> Self { + [value.0, value.1, value.2, value.3] + } +} + +impl From for [u8; 3] { + fn from(value: Color) -> Self { + [value.0, value.1, value.2] + } +} + +impl From<[u8; 4]> for Color { + fn from(value: [u8; 4]) -> Self { + Color(value[0], value[1], value[2], value[3]) + } +} + +impl From<[u8; 3]> for Color { + fn from(value: [u8; 3]) -> Self { + Color(value[0], value[1], value[2], 255) + } +} + +impl FromStr for Color { + type Err = String; + fn from_str(mut color: &str) -> Result { + color = color.trim().strip_prefix('#').unwrap_or(color); + let color = match color.len() { + // TODO: use repeat_n once our MSRV is bumped to 1.82 + 3 => color.chars() + .flat_map(|c| std::iter::repeat(c).take(2)) + .chain(std::iter::repeat('f').take(2)) + .collect(), + 6 => format!("{color}FF"), + 8 => color.to_string(), + _ => return Err("Invalid hex color length, must be either 3, 6 or 8, for example: #fff, #ffffff, or #ffffffff".into()), + }; + + let r = u8::from_str_radix(&color[0..2], 16).map_err(|e| e.to_string())?; + let g = u8::from_str_radix(&color[2..4], 16).map_err(|e| e.to_string())?; + let b = u8::from_str_radix(&color[4..6], 16).map_err(|e| e.to_string())?; + let a = u8::from_str_radix(&color[6..8], 16).map_err(|e| e.to_string())?; + + Ok(Color(r, g, b, a)) + } +} + +fn default_alpha() -> u8 { + 255 +} + +#[derive(Deserialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(untagged)] +enum InnerColor { + /// Color hex string, for example: #fff, #ffffff, or #ffffffff. + String(String), + /// Array of RGB colors. Each value has minimum of 0 and maximum of 255. + Rgb((u8, u8, u8)), + /// Array of RGBA colors. Each value has minimum of 0 and maximum of 255. + Rgba((u8, u8, u8, u8)), + /// Object of red, green, blue, alpha color values. Each value has minimum of 0 and maximum of 255. + RgbaObject { + red: u8, + green: u8, + blue: u8, + #[serde(default = "default_alpha")] + alpha: u8, + }, +} + +impl<'de> Deserialize<'de> for Color { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let color = InnerColor::deserialize(deserializer)?; + let color = match color { + InnerColor::String(string) => string.parse().map_err(serde::de::Error::custom)?, + InnerColor::Rgb(rgb) => Color(rgb.0, rgb.1, rgb.2, 255), + InnerColor::Rgba(rgb) => rgb.into(), + InnerColor::RgbaObject { + red, + green, + blue, + alpha, + } => Color(red, green, blue, alpha), + }; + + Ok(color) + } +} + +#[cfg(feature = "schema")] +impl schemars::JsonSchema for Color { + fn schema_name() -> String { + "Color".to_string() + } + + fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let mut schema = schemars::schema_for!(InnerColor).schema; + schema.metadata = None; // Remove `title: InnerColor` from schema + + // add hex color pattern validation + let any_of = schema.subschemas().any_of.as_mut().unwrap(); + let schemars::schema::Schema::Object(str_schema) = any_of.first_mut().unwrap() else { + unreachable!() + }; + str_schema.string().pattern = Some("^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$".into()); + + schema.into() + } +} + /// The window effects configuration object #[skip_serializing_none] #[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)] @@ -1502,6 +1634,7 @@ pub struct WindowConfig { /// ## Platform-specific /// /// - **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+. + #[serde(alias = "proxy-url")] pub proxy_url: Option, /// Whether page zooming by hotkeys is enabled /// @@ -1512,7 +1645,7 @@ pub struct WindowConfig { /// 20% in each step, ranging from 20% to 1000%. Requires `webview:allow-set-webview-zoom` permission /// /// - **Android / iOS**: Unsupported. - #[serde(default)] + #[serde(default, alias = "zoom-hotkeys-enabled")] pub zoom_hotkeys_enabled: bool, /// Whether browser extensions can be installed for the webview process /// @@ -1520,7 +1653,7 @@ pub struct WindowConfig { /// /// - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled) /// - **MacOS / Linux / iOS / Android** - Unsupported. - #[serde(default)] + #[serde(default, alias = "browser-extensions-enabled")] pub browser_extensions_enabled: bool, /// Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`. @@ -1544,6 +1677,16 @@ pub struct WindowConfig { /// - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android. /// - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window. pub devtools: Option, + + /// Set the window and webview background color. + /// + /// ## Platform-specific: + /// + /// - **Windows**: alpha channel is ignored for the window layer. + /// - **Windows**: On Windows 7, alpha channel is ignored for the webview layer. + /// - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored for the webview layer. + #[serde(alias = "background-color")] + pub background_color: Option, } impl Default for WindowConfig { @@ -1595,6 +1738,7 @@ impl Default for WindowConfig { browser_extensions_enabled: false, use_https_scheme: false, devtools: None, + background_color: None, } } } @@ -2847,6 +2991,7 @@ mod build { let browser_extensions_enabled = self.browser_extensions_enabled; let use_https_scheme = self.use_https_scheme; let devtools = opt_lit(self.devtools.as_ref()); + let background_color = opt_lit(self.background_color.as_ref()); literal_struct!( tokens, @@ -2896,7 +3041,8 @@ mod build { zoom_hotkeys_enabled, browser_extensions_enabled, use_https_scheme, - devtools + devtools, + background_color ); } } @@ -3390,4 +3536,15 @@ mod test { assert_eq!(d_bundle, bundle); assert_eq!(d_windows, app.windows); } + + #[test] + fn parse_hex_color() { + use super::Color; + + assert_eq!(Color(255, 255, 255, 255), "fff".parse().unwrap()); + assert_eq!(Color(255, 255, 255, 255), "#fff".parse().unwrap()); + assert_eq!(Color(0, 0, 0, 255), "#000000".parse().unwrap()); + assert_eq!(Color(0, 0, 0, 255), "#000000ff".parse().unwrap()); + assert_eq!(Color(0, 255, 0, 255), "#00ff00ff".parse().unwrap()); + } } diff --git a/crates/tauri/scripts/bundle.global.js b/crates/tauri/scripts/bundle.global.js index 316e09b65f99..760a790a1605 100644 --- a/crates/tauri/scripts/bundle.global.js +++ b/crates/tauri/scripts/bundle.global.js @@ -1 +1 @@ -var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i,r,s,a;"function"==typeof SuppressedError&&SuppressedError;const l="__TAURI_TO_IPC_KEY__";function o(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}class u{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),r.set(this,0),s.set(this,{}),this.id=o((({message:e,id:a})=>{if(a===n(this,r,"f")){t(this,r,a+1,"f"),n(this,i,"f").call(this,e);const l=Object.keys(n(this,s,"f"));if(l.length>0){let e=a+1;for(const t of l.sort()){if(parseInt(t)!==e)break;{const r=n(this,s,"f")[t];delete n(this,s,"f")[t],n(this,i,"f").call(this,r),e+=1}}t(this,r,e,"f")}}else n(this,s,"f")[a.toString()]=e}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,r=new WeakMap,s=new WeakMap,l)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[l]()}}class c{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function d(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}class h{get rid(){return n(this,a,"f")}constructor(e){a.set(this,void 0),t(this,a,e,"f")}async close(){return d("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;var p=Object.freeze({__proto__:null,Channel:u,PluginListener:c,Resource:h,SERIALIZE_TO_IPC_FN:l,addPluginListener:async function(e,n,t){const i=new u;return i.onmessage=t,d(`plugin:${e}|registerListener`,{event:n,handler:i}).then((()=>new c(e,n,i.id)))},checkPermissions:async function(e){return d(`plugin:${e}|check_permissions`)},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:d,isTauri:function(){return"isTauri"in window&&!!window.isTauri},requestPermissions:async function(e){return d(`plugin:${e}|request_permissions`)},transformCallback:o});class w extends h{constructor(e){super(e)}static async new(e,n,t){return d("plugin:image|new",{rgba:y(e),width:n,height:t}).then((e=>new w(e)))}static async fromBytes(e){return d("plugin:image|from_bytes",{bytes:y(e)}).then((e=>new w(e)))}static async fromPath(e){return d("plugin:image|from_path",{path:e}).then((e=>new w(e)))}async rgba(){return d("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return d("plugin:image|size",{rid:this.rid})}}function y(e){return null==e?null:"string"==typeof e?e:e instanceof w?e.rid:e}var _=Object.freeze({__proto__:null,Image:w,transformImage:y});var g=Object.freeze({__proto__:null,defaultWindowIcon:async function(){return d("plugin:app|default_window_icon").then((e=>e?new w(e):null))},getName:async function(){return d("plugin:app|name")},getTauriVersion:async function(){return d("plugin:app|tauri_version")},getVersion:async function(){return d("plugin:app|version")},hide:async function(){return d("plugin:app|app_hide")},setTheme:async function(e){return d("plugin:app|set_app_theme",{theme:e})},show:async function(){return d("plugin:app|app_show")}});class b{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.width=e[0].Logical.width,this.height=e[0].Logical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toPhysical(e){return new m(this.width*e,this.height*e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class m{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.width=e[0].Physical.width,this.height=e[0].Physical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toLogical(e){return new b(this.width/e,this.height/e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class v{constructor(e){this.size=e}toLogical(e){return this.size instanceof b?this.size:this.size.toLogical(e)}toPhysical(e){return this.size instanceof m?this.size:this.size.toPhysical(e)}[l](){return{[`${this.size.type}`]:{width:this.size.width,height:this.size.height}}}toJSON(){return this[l]()}}class f{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.x=e[0].Logical.x,this.y=e[0].Logical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toPhysical(e){return new k(this.x*e,this.x*e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class k{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.x=e[0].Physical.x,this.y=e[0].Physical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toLogical(e){return new f(this.x/e,this.x/e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class A{constructor(e){this.position=e}toLogical(e){return this.position instanceof f?this.position:this.position.toLogical(e)}toPhysical(e){return this.position instanceof k?this.position:this.position.toPhysical(e)}[l](){return{[`${this.position.type}`]:{x:this.position.x,y:this.position.y}}}toJSON(){return this[l]()}}var E,T=Object.freeze({__proto__:null,LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,Position:A,Size:v});async function D(e,n){await d("plugin:event|unlisten",{event:e,eventId:n})}async function I(e,n,t){var i;const r="string"==typeof(null==t?void 0:t.target)?{kind:"AnyLabel",label:t.target}:null!==(i=null==t?void 0:t.target)&&void 0!==i?i:{kind:"Any"};return d("plugin:event|listen",{event:e,target:r,handler:o(n)}).then((n=>async()=>D(e,n)))}async function R(e,n,t){return I(e,(t=>{D(e,t.id),n(t)}),t)}async function S(e,n){await d("plugin:event|emit",{event:e,payload:n})}async function L(e,n,t){const i="string"==typeof e?{kind:"AnyLabel",label:e}:e;await d("plugin:event|emit_to",{target:i,event:n,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(E||(E={}));var x,N,C,P=Object.freeze({__proto__:null,get TauriEvent(){return E},emit:S,emitTo:L,listen:I,once:R});function z(e){var n;if("items"in e)e.items=null===(n=e.items)||void 0===n?void 0:n.map((e=>"rid"in e?e:z(e)));else if("action"in e&&e.action){const n=new u;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function W(e,n){const t=new u;if(n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items)){function i(e){var n;return"rid"in e?[e.rid,e.kind]:("item"in e&&"object"==typeof e.item&&(null===(n=e.item.About)||void 0===n?void 0:n.icon)&&(e.item.About.icon=y(e.item.About.icon)),"icon"in e&&e.icon&&(e.icon=y(e.icon)),"items"in e&&e.items&&(e.items=e.items.map(i)),z(e))}n.items=n.items.map(i)}return d("plugin:menu|new",{kind:e,options:n,handler:t})}class O extends h{get id(){return n(this,x,"f")}get kind(){return n(this,N,"f")}constructor(e,n,i){super(e),x.set(this,void 0),N.set(this,void 0),t(this,x,n,"f"),t(this,N,i,"f")}}x=new WeakMap,N=new WeakMap;class F extends O{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return W("MenuItem",e).then((([e,n])=>new F(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class M extends O{constructor(e,n){super(e,n,"Check")}static async new(e){return W("Check",e).then((([e,n])=>new M(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return d("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return d("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(C||(C={}));class U extends O{constructor(e,n){super(e,n,"Icon")}static async new(e){return W("Icon",e).then((([e,n])=>new U(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return d("plugin:menu|set_icon",{rid:this.rid,icon:y(e)})}}class B extends O{constructor(e,n){super(e,n,"Predefined")}static async new(e){return W("Predefined",e).then((([e,n])=>new B(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}function j([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class V extends O{constructor(e,n){super(e,n,"Submenu")}static async new(e){return W("Submenu",e).then((([e,n])=>new V(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(j)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(j)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?j(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsWindowsMenuForNSApp(){return d("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return d("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function G([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class H extends O{constructor(e,n){super(e,n,"Menu")}static async new(e){return W("Menu",e).then((([e,n])=>new H(e,n)))}static async default(){return d("plugin:menu|create_default").then((([e,n])=>new H(e,n)))}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(G)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(G)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?G(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsAppMenu(){return d("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new H(e[0],e[1]):null))}async setAsWindowMenu(e){var n;return d("plugin:menu|set_as_window_menu",{rid:this.rid,window:null!==(n=null==e?void 0:e.label)&&void 0!==n?n:null}).then((e=>e?new H(e[0],e[1]):null))}}var $=Object.freeze({__proto__:null,CheckMenuItem:M,IconMenuItem:U,Menu:H,MenuItem:F,get NativeIcon(){return C},PredefinedMenuItem:B,Submenu:V});function q(){var e;window.__TAURI_INTERNALS__=null!==(e=window.__TAURI_INTERNALS__)&&void 0!==e?e:{}}var J,Q=Object.freeze({__proto__:null,clearMocks:function(){var e,n,t;"object"==typeof window.__TAURI_INTERNALS__&&((null===(e=window.__TAURI_INTERNALS__)||void 0===e?void 0:e.convertFileSrc)&&delete window.__TAURI_INTERNALS__.convertFileSrc,(null===(n=window.__TAURI_INTERNALS__)||void 0===n?void 0:n.invoke)&&delete window.__TAURI_INTERNALS__.invoke,(null===(t=window.__TAURI_INTERNALS__)||void 0===t?void 0:t.metadata)&&delete window.__TAURI_INTERNALS__.metadata)},mockConvertFileSrc:function(e){q(),window.__TAURI_INTERNALS__.convertFileSrc=function(n,t="asset"){const i=encodeURIComponent(n);return"windows"===e?`http://${t}.localhost/${i}`:`${t}://localhost/${i}`}},mockIPC:function(e){q(),window.__TAURI_INTERNALS__.transformCallback=function(e,n=!1){const t=window.crypto.getRandomValues(new Uint32Array(1))[0],i=`_${t}`;return Object.defineProperty(window,i,{value:t=>(n&&Reflect.deleteProperty(window,i),e&&e(t)),writable:!1,configurable:!0}),t},window.__TAURI_INTERNALS__.invoke=function(n,t,i){return e(n,t)}},mockWindows:function(e,...n){q(),window.__TAURI_INTERNALS__.metadata={currentWindow:{label:e},currentWebview:{windowLabel:e,label:e}}}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(J||(J={}));var Z=Object.freeze({__proto__:null,get BaseDirectory(){return J},appCacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppCache})},appConfigDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppConfig})},appDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppData})},appLocalDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLocalData})},appLogDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLog})},audioDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Audio})},basename:async function(e,n){return d("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Cache})},configDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Config})},dataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Desktop})},dirname:async function(e){return d("plugin:path|dirname",{path:e})},documentDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Document})},downloadDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Download})},executableDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Executable})},extname:async function(e){return d("plugin:path|extname",{path:e})},fontDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Font})},homeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Home})},isAbsolute:async function(e){return d("plugin:path|isAbsolute",{path:e})},join:async function(...e){return d("plugin:path|join",{paths:e})},localDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.LocalData})},normalize:async function(e){return d("plugin:path|normalize",{path:e})},pictureDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Picture})},publicDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Public})},resolve:async function(...e){return d("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return d("plugin:path|resolve_directory",{directory:J.Resource,path:e})},resourceDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Resource})},runtimeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Temp})},templateDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Template})},videoDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Video})}});class K extends h{constructor(e,n){super(e),this.id=n}static async getById(e){return d("plugin:tray|get_by_id",{id:e}).then((n=>n?new K(n,e):null))}static async removeById(e){return d("plugin:tray|remove_by_id",{id:e})}static async new(e){(null==e?void 0:e.menu)&&(e.menu=[e.menu.rid,e.menu.kind]),(null==e?void 0:e.icon)&&(e.icon=y(e.icon));const n=new u;if(null==e?void 0:e.action){const t=e.action;n.onmessage=e=>t(function(e){const n=e;return n.position=new k(e.position),n.rect.position=new k(e.rect.position),n.rect.size=new m(e.rect.size),n}(e)),delete e.action}return d("plugin:tray|new",{options:null!=e?e:{},handler:n}).then((([e,n])=>new K(e,n)))}async setIcon(e){let n=null;return e&&(n=y(e)),d("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),d("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return d("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return d("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return d("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return d("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return d("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return d("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var Y,X,ee=Object.freeze({__proto__:null,TrayIcon:K});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(Y||(Y={}));class ne{constructor(e){this._preventDefault=!1,this.event=e.event,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function te(){return new se(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}async function ie(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new se(e,{skip:!0})))))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(X||(X={}));const re=["tauri://created","tauri://error"];class se{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:window|create",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await ie()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return te()}static async getAll(){return ie()}static async getFocusedWindow(){for(const e of await ie())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Window",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Window",label:this.label}})}async emit(e,n){if(!re.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!re.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!re.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return d("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return d("plugin:window|inner_position",{label:this.label}).then((e=>new k(e)))}async outerPosition(){return d("plugin:window|outer_position",{label:this.label}).then((e=>new k(e)))}async innerSize(){return d("plugin:window|inner_size",{label:this.label}).then((e=>new m(e)))}async outerSize(){return d("plugin:window|outer_size",{label:this.label}).then((e=>new m(e)))}async isFullscreen(){return d("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return d("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return d("plugin:window|is_maximized",{label:this.label})}async isFocused(){return d("plugin:window|is_focused",{label:this.label})}async isDecorated(){return d("plugin:window|is_decorated",{label:this.label})}async isResizable(){return d("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return d("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return d("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return d("plugin:window|is_closable",{label:this.label})}async isVisible(){return d("plugin:window|is_visible",{label:this.label})}async title(){return d("plugin:window|title",{label:this.label})}async theme(){return d("plugin:window|theme",{label:this.label})}async center(){return d("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===Y.Critical?{type:"Critical"}:{type:"Informational"}),d("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return d("plugin:window|set_resizable",{label:this.label,value:e})}async setEnabled(e){return d("plugin:window|set_enabled",{label:this.label,value:e})}async isEnabled(){return d("plugin:window|is_enabled",{label:this.label})}async setMaximizable(e){return d("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return d("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return d("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return d("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return d("plugin:window|maximize",{label:this.label})}async unmaximize(){return d("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return d("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return d("plugin:window|minimize",{label:this.label})}async unminimize(){return d("plugin:window|unminimize",{label:this.label})}async show(){return d("plugin:window|show",{label:this.label})}async hide(){return d("plugin:window|hide",{label:this.label})}async close(){return d("plugin:window|close",{label:this.label})}async destroy(){return d("plugin:window|destroy",{label:this.label})}async setDecorations(e){return d("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return d("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return d("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return d("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return d("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return d("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return d("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){return d("plugin:window|set_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setMinSize(e){return d("plugin:window|set_min_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setMaxSize(e){return d("plugin:window|set_max_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setSizeConstraints(e){function n(e){return e?{Logical:e}:null}return d("plugin:window|set_size_constraints",{label:this.label,value:{minWidth:n(null==e?void 0:e.minWidth),minHeight:n(null==e?void 0:e.minHeight),maxWidth:n(null==e?void 0:e.maxWidth),maxHeight:n(null==e?void 0:e.maxHeight)}})}async setPosition(e){return d("plugin:window|set_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFullscreen(e){return d("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return d("plugin:window|set_focus",{label:this.label})}async setIcon(e){return d("plugin:window|set_icon",{label:this.label,value:y(e)})}async setSkipTaskbar(e){return d("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return d("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return d("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return d("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setCursorPosition(e){return d("plugin:window|set_cursor_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setIgnoreCursorEvents(e){return d("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return d("plugin:window|start_dragging",{label:this.label})}async startResizeDragging(e){return d("plugin:window|start_resize_dragging",{label:this.label,value:e})}async setProgressBar(e){return d("plugin:window|set_progress_bar",{label:this.label,value:e})}async setVisibleOnAllWorkspaces(e){return d("plugin:window|set_visible_on_all_workspaces",{label:this.label,value:e})}async setTitleBarStyle(e){return d("plugin:window|set_title_bar_style",{label:this.label,value:e})}async setTheme(e){return d("plugin:window|set_theme",{label:this.label,value:e})}async onResized(e){return this.listen(E.WINDOW_RESIZED,(n=>{n.payload=new m(n.payload),e(n)}))}async onMoved(e){return this.listen(E.WINDOW_MOVED,(n=>{n.payload=new k(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(E.WINDOW_CLOSE_REQUESTED,(async n=>{const t=new ne(n);await e(t),t.isPreventDefault()||await this.destroy()}))}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}async onFocusChanged(e){const n=await this.listen(E.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(E.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(E.WINDOW_SCALE_FACTOR_CHANGED,e)}async onThemeChanged(e){return this.listen(E.WINDOW_THEME_CHANGED,e)}}var ae,le;function oe(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:new k(e.position),size:new m(e.size)}}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(ae||(ae={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(le||(le={}));var ue=Object.freeze({__proto__:null,CloseRequestedEvent:ne,get Effect(){return ae},get EffectState(){return le},LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,get ProgressBarStatus(){return X},get UserAttentionType(){return Y},Window:se,availableMonitors:async function(){return d("plugin:window|available_monitors").then((e=>e.map(oe)))},currentMonitor:async function(){return d("plugin:window|current_monitor").then(oe)},cursorPosition:async function(){return d("plugin:window|cursor_position").then((e=>new k(e)))},getAllWindows:ie,getCurrentWindow:te,monitorFromPoint:async function(e,n){return d("plugin:window|monitor_from_point",{x:e,y:n}).then(oe)},primaryMonitor:async function(){return d("plugin:window|primary_monitor").then(oe)}});function ce(){return new pe(te(),window.__TAURI_INTERNALS__.metadata.currentWebview.label,{skip:!0})}async function de(){return d("plugin:webview|get_all_webviews").then((e=>e.map((e=>new pe(new se(e.windowLabel,{skip:!0}),e.label,{skip:!0})))))}const he=["tauri://created","tauri://error"];class pe{constructor(e,n,t){this.window=e,this.label=n,this.listeners=Object.create(null),(null==t?void 0:t.skip)||d("plugin:webview|create_webview",{windowLabel:e.label,label:n,options:t}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await de()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return ce()}static async getAll(){return de()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Webview",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Webview",label:this.label}})}async emit(e,n){if(!he.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!he.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!he.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async position(){return d("plugin:webview|webview_position",{label:this.label}).then((e=>new k(e)))}async size(){return d("plugin:webview|webview_size",{label:this.label}).then((e=>new m(e)))}async close(){return d("plugin:webview|close",{label:this.label})}async setSize(e){return d("plugin:webview|set_webview_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setPosition(e){return d("plugin:webview|set_webview_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFocus(){return d("plugin:webview|set_webview_focus",{label:this.label})}async hide(){return d("plugin:webview|webview_hide",{label:this.label})}async show(){return d("plugin:webview|webview_show",{label:this.label})}async setZoom(e){return d("plugin:webview|set_webview_zoom",{label:this.label,value:e})}async reparent(e){return d("plugin:webview|reparent",{label:this.label,window:"string"==typeof e?e:e.label})}async clearAllBrowsingData(){return d("plugin:webview|clear_all_browsing_data")}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}}var we,ye,_e=Object.freeze({__proto__:null,Webview:pe,getAllWebviews:de,getCurrentWebview:ce});function ge(){const e=ce();return new me(e.label,{skip:!0})}async function be(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new me(e,{skip:!0})))))}class me{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:webview|create_webview_window",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;const t=null!==(n=(await be()).find((n=>n.label===e)))&&void 0!==n?n:null;return t?new me(t.label,{skip:!0}):null}static getCurrent(){return ge()}static async getAll(){return be()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"WebviewWindow",label:this.label}})}}we=me,ye=[se,pe],(Array.isArray(ye)?ye:[ye]).forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((n=>{var t;"object"==typeof we.prototype&&we.prototype&&n in we.prototype||Object.defineProperty(we.prototype,n,null!==(t=Object.getOwnPropertyDescriptor(e.prototype,n))&&void 0!==t?t:Object.create(null))}))}));var ve=Object.freeze({__proto__:null,WebviewWindow:me,getAllWebviewWindows:be,getCurrentWebviewWindow:ge});return e.app=g,e.core=p,e.dpi=T,e.event=P,e.image=_,e.menu=$,e.mocks=Q,e.path=Z,e.tray=ee,e.webview=_e,e.webviewWindow=ve,e.window=ue,e}({});window.__TAURI__=__TAURI_IIFE__; +var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i,r,s,a;"function"==typeof SuppressedError&&SuppressedError;const l="__TAURI_TO_IPC_KEY__";function o(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}class u{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),r.set(this,0),s.set(this,{}),this.id=o((({message:e,id:a})=>{if(a===n(this,r,"f")){t(this,r,a+1,"f"),n(this,i,"f").call(this,e);const l=Object.keys(n(this,s,"f"));if(l.length>0){let e=a+1;for(const t of l.sort()){if(parseInt(t)!==e)break;{const r=n(this,s,"f")[t];delete n(this,s,"f")[t],n(this,i,"f").call(this,r),e+=1}}t(this,r,e,"f")}}else n(this,s,"f")[a.toString()]=e}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}[(i=new WeakMap,r=new WeakMap,s=new WeakMap,l)](){return`__CHANNEL__:${this.id}`}toJSON(){return this[l]()}}class c{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return d(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function d(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}class h{get rid(){return n(this,a,"f")}constructor(e){a.set(this,void 0),t(this,a,e,"f")}async close(){return d("plugin:resources|close",{rid:this.rid})}}a=new WeakMap;var p=Object.freeze({__proto__:null,Channel:u,PluginListener:c,Resource:h,SERIALIZE_TO_IPC_FN:l,addPluginListener:async function(e,n,t){const i=new u;return i.onmessage=t,d(`plugin:${e}|registerListener`,{event:n,handler:i}).then((()=>new c(e,n,i.id)))},checkPermissions:async function(e){return d(`plugin:${e}|check_permissions`)},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:d,isTauri:function(){return"isTauri"in window&&!!window.isTauri},requestPermissions:async function(e){return d(`plugin:${e}|request_permissions`)},transformCallback:o});class w extends h{constructor(e){super(e)}static async new(e,n,t){return d("plugin:image|new",{rgba:y(e),width:n,height:t}).then((e=>new w(e)))}static async fromBytes(e){return d("plugin:image|from_bytes",{bytes:y(e)}).then((e=>new w(e)))}static async fromPath(e){return d("plugin:image|from_path",{path:e}).then((e=>new w(e)))}async rgba(){return d("plugin:image|rgba",{rid:this.rid}).then((e=>new Uint8Array(e)))}async size(){return d("plugin:image|size",{rid:this.rid})}}function y(e){return null==e?null:"string"==typeof e?e:e instanceof w?e.rid:e}var _=Object.freeze({__proto__:null,Image:w,transformImage:y});var g=Object.freeze({__proto__:null,defaultWindowIcon:async function(){return d("plugin:app|default_window_icon").then((e=>e?new w(e):null))},getName:async function(){return d("plugin:app|name")},getTauriVersion:async function(){return d("plugin:app|tauri_version")},getVersion:async function(){return d("plugin:app|version")},hide:async function(){return d("plugin:app|app_hide")},setTheme:async function(e){return d("plugin:app|set_app_theme",{theme:e})},show:async function(){return d("plugin:app|app_show")}});class b{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.width=e[0].Logical.width,this.height=e[0].Logical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toPhysical(e){return new m(this.width*e,this.height*e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class m{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.width=e[0].Physical.width,this.height=e[0].Physical.height):(this.width=e[0].width,this.height=e[0].height):(this.width=e[0],this.height=e[1])}toLogical(e){return new b(this.width/e,this.height/e)}[l](){return{width:this.width,height:this.height}}toJSON(){return this[l]()}}class v{constructor(e){this.size=e}toLogical(e){return this.size instanceof b?this.size:this.size.toLogical(e)}toPhysical(e){return this.size instanceof m?this.size:this.size.toPhysical(e)}[l](){return{[`${this.size.type}`]:{width:this.size.width,height:this.size.height}}}toJSON(){return this[l]()}}class f{constructor(...e){this.type="Logical",1===e.length?"Logical"in e[0]?(this.x=e[0].Logical.x,this.y=e[0].Logical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toPhysical(e){return new k(this.x*e,this.x*e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class k{constructor(...e){this.type="Physical",1===e.length?"Physical"in e[0]?(this.x=e[0].Physical.x,this.y=e[0].Physical.y):(this.x=e[0].x,this.y=e[0].y):(this.x=e[0],this.y=e[1])}toLogical(e){return new f(this.x/e,this.x/e)}[l](){return{x:this.x,y:this.y}}toJSON(){return this[l]()}}class A{constructor(e){this.position=e}toLogical(e){return this.position instanceof f?this.position:this.position.toLogical(e)}toPhysical(e){return this.position instanceof k?this.position:this.position.toPhysical(e)}[l](){return{[`${this.position.type}`]:{x:this.position.x,y:this.position.y}}}toJSON(){return this[l]()}}var E,T=Object.freeze({__proto__:null,LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,Position:A,Size:v});async function D(e,n){await d("plugin:event|unlisten",{event:e,eventId:n})}async function I(e,n,t){var i;const r="string"==typeof(null==t?void 0:t.target)?{kind:"AnyLabel",label:t.target}:null!==(i=null==t?void 0:t.target)&&void 0!==i?i:{kind:"Any"};return d("plugin:event|listen",{event:e,target:r,handler:o(n)}).then((n=>async()=>D(e,n)))}async function R(e,n,t){return I(e,(t=>{D(e,t.id),n(t)}),t)}async function S(e,n){await d("plugin:event|emit",{event:e,payload:n})}async function L(e,n,t){const i="string"==typeof e?{kind:"AnyLabel",label:e}:e;await d("plugin:event|emit_to",{target:i,event:n,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"}(E||(E={}));var x,C,N,P=Object.freeze({__proto__:null,get TauriEvent(){return E},emit:S,emitTo:L,listen:I,once:R});function z(e){var n;if("items"in e)e.items=null===(n=e.items)||void 0===n?void 0:n.map((e=>"rid"in e?e:z(e)));else if("action"in e&&e.action){const n=new u;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function W(e,n){const t=new u;if(n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items)){function i(e){var n;return"rid"in e?[e.rid,e.kind]:("item"in e&&"object"==typeof e.item&&(null===(n=e.item.About)||void 0===n?void 0:n.icon)&&(e.item.About.icon=y(e.item.About.icon)),"icon"in e&&e.icon&&(e.icon=y(e.icon)),"items"in e&&e.items&&(e.items=e.items.map(i)),z(e))}n.items=n.items.map(i)}return d("plugin:menu|new",{kind:e,options:n,handler:t})}class O extends h{get id(){return n(this,x,"f")}get kind(){return n(this,C,"f")}constructor(e,n,i){super(e),x.set(this,void 0),C.set(this,void 0),t(this,x,n,"f"),t(this,C,i,"f")}}x=new WeakMap,C=new WeakMap;class F extends O{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return W("MenuItem",e).then((([e,n])=>new F(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class M extends O{constructor(e,n){super(e,n,"Check")}static async new(e){return W("Check",e).then((([e,n])=>new M(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return d("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return d("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(N||(N={}));class U extends O{constructor(e,n){super(e,n,"Icon")}static async new(e){return W("Icon",e).then((([e,n])=>new U(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return d("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return d("plugin:menu|set_icon",{rid:this.rid,icon:y(e)})}}class B extends O{constructor(e,n){super(e,n,"Predefined")}static async new(e){return W("Predefined",e).then((([e,n])=>new B(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}function j([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class V extends O{constructor(e,n){super(e,n,"Submenu")}static async new(e){return W("Submenu",e).then((([e,n])=>new V(e,n)))}async text(){return d("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return d("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return d("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return d("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(j)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(j)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?j(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsWindowsMenuForNSApp(){return d("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return d("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function G([e,n,t]){switch(t){case"Submenu":return new V(e,n);case"Predefined":return new B(e,n);case"Check":return new M(e,n);case"Icon":return new U(e,n);default:return new F(e,n)}}class H extends O{constructor(e,n){super(e,n,"Menu")}static async new(e){return W("Menu",e).then((([e,n])=>new H(e,n)))}static async default(){return d("plugin:menu|create_default").then((([e,n])=>new H(e,n)))}async append(e){return d("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return d("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return d("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return d("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return d("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(G)}async items(){return d("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(G)))}async get(e){return d("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?G(e):null))}async popup(e,n){var t;return d("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:null!==(t=null==n?void 0:n.label)&&void 0!==t?t:null,at:e instanceof A?e:e?new A(e):null})}async setAsAppMenu(){return d("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new H(e[0],e[1]):null))}async setAsWindowMenu(e){var n;return d("plugin:menu|set_as_window_menu",{rid:this.rid,window:null!==(n=null==e?void 0:e.label)&&void 0!==n?n:null}).then((e=>e?new H(e[0],e[1]):null))}}var $=Object.freeze({__proto__:null,CheckMenuItem:M,IconMenuItem:U,Menu:H,MenuItem:F,get NativeIcon(){return N},PredefinedMenuItem:B,Submenu:V});function q(){var e;window.__TAURI_INTERNALS__=null!==(e=window.__TAURI_INTERNALS__)&&void 0!==e?e:{}}var J,Q=Object.freeze({__proto__:null,clearMocks:function(){var e,n,t;"object"==typeof window.__TAURI_INTERNALS__&&((null===(e=window.__TAURI_INTERNALS__)||void 0===e?void 0:e.convertFileSrc)&&delete window.__TAURI_INTERNALS__.convertFileSrc,(null===(n=window.__TAURI_INTERNALS__)||void 0===n?void 0:n.invoke)&&delete window.__TAURI_INTERNALS__.invoke,(null===(t=window.__TAURI_INTERNALS__)||void 0===t?void 0:t.metadata)&&delete window.__TAURI_INTERNALS__.metadata)},mockConvertFileSrc:function(e){q(),window.__TAURI_INTERNALS__.convertFileSrc=function(n,t="asset"){const i=encodeURIComponent(n);return"windows"===e?`http://${t}.localhost/${i}`:`${t}://localhost/${i}`}},mockIPC:function(e){q(),window.__TAURI_INTERNALS__.transformCallback=function(e,n=!1){const t=window.crypto.getRandomValues(new Uint32Array(1))[0],i=`_${t}`;return Object.defineProperty(window,i,{value:t=>(n&&Reflect.deleteProperty(window,i),e&&e(t)),writable:!1,configurable:!0}),t},window.__TAURI_INTERNALS__.invoke=function(n,t,i){return e(n,t)}},mockWindows:function(e,...n){q(),window.__TAURI_INTERNALS__.metadata={currentWindow:{label:e},currentWebview:{windowLabel:e,label:e}}}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(J||(J={}));var Z=Object.freeze({__proto__:null,get BaseDirectory(){return J},appCacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppCache})},appConfigDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppConfig})},appDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppData})},appLocalDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLocalData})},appLogDir:async function(){return d("plugin:path|resolve_directory",{directory:J.AppLog})},audioDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Audio})},basename:async function(e,n){return d("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Cache})},configDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Config})},dataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Desktop})},dirname:async function(e){return d("plugin:path|dirname",{path:e})},documentDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Document})},downloadDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Download})},executableDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Executable})},extname:async function(e){return d("plugin:path|extname",{path:e})},fontDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Font})},homeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Home})},isAbsolute:async function(e){return d("plugin:path|isAbsolute",{path:e})},join:async function(...e){return d("plugin:path|join",{paths:e})},localDataDir:async function(){return d("plugin:path|resolve_directory",{directory:J.LocalData})},normalize:async function(e){return d("plugin:path|normalize",{path:e})},pictureDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Picture})},publicDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Public})},resolve:async function(...e){return d("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return d("plugin:path|resolve_directory",{directory:J.Resource,path:e})},resourceDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Resource})},runtimeDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Temp})},templateDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Template})},videoDir:async function(){return d("plugin:path|resolve_directory",{directory:J.Video})}});class K extends h{constructor(e,n){super(e),this.id=n}static async getById(e){return d("plugin:tray|get_by_id",{id:e}).then((n=>n?new K(n,e):null))}static async removeById(e){return d("plugin:tray|remove_by_id",{id:e})}static async new(e){(null==e?void 0:e.menu)&&(e.menu=[e.menu.rid,e.menu.kind]),(null==e?void 0:e.icon)&&(e.icon=y(e.icon));const n=new u;if(null==e?void 0:e.action){const t=e.action;n.onmessage=e=>t(function(e){const n=e;return n.position=new k(e.position),n.rect.position=new k(e.rect.position),n.rect.size=new m(e.rect.size),n}(e)),delete e.action}return d("plugin:tray|new",{options:null!=e?e:{},handler:n}).then((([e,n])=>new K(e,n)))}async setIcon(e){let n=null;return e&&(n=y(e)),d("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),d("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return d("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return d("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return d("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return d("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return d("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return d("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var Y,X,ee=Object.freeze({__proto__:null,TrayIcon:K});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(Y||(Y={}));class ne{constructor(e){this._preventDefault=!1,this.event=e.event,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function te(){return new se(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}async function ie(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new se(e,{skip:!0})))))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(X||(X={}));const re=["tauri://created","tauri://error"];class se{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:window|create",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await ie()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return te()}static async getAll(){return ie()}static async getFocusedWindow(){for(const e of await ie())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Window",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Window",label:this.label}})}async emit(e,n){if(!re.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!re.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!re.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return d("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return d("plugin:window|inner_position",{label:this.label}).then((e=>new k(e)))}async outerPosition(){return d("plugin:window|outer_position",{label:this.label}).then((e=>new k(e)))}async innerSize(){return d("plugin:window|inner_size",{label:this.label}).then((e=>new m(e)))}async outerSize(){return d("plugin:window|outer_size",{label:this.label}).then((e=>new m(e)))}async isFullscreen(){return d("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return d("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return d("plugin:window|is_maximized",{label:this.label})}async isFocused(){return d("plugin:window|is_focused",{label:this.label})}async isDecorated(){return d("plugin:window|is_decorated",{label:this.label})}async isResizable(){return d("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return d("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return d("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return d("plugin:window|is_closable",{label:this.label})}async isVisible(){return d("plugin:window|is_visible",{label:this.label})}async title(){return d("plugin:window|title",{label:this.label})}async theme(){return d("plugin:window|theme",{label:this.label})}async center(){return d("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===Y.Critical?{type:"Critical"}:{type:"Informational"}),d("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return d("plugin:window|set_resizable",{label:this.label,value:e})}async setEnabled(e){return d("plugin:window|set_enabled",{label:this.label,value:e})}async isEnabled(){return d("plugin:window|is_enabled",{label:this.label})}async setMaximizable(e){return d("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return d("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return d("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return d("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return d("plugin:window|maximize",{label:this.label})}async unmaximize(){return d("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return d("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return d("plugin:window|minimize",{label:this.label})}async unminimize(){return d("plugin:window|unminimize",{label:this.label})}async show(){return d("plugin:window|show",{label:this.label})}async hide(){return d("plugin:window|hide",{label:this.label})}async close(){return d("plugin:window|close",{label:this.label})}async destroy(){return d("plugin:window|destroy",{label:this.label})}async setDecorations(e){return d("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return d("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return d("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return d("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return d("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return d("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return d("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){return d("plugin:window|set_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setMinSize(e){return d("plugin:window|set_min_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setMaxSize(e){return d("plugin:window|set_max_size",{label:this.label,value:e instanceof v?e:e?new v(e):null})}async setSizeConstraints(e){function n(e){return e?{Logical:e}:null}return d("plugin:window|set_size_constraints",{label:this.label,value:{minWidth:n(null==e?void 0:e.minWidth),minHeight:n(null==e?void 0:e.minHeight),maxWidth:n(null==e?void 0:e.maxWidth),maxHeight:n(null==e?void 0:e.maxHeight)}})}async setPosition(e){return d("plugin:window|set_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFullscreen(e){return d("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return d("plugin:window|set_focus",{label:this.label})}async setIcon(e){return d("plugin:window|set_icon",{label:this.label,value:y(e)})}async setSkipTaskbar(e){return d("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return d("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return d("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return d("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setBackgroundColor(e){return d("plugin:window|set_background_color",{color:e})}async setCursorPosition(e){return d("plugin:window|set_cursor_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setIgnoreCursorEvents(e){return d("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return d("plugin:window|start_dragging",{label:this.label})}async startResizeDragging(e){return d("plugin:window|start_resize_dragging",{label:this.label,value:e})}async setProgressBar(e){return d("plugin:window|set_progress_bar",{label:this.label,value:e})}async setVisibleOnAllWorkspaces(e){return d("plugin:window|set_visible_on_all_workspaces",{label:this.label,value:e})}async setTitleBarStyle(e){return d("plugin:window|set_title_bar_style",{label:this.label,value:e})}async setTheme(e){return d("plugin:window|set_theme",{label:this.label,value:e})}async onResized(e){return this.listen(E.WINDOW_RESIZED,(n=>{n.payload=new m(n.payload),e(n)}))}async onMoved(e){return this.listen(E.WINDOW_MOVED,(n=>{n.payload=new k(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(E.WINDOW_CLOSE_REQUESTED,(async n=>{const t=new ne(n);await e(t),t.isPreventDefault()||await this.destroy()}))}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}async onFocusChanged(e){const n=await this.listen(E.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(E.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(E.WINDOW_SCALE_FACTOR_CHANGED,e)}async onThemeChanged(e){return this.listen(E.WINDOW_THEME_CHANGED,e)}}var ae,le;function oe(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:new k(e.position),size:new m(e.size)}}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(ae||(ae={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(le||(le={}));var ue=Object.freeze({__proto__:null,CloseRequestedEvent:ne,get Effect(){return ae},get EffectState(){return le},LogicalPosition:f,LogicalSize:b,PhysicalPosition:k,PhysicalSize:m,get ProgressBarStatus(){return X},get UserAttentionType(){return Y},Window:se,availableMonitors:async function(){return d("plugin:window|available_monitors").then((e=>e.map(oe)))},currentMonitor:async function(){return d("plugin:window|current_monitor").then(oe)},cursorPosition:async function(){return d("plugin:window|cursor_position").then((e=>new k(e)))},getAllWindows:ie,getCurrentWindow:te,monitorFromPoint:async function(e,n){return d("plugin:window|monitor_from_point",{x:e,y:n}).then(oe)},primaryMonitor:async function(){return d("plugin:window|primary_monitor").then(oe)}});function ce(){return new pe(te(),window.__TAURI_INTERNALS__.metadata.currentWebview.label,{skip:!0})}async function de(){return d("plugin:webview|get_all_webviews").then((e=>e.map((e=>new pe(new se(e.windowLabel,{skip:!0}),e.label,{skip:!0})))))}const he=["tauri://created","tauri://error"];class pe{constructor(e,n,t){this.window=e,this.label=n,this.listeners=Object.create(null),(null==t?void 0:t.skip)||d("plugin:webview|create_webview",{windowLabel:e.label,label:n,options:t}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;return null!==(n=(await de()).find((n=>n.label===e)))&&void 0!==n?n:null}static getCurrent(){return ce()}static async getAll(){return de()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"Webview",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"Webview",label:this.label}})}async emit(e,n){if(!he.includes(e))return S(e,n);for(const t of this.listeners[e]||[])t({event:e,id:-1,payload:n})}async emitTo(e,n,t){if(!he.includes(n))return L(e,n,t);for(const e of this.listeners[n]||[])e({event:n,id:-1,payload:t})}_handleTauriEvent(e,n){return!!he.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async position(){return d("plugin:webview|webview_position",{label:this.label}).then((e=>new k(e)))}async size(){return d("plugin:webview|webview_size",{label:this.label}).then((e=>new m(e)))}async close(){return d("plugin:webview|close",{label:this.label})}async setSize(e){return d("plugin:webview|set_webview_size",{label:this.label,value:e instanceof v?e:new v(e)})}async setPosition(e){return d("plugin:webview|set_webview_position",{label:this.label,value:e instanceof A?e:new A(e)})}async setFocus(){return d("plugin:webview|set_webview_focus",{label:this.label})}async hide(){return d("plugin:webview|webview_hide",{label:this.label})}async show(){return d("plugin:webview|webview_show",{label:this.label})}async setZoom(e){return d("plugin:webview|set_webview_zoom",{label:this.label,value:e})}async reparent(e){return d("plugin:webview|reparent",{label:this.label,window:"string"==typeof e?e:e.label})}async clearAllBrowsingData(){return d("plugin:webview|clear_all_browsing_data")}async setBackgroundColor(e){return d("plugin:webview|set_webview_background_color",{color:e})}async onDragDropEvent(e){const n=await this.listen(E.DRAG_ENTER,(n=>{e({...n,payload:{type:"enter",paths:n.payload.paths,position:new k(n.payload.position)}})})),t=await this.listen(E.DRAG_OVER,(n=>{e({...n,payload:{type:"over",position:new k(n.payload.position)}})})),i=await this.listen(E.DRAG_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:new k(n.payload.position)}})})),r=await this.listen(E.DRAG_LEAVE,(n=>{e({...n,payload:{type:"leave"}})}));return()=>{n(),i(),t(),r()}}}var we,ye,_e=Object.freeze({__proto__:null,Webview:pe,getAllWebviews:de,getCurrentWebview:ce});function ge(){const e=ce();return new me(e.label,{skip:!0})}async function be(){return d("plugin:window|get_all_windows").then((e=>e.map((e=>new me(e,{skip:!0})))))}class me{constructor(e,n={}){var t;this.label=e,this.listeners=Object.create(null),(null==n?void 0:n.skip)||d("plugin:webview|create_webview_window",{options:{...n,parent:"string"==typeof n.parent?n.parent:null===(t=n.parent)||void 0===t?void 0:t.label,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static async getByLabel(e){var n;const t=null!==(n=(await be()).find((n=>n.label===e)))&&void 0!==n?n:null;return t?new me(t.label,{skip:!0}):null}static getCurrent(){return ge()}static async getAll(){return be()}async listen(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:I(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async once(e,n){return this._handleTauriEvent(e,n)?()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)}:R(e,n,{target:{kind:"WebviewWindow",label:this.label}})}async setBackgroundColor(e){return d("plugin:window|set_background_color",{color:e}).then((()=>d("plugin:webview|set_webview_background_color",{color:e})))}}we=me,ye=[se,pe],(Array.isArray(ye)?ye:[ye]).forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((n=>{var t;"object"==typeof we.prototype&&we.prototype&&n in we.prototype||Object.defineProperty(we.prototype,n,null!==(t=Object.getOwnPropertyDescriptor(e.prototype,n))&&void 0!==t?t:Object.create(null))}))}));var ve=Object.freeze({__proto__:null,WebviewWindow:me,getAllWebviewWindows:be,getCurrentWebviewWindow:ge});return e.app=g,e.core=p,e.dpi=T,e.event=P,e.image=_,e.menu=$,e.mocks=Q,e.path=Z,e.tray=ee,e.webview=_e,e.webviewWindow=ve,e.window=ue,e}({});window.__TAURI__=__TAURI_IIFE__; diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs index 92fcb9be64c4..a1488ae38d5b 100644 --- a/crates/tauri/src/test/mock_runtime.rs +++ b/crates/tauri/src/test/mock_runtime.rs @@ -486,6 +486,10 @@ impl WindowBuilder for MockWindowBuilder { fn get_theme(&self) -> Option { None } + + fn background_color(self, _color: tauri_utils::config::Color) -> Self { + self + } } impl WebviewDispatch for MockWebviewDispatcher { @@ -597,6 +601,10 @@ impl WebviewDispatch for MockWebviewDispatcher { fn show(&self) -> Result<()> { Ok(()) } + + fn set_background_color(&self, color: Option) -> Result<()> { + Ok(()) + } } impl WindowDispatch for MockWindowDispatcher { @@ -991,6 +999,10 @@ impl WindowDispatch for MockWindowDispatcher { fn is_enabled(&self) -> Result { Ok(true) } + + fn set_background_color(&self, color: Option) -> Result<()> { + Ok(()) + } } #[derive(Debug, Clone)] diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs index bf3f1f3be4b5..987186939140 100644 --- a/crates/tauri/src/webview/mod.rs +++ b/crates/tauri/src/webview/mod.rs @@ -22,6 +22,7 @@ use tauri_runtime::{ webview::{DetachedWebview, PendingWebview, WebviewAttributes}, WebviewDispatch, }; +pub use tauri_utils::config::Color; use tauri_utils::config::{WebviewUrl, WindowConfig}; pub use url::Url; @@ -830,6 +831,19 @@ fn main() { self.webview_attributes.devtools.replace(enabled); self } + + /// Set the webview background color. + /// + /// ## Platform-specific: + /// + /// - **macOS / iOS**: Not implemented. + /// - **Windows**: On Windows 7, alpha channel is ignored. + /// - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + #[must_use] + pub fn background_color(mut self, color: Color) -> Self { + self.webview_attributes.background_color = Some(color); + self + } } /// Webview. @@ -1619,6 +1633,22 @@ tauri::Builder::default() .map_err(Into::into) } + /// Specify the webview background color. + /// + /// ## Platfrom-specific: + /// + /// - **macOS / iOS**: Not implemented. + /// - **Windows**: + /// - On Windows 7, transparency is not supported and the alpha value will be ignored. + /// - On Windows higher than 7: translucent colors are not supported so any alpha value other than `0` will be replaced by `255` + pub fn set_background_color(&self, color: Option) -> crate::Result<()> { + self + .webview + .dispatcher + .set_background_color(color) + .map_err(Into::into) + } + /// Clear all browsing data for this webview. pub fn clear_all_browsing_data(&self) -> crate::Result<()> { self diff --git a/crates/tauri/src/webview/plugin.rs b/crates/tauri/src/webview/plugin.rs index 0856e254e65f..aa92050e361f 100644 --- a/crates/tauri/src/webview/plugin.rs +++ b/crates/tauri/src/webview/plugin.rs @@ -18,8 +18,8 @@ mod desktop_commands { use super::*; use crate::{ - command, sealed::ManagerBase, utils::config::WindowEffectsConfig, AppHandle, Webview, - WebviewWindowBuilder, + command, sealed::ManagerBase, utils::config::WindowEffectsConfig, webview::Color, AppHandle, + Webview, WebviewWindowBuilder, }; fn default_true() -> bool { @@ -199,6 +199,11 @@ mod desktop_commands { setter!(webview_hide, hide); setter!(webview_show, show); setter!(set_webview_zoom, set_zoom, f64); + setter!( + set_webview_background_color, + set_background_color, + Option + ); setter!(clear_all_browsing_data, clear_all_browsing_data); #[command(root = "crate")] @@ -282,6 +287,7 @@ pub fn init() -> TauriPlugin { desktop_commands::set_webview_size, desktop_commands::set_webview_position, desktop_commands::set_webview_focus, + desktop_commands::set_webview_background_color, desktop_commands::set_webview_zoom, desktop_commands::webview_hide, desktop_commands::webview_show, diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs index 32799a665d8b..a81599ed18dd 100644 --- a/crates/tauri/src/webview/webview_window.rs +++ b/crates/tauri/src/webview/webview_window.rs @@ -29,7 +29,7 @@ use crate::{ }; use serde::Serialize; use tauri_utils::{ - config::{WebviewUrl, WindowConfig}, + config::{Color, WebviewUrl, WindowConfig}, Theme, }; use url::Url; @@ -935,6 +935,23 @@ impl<'a, R: Runtime, M: Manager> WebviewWindowBuilder<'a, R, M> { self.webview_builder = self.webview_builder.devtools(enabled); self } + + /// Set the window and webview background color. + /// + /// ## Platform-specific: + /// + /// - **Android / iOS:** Unsupported for the window layer. + /// - **macOS / iOS**: Not implemented for the webview layer. + /// - **Windows**: + /// - alpha channel is ignored for the window layer. + /// - On Windows 7, alpha channel is ignored for the webview layer. + /// - On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + #[must_use] + pub fn background_color(mut self, color: Color) -> Self { + self.window_builder = self.window_builder.background_color(color); + self.webview_builder = self.webview_builder.background_color(color); + self + } } /// A type that wraps a [`Window`] together with a [`Webview`]. @@ -1617,6 +1634,21 @@ impl WebviewWindow { self.window.set_icon(icon) } + /// Sets the window background color. + /// + /// ## Platform-specific: + /// + /// - **iOS / Android:** Unsupported. + /// - **macOS**: Not implemented for the webview layer.. + /// - **Windows**: + /// - alpha channel is ignored for the window layer. + /// - On Windows 7, transparency is not supported and the alpha value will be ignored for the webview layer.. + /// - On Windows 8 and newer: translucent colors are not supported so any alpha value other than `0` will be replaced by `255` for the webview layer. + pub fn set_background_color(&self, color: Option) -> crate::Result<()> { + self.window.set_background_color(color)?; + self.webview.set_background_color(color) + } + /// Whether to hide the window icon from the taskbar or not. /// /// ## Platform-specific diff --git a/crates/tauri/src/window/mod.rs b/crates/tauri/src/window/mod.rs index 7f0ffe3cf728..93310fcc9d78 100644 --- a/crates/tauri/src/window/mod.rs +++ b/crates/tauri/src/window/mod.rs @@ -846,6 +846,18 @@ impl<'a, R: Runtime, M: Manager> WindowBuilder<'a, R, M> { } } +impl<'a, R: Runtime, M: Manager> WindowBuilder<'a, R, M> { + /// Set the window and webview background color. + /// + /// ## Platform-specific: + /// + /// - **Windows**: alpha channel is ignored. + #[must_use] + pub fn background_color(mut self, color: Color) -> Self { + self.window_builder = self.window_builder.background_color(color); + self + } +} /// A wrapper struct to hold the window menu state /// and whether it is global per-app or specific to this window. #[cfg(desktop)] @@ -1817,6 +1829,20 @@ tauri::Builder::default() .map_err(Into::into) } + /// Sets the window background color. + /// + /// ## Platform-specific: + /// + /// - **Windows:** alpha channel is ignored. + /// - **iOS / Android:** Unsupported. + pub fn set_background_color(&self, color: Option) -> crate::Result<()> { + self + .window + .dispatcher + .set_background_color(color) + .map_err(Into::into) + } + /// Prevents the window contents from being captured by other apps. pub fn set_content_protected(&self, protected: bool) -> crate::Result<()> { self diff --git a/crates/tauri/src/window/plugin.rs b/crates/tauri/src/window/plugin.rs index a25229e6dd69..edb44b20fc97 100644 --- a/crates/tauri/src/window/plugin.rs +++ b/crates/tauri/src/window/plugin.rs @@ -19,6 +19,7 @@ mod desktop_commands { command, sealed::ManagerBase, utils::config::{WindowConfig, WindowEffectsConfig}, + window::Color, window::{ProgressBarState, WindowBuilder}, AppHandle, CursorIcon, Manager, Monitor, PhysicalPosition, PhysicalSize, Position, Size, Theme, UserAttentionType, Webview, Window, @@ -130,6 +131,7 @@ mod desktop_commands { setter!(set_skip_taskbar, bool); setter!(set_cursor_grab, bool); setter!(set_cursor_visible, bool); + setter!(set_background_color, Option); setter!(set_cursor_icon, CursorIcon); setter!(set_cursor_position, Position); setter!(set_ignore_cursor_events, bool); @@ -291,6 +293,7 @@ pub fn init() -> TauriPlugin { desktop_commands::set_progress_bar, desktop_commands::set_icon, desktop_commands::set_visible_on_all_workspaces, + desktop_commands::set_background_color, desktop_commands::set_title_bar_style, desktop_commands::set_theme, desktop_commands::toggle_maximize, diff --git a/examples/api/src-tauri/src/lib.rs b/examples/api/src-tauri/src/lib.rs index 7f7007eef558..512f43c0aac0 100644 --- a/examples/api/src-tauri/src/lib.rs +++ b/examples/api/src-tauri/src/lib.rs @@ -66,8 +66,7 @@ pub fn run_app) + Send + 'static>( .build()?, )); - let mut window_builder = - WebviewWindowBuilder::new(app, "main", WebviewUrl::default()).use_https_scheme(true); + let mut window_builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default()); #[cfg(all(desktop, not(test)))] { diff --git a/packages/api/src/webview.ts b/packages/api/src/webview.ts index 42a2643d0d05..393fb0c4831e 100644 --- a/packages/api/src/webview.ts +++ b/packages/api/src/webview.ts @@ -30,7 +30,7 @@ import { once } from './event' import { invoke } from './core' -import { Window, getCurrentWindow } from './window' +import { Color, Window, getCurrentWindow } from './window' import { WebviewWindow } from './webviewWindow' /** The drag and drop event types. */ @@ -537,6 +537,24 @@ class Webview { return invoke('plugin:webview|clear_all_browsing_data') } + /** + * Specify the webview background color. + * + * #### Platfrom-specific: + * + * - **macOS / iOS**: Not implemented. + * - **Windows**: + * - On Windows 7, transparency is not supported and the alpha value will be ignored. + * - On Windows higher than 7: translucent colors are not supported so any alpha value other than `0` will be replaced by `255` + * + * @returns A promise indicating the success or failure of the operation. + * + * @since 2.1.0 + */ + async setBackgroundColor(color: Color | null): Promise { + return invoke('plugin:webview|set_webview_background_color', { color }) + } + // Listeners /** @@ -733,8 +751,21 @@ interface WebviewOptions { * @since 2.1.0 */ devtools?: boolean + /** + * Set the window and webview background color. + * + * #### Platform-specific: + * + * - **macOS / iOS**: Not implemented. + * - **Windows**: + * - On Windows 7, alpha channel is ignored. + * - On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + * + * @since 2.1.0 + */ + backgroundColor?: Color } export { Webview, getCurrentWebview, getAllWebviews } -export type { DragDropEvent, WebviewOptions } +export type { DragDropEvent, WebviewOptions, Color } diff --git a/packages/api/src/webviewWindow.ts b/packages/api/src/webviewWindow.ts index a103dd19ee6f..d2bfab8c28fc 100644 --- a/packages/api/src/webviewWindow.ts +++ b/packages/api/src/webviewWindow.ts @@ -13,7 +13,7 @@ import { Window } from './window' import { listen, once } from './event' import type { EventName, EventCallback, UnlistenFn } from './event' import { invoke } from './core' -import type { DragDropEvent } from './webview' +import type { Color, DragDropEvent } from './webview' /** * Get an instance of `Webview` for the current webview window. @@ -202,6 +202,28 @@ class WebviewWindow { target: { kind: 'WebviewWindow', label: this.label } }) } + + /** + * Set the window and webview background color. + * + * #### Platform-specific: + * + * - **Android / iOS:** Unsupported for the window layer. + * - **macOS / iOS**: Not implemented for the webview layer. + * - **Windows**: + * - alpha channel is ignored for the window layer. + * - On Windows 7, alpha channel is ignored for the webview layer. + * - On Windows 8 and newer, if alpha channel is not `0`, it will be ignored. + * + * @returns A promise indicating the success or failure of the operation. + * + * @since 2.1.0 + */ + async setBackgroundColor(color: Color): Promise { + return invoke('plugin:window|set_background_color', { color }).then(() => { + return invoke('plugin:webview|set_webview_background_color', { color }) + }) + } } // Order matters, we use window APIs by default @@ -235,4 +257,4 @@ function applyMixins( } export { WebviewWindow, getCurrentWebviewWindow, getAllWebviewWindows } -export type { DragDropEvent } +export type { DragDropEvent, Color } diff --git a/packages/api/src/window.ts b/packages/api/src/window.ts index 037f06e6523d..1d2ddc4b7182 100644 --- a/packages/api/src/window.ts +++ b/packages/api/src/window.ts @@ -1517,6 +1517,22 @@ class Window { }) } + /** + * Sets the window background color. + * + * #### Platform-specific: + * + * - **Windows:** alpha channel is ignored. + * - **iOS / Android:** Unsupported. + * + * @returns A promise indicating the success or failure of the operation. + * + * @since 2.1.0 + */ + async setBackgroundColor(color: Color): Promise { + return invoke('plugin:window|set_background_color', { color }) + } + /** * Changes the position of the cursor in window coordinates. * @example @@ -1920,11 +1936,17 @@ class Window { } /** - * an array RGBA colors. Each value has minimum of 0 and maximum of 255. + * An RGBA color. Each value has minimum of 0 and maximum of 255. + * + * It can be either a string `#ffffff`, an array of 3 or 4 elements or an object. * * @since 2.0.0 */ -type Color = [number, number, number, number] +type Color = + | [number, number, number] + | [number, number, number, number] + | { red: number; green: number; blue: number; alpha: number } + | string /** * Platform-specific window effects @@ -2232,6 +2254,17 @@ interface WindowOptions { * - **Linux**: Unsupported */ windowEffects?: Effects + /** + * Set the window background color. + * + * #### Platform-specific: + * + * - **Android / iOS:** Unsupported. + * - **Windows**: alpha channel is ignored. + * + * @since 2.1.0 + */ + backgroundColor?: Color } function mapMonitor(m: Monitor | null): Monitor | null {