feat: background color APIs (#11486)

* feat: background color APIs

closes #10519
closes #1564

* clippy

* git branch

* bundle

* fix hex color schema pattern

* add missing `^`

* fix iOS

* revert test

* revert apple-codesign bump

* fmt

* add change files

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
Amr Bashir 2024-11-06 18:21:47 +02:00 committed by GitHub
parent fabc2f283e
commit 4d545ab3ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 978 additions and 202 deletions

View File

@ -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.

View File

@ -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`.

440
Cargo.lock generated
View File

@ -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",
@ -5773,18 +5814,27 @@ dependencies = [
"objc2-foundation",
]
[[package]]
name = "object"
version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [
"crc32fast",
"flate2",
"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 = [
"crc32fast",
"flate2",
"hashbrown 0.15.0",
"indexmap 2.6.0",
"memchr",
"ruzstd",
]
[[package]]
@ -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]]
@ -9885,6 +10021,28 @@ dependencies = [
"core_maths",
]
[[package]]
name = "tungstenite"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http 1.1.0",
"httparse",
"log",
"rand 0.8.5",
"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"
@ -9898,9 +10056,6 @@ dependencies = [
"httparse",
"log",
"rand 0.8.5",
"rustls 0.23.13",
"rustls-native-certs 0.7.3",
"rustls-pki-types",
"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"

View File

@ -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: <https://v2.tauri.app/reference/config/#securityconfig>",

View File

@ -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"

View File

@ -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"

View File

@ -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<Theme>),
SetBackgroundColor(Option<Color>),
DragWindow,
ResizeDragWindow(tauri_runtime::ResizeDirection),
RequestRedraw,
@ -1296,6 +1308,7 @@ pub enum WebviewMessage {
Reparent(WindowId, Sender<Result<()>>),
SetAutoResize(bool),
SetZoom(f64),
SetBackgroundColor(Option<Color>),
ClearAllBrowsingData,
// Getters
Url(Sender<Result<String>>),
@ -1612,6 +1625,17 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
),
)
}
fn set_background_color(&self, color: Option<Color>) -> 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<T: UserEvent> WindowDispatch<T> for WryWindowDispatcher<T> {
Message::Window(self.window_id, WindowMessage::SetTheme(theme)),
)
}
fn set_background_color(&self, color: Option<Color>) -> 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<WebviewWrapper>,
window_event_listeners: WindowEventListeners,
#[cfg(windows)]
background_color: Option<tao::window::RGBA>,
#[cfg(windows)]
is_window_transparent: bool,
#[cfg(windows)]
surface: Option<softbuffer::Surface<Arc<Window>, Arc<Window>>>,
@ -3097,6 +3130,9 @@ fn handle_user_message<T: UserEvent>(
_ => None,
});
}
WindowMessage::SetBackgroundColor(color) => {
window.set_background_color(color.map(Into::into))
}
}
}
}
@ -3292,6 +3328,13 @@ fn handle_user_message<T: UserEvent>(
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<T: UserEvent>(
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<T: UserEvent>(
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<T: UserEvent>(
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<T: UserEvent>(
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<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
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<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
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<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
webviews,
window_event_listeners,
#[cfg(windows)]
background_color,
#[cfg(windows)]
is_window_transparent,
#[cfg(windows)]
surface,
@ -4079,6 +4131,10 @@ fn create_webview<T: UserEvent>(
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();

View File

@ -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<tao::window::Window>,
std::sync::Arc<tao::window::Window>,
>,
background_color: Option<tao::window::RGBA>,
);
}

View File

@ -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<tao::window::Window>,
std::sync::Arc<tao::window::Window>,
>,
background_color: Option<tao::window::RGBA>,
) {
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();
}
}

View File

@ -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<T: UserEvent>: 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<Color>) -> Result<()>;
/// Clear all browsing data for this webview.
fn clear_all_browsing_data(&self) -> Result<()>;
}
@ -753,6 +757,9 @@ pub trait WindowDispatch<T: UserEvent>: 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<Color>) -> Result<()>;
/// Prevents the window contents from being captured by other apps.
fn set_content_protected(&self, protected: bool) -> Result<()>;

View File

@ -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<bool>,
pub background_color: Option<Color>,
}
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.

View File

@ -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

View File

@ -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: <https://v2.tauri.app/reference/config/#securityconfig>",

View File

@ -106,7 +106,7 @@ async fn try_next_schema() -> anyhow::Result<String> {
async fn schema_file_for_version(version: Version) -> anyhow::Result<String> {
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);

View File

@ -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<Color> for (u8, u8, u8, u8) {
}
}
impl From<Color> 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<Color> for [u8; 4] {
fn from(value: Color) -> Self {
[value.0, value.1, value.2, value.3]
}
}
impl From<Color> 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<Self, Self::Err> {
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<D>(deserializer: D) -> Result<Self, D::Error>
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<Url>,
/// 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://<scheme>.localhost` instead of the default `http://<scheme>.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<bool>,
/// 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<Color>,
}
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());
}
}

File diff suppressed because one or more lines are too long

View File

@ -486,6 +486,10 @@ impl WindowBuilder for MockWindowBuilder {
fn get_theme(&self) -> Option<Theme> {
None
}
fn background_color(self, _color: tauri_utils::config::Color) -> Self {
self
}
}
impl<T: UserEvent> WebviewDispatch<T> for MockWebviewDispatcher {
@ -597,6 +601,10 @@ impl<T: UserEvent> WebviewDispatch<T> for MockWebviewDispatcher {
fn show(&self) -> Result<()> {
Ok(())
}
fn set_background_color(&self, color: Option<tauri_utils::config::Color>) -> Result<()> {
Ok(())
}
}
impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {
@ -991,6 +999,10 @@ impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {
fn is_enabled(&self) -> Result<bool> {
Ok(true)
}
fn set_background_color(&self, color: Option<tauri_utils::config::Color>) -> Result<()> {
Ok(())
}
}
#[derive(Debug, Clone)]

View File

@ -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<Color>) -> 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

View File

@ -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<Color>
);
setter!(clear_all_browsing_data, clear_all_browsing_data);
#[command(root = "crate")]
@ -282,6 +287,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
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,

View File

@ -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<R>> 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<R: Runtime> WebviewWindow<R> {
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<Color>) -> 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

View File

@ -846,6 +846,18 @@ impl<'a, R: Runtime, M: Manager<R>> WindowBuilder<'a, R, M> {
}
}
impl<'a, R: Runtime, M: Manager<R>> 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<Color>) -> 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

View File

@ -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<Color>);
setter!(set_cursor_icon, CursorIcon);
setter!(set_cursor_position, Position);
setter!(set_ignore_cursor_events, bool);
@ -291,6 +293,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
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,

View File

@ -66,8 +66,7 @@ pub fn run_app<R: Runtime, F: FnOnce(&App<R>) + 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)))]
{

View File

@ -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<void> {
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 }

View File

@ -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<void> {
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 }

View File

@ -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<void> {
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 {