denoland/deno · #36649

feat(desktop): support checked, icon, and tooltip on menu items

crowlKats · merged Aug 25, 20267 files · 110 + / 26
Cargo.lock3 + / 2
@@ -3382,6 +3382,7 @@ dependencies = [  "rustyline",  "same-file",  "serde",+ "serde_bytes",  "sha2",  "sys_traits",  "test_util",@@ -6391,9 +6392,9 @@ dependencies = [  [[package]] name = "laufey"-version = "0.6.1"+version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "9a9149a6c84f22c936d2b6ff1ba3392de20f9ee76eb65e5aebfdca4c8621ba3f"+checksum = "8a2a04490eb866f17dcbbb44c8277b45964eeb0f68bb17c444e69c2feff0db94" dependencies = [  "bindgen 0.72.1",  "tokio",
cli/laufey_sums.lock18 + / 18
@@ -12,22 +12,22 @@ # A `# version: vX.Y.Z` directive (optional) is matched against LAUFEY_VERSION # at build time to guard against forgetting to refresh this file. #-# version: v0.6.1+# version: v0.7.0 -b8eaa10b19b76d8e04c2c958bb1e8296b36aa92050a9ff710e5e41978670cc65  laufey-cef-aarch64-apple-darwin.tar.gz-4f5d87c14e0050a1188f362a5e3cc2cf208f3b5c50db2ca7d68d644b4ae5135a  laufey-cef-aarch64-unknown-linux-gnu.tar.gz-7c7a1df2bcd752c1a69dc76d82482025878ad55b0b5379816f9587c652f388c4  laufey-cef-x86_64-apple-darwin.tar.gz-95b7dad31881c036a5355a8d9b1272d60161866295506ae91b0244cc88994951  laufey-cef-x86_64-unknown-linux-gnu.tar.gz-1626fde17f134365d7bee6edf6bbe03a9a549f775c3bfd8996d01ebeefce4f65  laufey-webview-aarch64-apple-darwin.tar.gz-96efbf6b1eea2d83915bcdd1d62d6d0a01e5daca83d7a94befc0644d02374e1a  laufey-webview-aarch64-unknown-linux-gnu.tar.gz-643c735b7c12d870c3259b5c9d429b6d40ed3bc36a58de3d1936df84fca31c2a  laufey-webview-x86_64-apple-darwin.tar.gz-714d4cabb8c55a2e82b643cc82b8f24706fccbfe9b98a902cb6371a222d6d9bd  laufey-webview-x86_64-unknown-linux-gnu.tar.gz-cd33994cdbfb4650e527965e56c26d49a01d26d5ad27ec76a5bb43c3dc1bc2e0  laufey-winit-aarch64-apple-darwin.tar.gz-cdc9c52b6730d3a684076d6033caa5b18dc96147e659005fddf7f0717b6758f6  laufey-winit-aarch64-unknown-linux-gnu.tar.gz-ce6d5ba64027ef9a0e34da589c9de1cb097a1f84229fe8cd303b8aba770e6065  laufey-winit-x86_64-apple-darwin.tar.gz-b0db0c0892181481976da48291ff5befe1cdf81d6e1e2598d6c78b9ed2c616f5  laufey-winit-x86_64-unknown-linux-gnu.tar.gz-00e5a5582c8b3bd236ea71cd0f78a772e6513777ca52cdbc2202720e4de02238  laufey-cef-x86_64-pc-windows-msvc.zip-2d9bfbac4b1aa9606ff7227287233cefbce10dffc1a59c821dd535b46bef268f  laufey-webview-aarch64-pc-windows-msvc.zip-48f52268d08fc0636373c5841146202a8acb4aeed4d4e8c98952e6ebe93f3124  laufey-webview-x86_64-pc-windows-msvc.zip-aebf9f07a0c1ca9068613ce9aedf6e364b9157ce28e04547d5b0e41b77416203  laufey-winit-aarch64-pc-windows-msvc.zip-5b629661d1702b950721c19a443ddd0f1640f5d14b8294e080cdead1a7722623  laufey-winit-x86_64-pc-windows-msvc.zip+edc9d8d68016417f726f0a7268240c015017439036e05cf16c464856cd423f47  laufey-cef-aarch64-apple-darwin.tar.gz+11cc33bca5a58bb47dc300a0097447c8ca41f61d18cbabb906023cfc4dc35fb9  laufey-cef-aarch64-unknown-linux-gnu.tar.gz+d2e6bcf24cf256e477ba59a8e07417ae7e4830d803c875dd3df4d89a163b09cb  laufey-cef-x86_64-apple-darwin.tar.gz+4d23f2d215370242e5c36ee7b89f6dcf7e3d79ea44bc3c50e3e6acaf837d73ad  laufey-cef-x86_64-pc-windows-msvc.zip+38359a26bec39f3114c81ef83cace7d351c002f8640bb01426bb7630042c02f3  laufey-cef-x86_64-unknown-linux-gnu.tar.gz+f1ac94af61bbc3c64bb4e7742b8fd3333704ce4546c2b279616a0f00ae5e6422  laufey-webview-aarch64-apple-darwin.tar.gz+6dfe651589326a8e5e00d08af43abecad3040a32a3c9314010cc5f9edcb50812  laufey-webview-aarch64-pc-windows-msvc.zip+bd7d7828a87793b26ec3234f36b13cdb0afb762daa94d7461c37de366da9accc  laufey-webview-aarch64-unknown-linux-gnu.tar.gz+46dd0b4314d0ed5f93f5ed16b3b4c9e1faf051fc6fccb373f9e233c253d49aa2  laufey-webview-x86_64-apple-darwin.tar.gz+f27ae3b90f0f527ef2c32575e5af7862d95e1400a98561a06a37ce8ffffaa53a  laufey-webview-x86_64-pc-windows-msvc.zip+6f4c5e05f934128c1d77f7a1cc8e859331171cf8a89a0d2e19f5c07cf081b235  laufey-webview-x86_64-unknown-linux-gnu.tar.gz+57481c5f5759f782c11c43f1c14133424c869123f1b42431f3138f7cb2e77651  laufey-winit-aarch64-apple-darwin.tar.gz+955db95103ee4656899dff7e507e01a194d5f670ec1129267da0b94216c0f50e  laufey-winit-aarch64-pc-windows-msvc.zip+cee7fac6d66faf043df09cceea80233cc41ce39fe317a72c80b778cce5568c93  laufey-winit-aarch64-unknown-linux-gnu.tar.gz+f05cdeddda3b30caa6dec4b258031c161ad3c5356c75794c5d0cc352b95ba5dd  laufey-winit-x86_64-apple-darwin.tar.gz+ee23fe21e1ff75a693aeb2aa48b07f0d95c449a1036e6acfaf1759436a878eab  laufey-winit-x86_64-pc-windows-msvc.zip+173c091ee71bcc3b6e9e9811c6e818f8f3ac92f72ab8e3ac1daaad0076aa56be  laufey-winit-x86_64-unknown-linux-gnu.tar.gz
cli/rt_desktop/Cargo.toml1 + / 1
@@ -33,7 +33,7 @@ deno_runtime.workspace = true deno_snapshots.workspace = true deno_terminal.workspace = true denort = { path = "../rt", default-features = false }-laufey = "0.6.1"+laufey = "0.7.0" libsui.workspace = true  log = { workspace = true, features = ["serde"] }
cli/rt_desktop/lib.rs19 + / 5
@@ -45,7 +45,7 @@ use denort::run::RunOptions; /// makes the failure mode obvious instead of "the desktop app silently won't /// launch". const _: () = assert!(-  laufey::LAUFEY_API_VERSION == 30,+  laufey::LAUFEY_API_VERSION == 34,   "LAUFEY_API_VERSION mismatch: update this assert and the prebuilt backend release pin in cli/tools/desktop.rs when laufey bumps its API version", ); @@ -868,14 +868,17 @@ fn desktop_menu_item_to_laufey_menu_item(       id,       accelerator,       enabled,+      checked,+      icon,+      tooltip,     } => laufey::MenuItem::Item {       label,       id,       accelerator,       enabled,-      checked: false,-      icon: None,-      tooltip: None,+      checked,+      icon,+      tooltip,     },     denort::desktop::MenuItem::Submenu { label, items } => {       laufey::MenuItem::Submenu {@@ -2137,19 +2140,27 @@ mod tests {       id: Some("file.save".into()),       accelerator: Some("CmdOrCtrl+S".into()),       enabled: true,+      checked: true,+      icon: Some(vec![0x89, b'P', b'N', b'G']),+      tooltip: Some("Save the current file".into()),     };     match desktop_menu_item_to_laufey_menu_item(item) {       laufey::MenuItem::Item {         label,         id,         accelerator,         enabled,-        ..+        checked,+        icon,+        tooltip,       } => {         assert_eq!(label, "Save");         assert_eq!(id.as_deref(), Some("file.save"));         assert_eq!(accelerator.as_deref(), Some("CmdOrCtrl+S"));         assert!(enabled);+        assert!(checked);+        assert_eq!(icon.as_deref(), Some(&[0x89, b'P', b'N', b'G'][..]));+        assert_eq!(tooltip.as_deref(), Some("Save the current file"));       }       _ => panic!("expected Item"),     }@@ -2165,6 +2176,9 @@ mod tests {           id: Some("open".into()),           accelerator: None,           enabled: false,+          checked: false,+          icon: None,+          tooltip: None,         },         denort::desktop::MenuItem::Separator,         denort::desktop::MenuItem::Role {
cli/tsc/dts/lib.deno.desktop.d.ts11 + / 0
@@ -497,6 +497,17 @@ declare namespace Deno {         id?: string;         accelerator?: string;         enabled: boolean;+        /** Show a checkmark next to the item. Supported on all+         * platforms. Defaults to `false`. */+        checked?: boolean;+        /** PNG-encoded image bytes shown next to the label, like+         * {@linkcode Tray.setIcon}. Supported on macOS and Windows;+         * ignored on Linux. On macOS a monochrome black+alpha PNG is+         * rendered as a template image, tinting to white when the item+         * is highlighted. */+        icon?: Uint8Array;+        /** Tooltip shown when hovering over the item. macOS only. */+        tooltip?: string;       };     }     | {
runtime/Cargo.toml1 + / 0
@@ -87,6 +87,7 @@ regex.workspace = true rustyline = { workspace = true, features = ["custom-bindings"] } same-file.workspace = true serde.workspace = true+serde_bytes.workspace = true sha2.workspace = true sys_traits.workspace = true thiserror.workspace = true
runtime/ops/desktop.rs57 + / 0
@@ -897,6 +897,15 @@ pub enum MenuItem {     id: Option<String>,     accelerator: Option<String>,     enabled: bool,+    /// Checkmark next to the item. All platforms.+    #[serde(default)]+    checked: bool,+    /// PNG-encoded image bytes shown next to the label. macOS and+    /// Windows only.+    #[serde(with = "serde_bytes", default)]+    icon: Option<Vec<u8>>,+    /// Tooltip shown on hover. macOS only.+    tooltip: Option<String>,   },   Submenu {     label: String,@@ -1770,6 +1779,7 @@ mod tests {    use super::BrowserWindow;   use super::DesktopEvent;+  use super::MenuItem;   use super::PendingBindResponses;   use super::PermissionState;   use super::Tray;@@ -1821,6 +1831,53 @@ mod tests {     }   } +  #[test]+  fn menu_item_wire_shape_new_fields_are_optional() {+    // Pre-existing callers only pass label/enabled (+ optional id and+    // accelerator); checked/icon/tooltip must default rather than error.+    let item: MenuItem = serde_json::from_value(json!({+      "item": { "label": "Save", "enabled": true }+    }))+    .unwrap();+    match item {+      MenuItem::Item {+        checked,+        icon,+        tooltip,+        ..+      } => {+        assert!(!checked);+        assert!(icon.is_none());+        assert!(tooltip.is_none());+      }+      _ => panic!("expected Item"),+    }++    let item: MenuItem = serde_json::from_value(json!({+      "item": {+        "label": "Mute",+        "enabled": true,+        "checked": true,+        "icon": [0x89, 0x50, 0x4E, 0x47],+        "tooltip": "Silence notifications",+      }+    }))+    .unwrap();+    match item {+      MenuItem::Item {+        checked,+        icon,+        tooltip,+        ..+      } => {+        assert!(checked);+        assert_eq!(icon.as_deref(), Some(&[0x89u8, 0x50, 0x4E, 0x47][..]));+        assert_eq!(tooltip.as_deref(), Some("Silence notifications"));+      }+      _ => panic!("expected Item"),+    }+  }+   #[test]   fn app_menu_click_wire_shape() {     let v = serde_json::to_value(DesktopEvent::AppMenuClick {