Ver código fonte

fix(Windows): sync menubar theme with the window theme (#9832)

* fix(Windows): sync menubar theme with the window theme

ref: https://github.com/tauri-apps/muda/issues/170

* fix moc runtime

* muda 0.13.4

* missing change file

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
Amr Bashir 1 ano atrás
pai
commit
276c4b1438

+ 6 - 0
.changes/core-windows-menubar-theme.md

@@ -0,0 +1,6 @@
+---
+"tauri": "patch:bug"
+---
+
+On Windows, fix wrong menubar theme when window is using an explicit theme.
+

+ 6 - 0
.changes/runtime-window-builder-get-theme.md

@@ -0,0 +1,6 @@
+---
+"tauri-runtime": patch:enhance
+"tauri-runtime-wry": patch:enhance
+---
+
+Added `WindowBuilder::get_theme`.

+ 3 - 3
Cargo.lock

@@ -1765,7 +1765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
 dependencies = [
  "cfg-if",
- "windows-targets 0.52.5",
+ "windows-targets 0.48.5",
 ]
 
 [[package]]
@@ -1940,9 +1940,9 @@ dependencies = [
 
 [[package]]
 name = "muda"
-version = "0.13.1"
+version = "0.13.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f428b4e9db3d17e2f809dfb1ff9ddfbbf16c71790d1656d10aee320877e1392f"
+checksum = "1717c136c99673f55640c14125a0349a5cd7fee6efcfb0adbfe4c289e3b3f7f2"
 dependencies = [
  "cocoa",
  "crossbeam-channel",

+ 7 - 0
core/tauri-runtime-wry/src/lib.rs

@@ -1023,6 +1023,13 @@ impl WindowBuilder for WindowBuilderWrapper {
   fn has_icon(&self) -> bool {
     self.inner.window.window_icon.is_some()
   }
+
+  fn get_theme(&self) -> Option<Theme> {
+    self.inner.window.preferred_theme.map(|theme| match theme {
+      TaoTheme::Dark => Theme::Dark,
+      _ => Theme::Light,
+    })
+  }
 }
 
 #[cfg(any(

+ 2 - 0
core/tauri-runtime/src/window.rs

@@ -409,6 +409,8 @@ pub trait WindowBuilder: WindowBuilderBase {
 
   /// Whether the icon was set or not.
   fn has_icon(&self) -> bool;
+
+  fn get_theme(&self) -> Option<Theme>;
 }
 
 /// A window that has yet to be built.

+ 1 - 1
core/tauri/Cargo.toml

@@ -78,7 +78,7 @@ dunce = "1"
 specta = { version = "^2.0.0-rc.9", optional = true, default-features = false, features = [ "function" ] }
 
 [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies]
-muda = { version = "0.13", default-features = false, features = [ "serde" ] }
+muda = { version = "0.13.4", default-features = false, features = [ "serde" ] }
 tray-icon = { version = "0.13", default-features = false, features = [ "serde" ], optional = true }
 
 [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]

+ 7 - 1
core/tauri/src/manager/menu.rs

@@ -54,6 +54,7 @@ impl<R: Runtime> MenuManager<R> {
   pub(crate) fn prepare_window_menu_creation_handler(
     &self,
     window_menu: Option<&crate::window::WindowMenu<R>>,
+    #[allow(unused)] theme: Option<tauri_utils::Theme>,
   ) -> Option<impl Fn(tauri_runtime::window::RawWindow<'_>)> {
     {
       if let Some(menu) = window_menu {
@@ -71,7 +72,12 @@ impl<R: Runtime> MenuManager<R> {
       let menu = menu.menu.clone();
       Some(move |raw: tauri_runtime::window::RawWindow<'_>| {
         #[cfg(target_os = "windows")]
-        let _ = menu.inner().init_for_hwnd(raw.hwnd as _);
+        {
+          let theme = theme
+            .map(crate::menu::map_to_menu_theme)
+            .unwrap_or(muda::MenuTheme::Auto);
+          let _ = menu.inner().init_for_hwnd_with_theme(raw.hwnd as _, theme);
+        }
         #[cfg(any(
           target_os = "linux",
           target_os = "dragonfly",

+ 9 - 0
core/tauri/src/menu/mod.rs

@@ -763,3 +763,12 @@ pub(crate) mod sealed {
     ) -> crate::Result<()>;
   }
 }
+
+#[cfg(windows)]
+pub(crate) fn map_to_menu_theme(theme: tauri_utils::Theme) -> muda::MenuTheme {
+  match theme {
+    tauri_utils::Theme::Light => muda::MenuTheme::Light,
+    tauri_utils::Theme::Dark => muda::MenuTheme::Dark,
+    _ => muda::MenuTheme::Auto,
+  }
+}

+ 4 - 0
core/tauri/src/test/mock_runtime.rs

@@ -462,6 +462,10 @@ impl WindowBuilder for MockWindowBuilder {
   fn has_icon(&self) -> bool {
     false
   }
+
+  fn get_theme(&self) -> Option<Theme> {
+    None
+  }
 }
 
 impl<T: UserEvent> WebviewDispatch<T> for MockWebviewDispatcher {

+ 7 - 2
core/tauri/src/window/mod.rs

@@ -390,7 +390,7 @@ tauri::Builder::default()
     #[cfg(desktop)]
     let handler = app_manager
       .menu
-      .prepare_window_menu_creation_handler(window_menu.as_ref());
+      .prepare_window_menu_creation_handler(window_menu.as_ref(), self.window_builder.get_theme());
     #[cfg(not(desktop))]
     #[allow(clippy::type_complexity)]
     let handler: Option<Box<dyn Fn(tauri_runtime::window::RawWindow<'_>) + Send>> = None;
@@ -1160,7 +1160,12 @@ tauri::Builder::default()
     self.run_on_main_thread(move || {
       #[cfg(windows)]
       if let Ok(hwnd) = window.hwnd() {
-        let _ = menu_.inner().init_for_hwnd(hwnd.0);
+        let theme = window
+          .theme()
+          .map(crate::menu::map_to_menu_theme)
+          .unwrap_or(muda::MenuTheme::Auto);
+
+        let _ = menu_.inner().init_for_hwnd_with_theme(hwnd.0, theme);
       }
       #[cfg(any(
         target_os = "linux",

+ 2 - 2
examples/api/src-tauri/Cargo.lock

@@ -1777,9 +1777,9 @@ dependencies = [
 
 [[package]]
 name = "muda"
-version = "0.13.2"
+version = "0.13.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6fde56ead0971b4caae4aa0f19502e49d1fac2af9d0c60068e2d235e26ce709"
+checksum = "1717c136c99673f55640c14125a0349a5cd7fee6efcfb0adbfe4c289e3b3f7f2"
 dependencies = [
  "cocoa",
  "crossbeam-channel",