Repository: tauri-apps/tauri (language: rust)

Issue:
Allow changing the webview background color 
**Describe the bug**
Window flashes a white background before rendering app content on macOS Big Sur.

The css for the `index.html` is:

```css
html, body {
  width: 100%; height: 100%;
  background: rgb(231, 232, 232);
}

@media (prefers-color-scheme: dark) {
  html, body {
    background: rgb(37, 38, 40);
  }
}
```

**To Reproduce**
Steps to reproduce the behavior:
1. Create an index.html with `<style>html, body { background: black; }</style>`
2. Run the app (dev, or dist bundle)
3. Screen will flash a white background before rendering the content.

**Expected behavior**
The main window should wait for the content to load, or it should apply the page's background color on open.

**Screenshots**

https://user-images.githubusercontent.com/1578018/115579993-b0ccbf80-a294-11eb-8c68-07898105ab25.mp4

**Platform and Versions (please complete the following information):**
<!-- You can use the `tauri info` command to get this information -->
OS: Mac OS, version 11.2.3 X64
Node: 15.13.0
NPM: 7.7.6
Yarn: 1.22.10
Rustc: 1.51.0

**Additional context**
This is running the app with the default values (no transparent window mode). When using transparent window mode, it doesn't flash, but the window loses all shadows and borders until it is resized.

https://user-images.githubusercontent.com/1578018/115580068-bfb37200-a294-11eb-832d-9639839ae126.mp4



Discussion / hints:
also experiencing this on linux:

https://user-images.githubusercontent.com/16073360/115911342-94b35480-a433-11eb-90b9-23e64960c7a3.mp4


I suspected this is the browser's default background color, so I made a small edit to `wry` to set the background manually to red (linux only) to see this a bit easier.  The initial color (dark/light) is the OS window's default color, then the webview is loaded with whatever background color is set (red here), and then the application loads.

https://user-images.githubusercontent.com/3301043/115920054-844cab00-a42e-11eb-99e6-1ff5ddbd674f.mp4

This is a change needed in wry to support setting the webview background color.  I've opened up a ticket at https://github.com/tauri-apps/wry/issues/197.

If/when that is implemented, then we can look at expanding the `tauri::Attributes` trait to include setting the background color, and maybe add a hex string `backgroundColor` field to the window config inside `tauri.config.json`.


Since I also ran into this issue today, I am sharing my hacky workaround in case someone is also bothered by the white flashing. The idea is to start the window as hidden and then show it after the html is hopefully rendered.

It works somehow like this:

```
.setup(|app| {

      let main_window = app.get_window("main").unwrap();
      // we perform the initialization code on a new task so the app doesn't freeze
      tauri::async_runtime::spawn(async move {
        // adapt sleeping time to be long enough
        sleep(Duration::from_millis(500));
        main_window.show().unwrap();
      });

      Ok(())
    })
```
and win the tauri.conf.json
```
"windows": [
  {
    ...
    "visible": false
  }
]
I faced the same issue building Museeks with Electron. I am not sure there is much Tauri can do about it.

How I actually solved it is by hiding the window by default, and showing it only after my frontend app has loaded (via an event) (instead of using an arbitrary `sleep` that may need different values on different systems)
@martpie: would you mind sharing your code?
Of course:

Tauri conf:

```diff
"windows": [
  {
    "title": "Your app",
+   "visible": false,
    "fullscreen": false,
    "resizable": true
  }
 ]
```

Rust side:

```rs
#[tauri::command]
pub async fn show_main_window(window: tauri::Window) {
    window.get_window("main").unwrap().show().unwrap(); // replace "main" by the name of your window
}
```

From your front-end, once you know your app is instantialized (for example with SolidJS):

```ts
import { invoke } from '@tauri-apps/api';

// Solid JS speicifc, `componentDidMount` for React, etc...
onMounted(() => {
  invoke('show_main_window');
})
```

you just have to find the equivalent of Vue, React etc if you use any other
> Of course:
> 
> 
> 
> Tauri conf:
> 
> 
> 
> ```diff
> 
> "windows": [
> 
>   {
> 
>     "title": "Your app",
> 
> +   "visible": false,
> 
>     "fullscreen": false,
> 
>     "resizable": true
> 
>   }
> 
>  ]
> 
> ```
> 
> 
> 
> Rust side:
> 
> 
> 
> ```rs
> 
> #[tauri::command]
> 
> pub async fn show_main_window(window: tauri::Window) {
> 
>     window.get_window("main").unwrap().show().unwrap(); // replace "main" by the name of your window
> 
> }
> 
> ```
> 
> 
> 
> From your front-end, once you know your app is instantialized (for example with SolidJS):
> 
> 
> 
> ```ts
> 
> import { invoke } from '@tauri-apps/api';
> 
> 
> 
> onMounted(() => {
> 
>   invoke('show_main_window');
> 
> })
> 
> ```
> 
> 
> 
> you just have to find the equivalent of Vue, React etc if you use any other

This is in fact the recommendations solution to this problem. And optimizing your Frontend rendering (through ssg or similar) so the delay to first-content is very small. Something like the app-shell architecture helps here as well.
MacOS solution:

We can remove the webView background:

```rust
main_window.with_webview(|webview|  unsafe {
   let id = webview.inner();
   let no: cocoa::base::id = msg_send![class!(NSNumber), numberWithBool:0];
   let _: cocoa::base::id =
   msg_send![id, setValue:no forKey: NSString::alloc(nil).init_str("drawsBackground")];
});
```

ref: https://github.com/tauri-apps/wry/blob/765fe5ae413a1c13ad99802b49f3af859a2445d5/src/webview/macos/mod.rs#L180

then set the window background to the color you want:

```rust
let id = main_window.ns_window().unwrap() as cocoa::base::id;
let color = NSColor::colorWithSRGBRed_green_blue_alpha_(nil, 0.0, 0.0, 0.0, 1.0);
let _: cocoa::base::id = msg_send![id, setBackgroundColor: color];
```
Unfortunately, this doesn't seem to work for dynamically created windows. At least with in Sveltekit.  If you create a window using WebveiwWindow and set display: false in the options, then the onMount function never gets called for the widget with the supplied route.
Has anyone solved this?
Hey 👋 What if we extend the tauri config to support setting a background color from one single place to both the shell's background color and the webview's background color? So whenever the initial load happens, there would be no "flash granade" thrown into your face.

Then, if needed, it can be overriden by the webview's CSS styles.

So it would be:

1. Tauri's Config -> `appBackgroundColor` 
- Sets the background color for the app shell
- Sets the background color for the webview's browser default background color
2. Application specific css overrides 
- This would override the webview's browser defaults with whatever color you've picked
Just wanted to check in on what the status of this is in 2024. I am still experiencing the issue outlined by the author on Windows 11. The maintainers of wry have added [`set_background_color`](https://docs.rs/wry/latest/wry/struct.WebView.html#method.set_background_color) to `wry::Webview` in [version 0.21.0](https://github.com/tauri-apps/wry/releases/tag/wry-v0.21.0). I just checked my `Cargo.lock` file and the latest version of Tauri seems to be using `wry 0.24.7`.

Unfortunately, from my research, there seems to be no way for us to accesss this wry API in our Rust code. Is there any plan on exposing this functionality for Tauri users? Alternatively, has anyone found a solution to this issue?
It's an interesting problem, that is hard to solve. Even some major products still have the white flash on startup problem, like Google Chrome for example.

If we just define a color through a static config file, then it would still flash in the wrong color for users that prefer a different theme. This is less than ideal, but I guess that in general it's at least less annoying with black than white.

A somewhat better solution would be if Tauri could detect light/dark system theme, and set a configurable light/dark background color when creating the initial window. But if an app supports multiple themes, besides just light and dark, then it would still flash in the wrong color for users that prefer a different theme.

There is always going to be a delay between the initial window being created, and frontend code rendering colors. As long as the app is applying any customizable colors through frontend code, there will be a flash of a different color. So ideally there would be some more sophisticated solution here.

One option would be to add some kind of argument or hook to the window creation where a color can be provided as input. So that the app has a chance to read user and system settings and make a decision based on some custom logic, and pass that into the window creation.

It would be really cool if there was a whole theme system in Tauri, where we could define custom themes in config, and it would be integrated, so it applies automatically to window background and decorations, and is made available to the app code as variables in Rust, JS, and CSS.

---

For Tauri v2, I am using the following workaround. However, I belive this only works for desktop, and there is no equivalent thing for mobile, so the white flash still remains an issue there.

#### Tauri `tauri.conf.json`

```
{
	"app": {
		"windows": [
			{
				"title": "MyTitle",
				"visible": false
			}
		],
	},
```

#### SvelteKit `+layout.svelte`

```svelte
<script>
	import { onMount } from "svelte";

	import { WebviewWindow } from "@tauri-apps/api/webviewWindow";
	import { PhysicalSize } from "@tauri-apps/api/dpi";

	import globals from "$lib/globals.svelte";

	function setPreferedTheme() {
		let prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
		let value = prefersDark ? "dark" : "light";
		document.documentElement.setAttribute("data-theme", value);
	}

	async function initWindow() {
		if (globals.windowInited) {
			return;
		}

		setPreferedTheme();

		// Sleep because it takes a split second for colors to update after setting theme,
		// which leads to a white flash if using dark theme.
		await new Promise(r => setTimeout(r, 42));

		let window = WebviewWindow.getCurrent();
		await window.setTitle("MyTitle");
		await window.setSize(new PhysicalSize(1400, 800));
		await window.setMinSize(new PhysicalSize(300, 400));
		await window.center();
		await window.show();

		globals.windowInited = true;
	}

	onMount(() => {
		initWindow();
	});
</script>
```
It would be great to expose the background color setting in the Webview API. Spent about an hour trying to set background color here and there and even used some sample from with_webview which returns a platform webview but nothing really worked and the app still flashes white background at open.
> but nothing really worked and the app still flashes white background at open.

Likely because it's not (only) the webview flashing but also the native window itself which makes this quite a bit harder.
> > but nothing really worked and the app still flashes white background at open.
> 
> 
> 
> Likely because it's not (only) the webview flashing but also the native window itself which makes this quite a bit harder.

Good point. I will set the background colour on both and see if it helps. 
I can create a window without webview and change the color. That works fine. 

But webview doesn't seem to react to the change of color:

```fs
pub trait WebviewExt {
    #[cfg(target_os = "macos")]
    fn set_background_color(&self, color: &tauri::window::Color) -> tauri::Result<()>;
}

impl WebviewExt for tauri::Webview {
    #[cfg(target_os = "macos")]
    fn set_background_color(&self, color: &tauri::window::Color) -> tauri::Result<()> {
        use crate::color_ext::ColorExt;
        let (r, g, b, a) = color.as_nscolor_tuple();

        self.with_webview(move |platform_webview| {
            unsafe {
                let nscolor: cocoa::base::id =
                    msg_send![class!(NSColor), colorWithDeviceRed:r green:g blue:b alpha:a];
                let id = platform_webview.ns_window();
                let () = msg_send![id, setBackgroundColor: nscolor];
            }
        })
    }
}
```
It seems apps using Electron have fixed this. I've been using MongoDB Compass for a long time and it had the same issue; a flash of white before the content loads and the background colour updates. But that seems to have been fixed with the latest  update.
Any update on this? This is another one of those things that make me wanna go to Electron :/

I understand it's a hard problem, and if I knew where to look I'd love to help. Is anyone actively working on it?

The "white flash" effect in a dark mode app really makes it feel cheap...
The best workaround is to hide the window by default, and only show it once your app has loaded the required resources (and eventually painted another frame via requestAnimationFrame)

This may introduce an additional delay to show the app though.

Pick your poison.
There is a guide on how to do it at least on macos in tauri v2 https://v2.tauri.app/plugin/window-customization/#macos-transparent-titlebar-with-custom-window-background-color
> The "white flash" effect in a dark mode app really makes it feel cheap...

@albingroen I agree with your point, this is a very impactful issue for the user experience. Just imagine the feeling of opening VSCode every time and seeing a blank white screen.

@amrbashir has made efforts in the past: [feat: allow setting webview bg color](https://github.com/tauri-apps/wry/pull/682), and I feel we are quite close to solving this problem, we just need a hero to step up and conquer this challenge.

Do you mean it's now supported by Wry-vanilla and the only thing left is to implement this into Tauri's APIs? (Surface option in window configuration, pass it to Wry, etc)?
Is there anything similar to Electron's event `ready-to-show`? [ref](https://www.electronjs.org/docs/latest/api/browser-window#showing-the-window-gracefully)
> Is there anything similar to Electron's event `ready-to-show`? [ref](https://www.electronjs.org/docs/latest/api/browser-window#showing-the-window-gracefully)

What I do is I make the window be initially invisible, attach either a `DOMContentLoaded` event listener on the JS side, or use a framework-specific "on mount" hook, like `createEffect` for React or `onMount` for SolidJS, in which show the current window.
With the release of tauri v2, is there any update to this?

I'll try digging through the changes and see if I can find something to accomplish this.
**EDIT: THIS DOESN'T WORK**

I solved this issue in my Svelte 5 + Tauri 2.0 app like so:

1. Set `"visible": false` in `tauri.conf.json`.

2. Set the `"core:window:allow-show"` permission under `capabilities/default.json` like so:
    ```json
    {
        ...
        "permissions": ["core:default", "core:window:allow-show", "shell:allow-open"]
    }
    ```

3. Show window on mount (using state rune / store):

    Homepage:
    ```svelte
    <script lang="ts">
      import { onMount } from "svelte";
      import { window } from "../stores/window.svelte.js";
    
      onMount(() => {
        window.show();
      });
    </script>
    ```

    Writable store:
    ```javascript
    import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
    
    let shown = $state(false);
    
    export const window = {
      get shown() {
        return shown;
      },
      async show() {
        if (!shown) {
          console.log("showing window");
          await getCurrentWebviewWindow().show();
          shown = true;
        } else {
          console.log("window already shown");
        }
      },
    };
    ```

Hope it helps, cheers! 🍺 
You will see the white background again if you reload, refresh, or resize the window. It seems very abrupt, especially in dark theme mode.

> I solved this issue in my Svelte 5 + Tauri 2.0 app like so:
> 
> 1. Set `"visible": false` in `tauri.conf.json`.
> 2. Set the `"core:window:allow-show"` permission under `capabilities/default.json` like so:
>    ```json
>    {
>        ...
>        "permissions": ["core:default", "core:window:allow-show", "shell:allow-open"]
>    }
>    ```
> 3. Show window on mount (using state rune / store):
>    Homepage:
>    ```svelte
>    <script lang="ts">
>      import { onMount } from "svelte";
>      import { window } from "../stores/window.svelte.js";
>    
>      onMount(() => {
>        window.show();
>      });
>    </script>
>    ```
>    
>    
>        
>          
>        
>    
>          
>        
>    
>        
>      
>    Writable store:
>    ```js
>    import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
>    
>    let shown = $state(false);
>    
>    export const window = {
>      get shown() {
>        return shown;
>      },
>      async show() {
>        if (!shown) {
>          console.log("showing window");
>          await getCurrentWebviewWindow().show();
>          shown = true;
>        } else {
>          console.log("window already shown");
>        }
>      },
>    };
>    ```
> 
> Hope it helps, cheers! 🍺


you're right @xuchaoqian. this is not fixed. i'll update my comment until i figure out a fix... unless; do you know how to fix it? :)

Fix patch:
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: <https://v2.tauri.app/reference/config/#securityconfig>",
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<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();
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<tao::window::Window>,
       std::sync::Arc<tao::window::Window>,
     >,
+    background_color: Option<tao::window::RGBA>,
   );
 }
 
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<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();
     }
   }
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<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<()>;
 
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<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.
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: <https://v2.tauri.app/reference/config/#securityconfig>",
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<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);
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<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());
+  }
 }
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 +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/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<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
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<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,
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<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
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<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
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<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,
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<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)))]
       {
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<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 }
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<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 }
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<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 {


Test patch:
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<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)]