Skip to content

Commit bcf2792

Browse files
feat(core): add ContextMenu::hpopupmenu on Windows (#11354)
* feat(core): add `ContextMenu::hpopupmenu` on Windows closes #11339 * Update crates/tauri/src/menu/mod.rs --------- Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app>
1 parent 68d4460 commit bcf2792

File tree

7 files changed

+27
-3
lines changed

7 files changed

+27
-3
lines changed

.changes/hpopupmenu.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": "patch:feat"
3+
---
4+
5+
On Windows, Add `ContextMenu::hpopupmenu` method to get the [`HMENU`](https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types#HMENU) used for popups and tray icon menu.

crates/tauri-cli/config.schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@
11041104
]
11051105
},
11061106
"Capability": {
1107-
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```",
1107+
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```",
11081108
"type": "object",
11091109
"required": [
11101110
"identifier",

crates/tauri-schema-generator/schemas/capability.schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"title": "Capability",
4-
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```",
4+
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```",
55
"type": "object",
66
"required": [
77
"identifier",

crates/tauri-schema-generator/schemas/config.schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@
11041104
]
11051105
},
11061106
"Capability": {
1107-
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```",
1107+
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows fine grained access to the Tauri core, application, or plugin commands.\n If a window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```",
11081108
"type": "object",
11091109
"required": [
11101110
"identifier",

crates/tauri/src/menu/menu.rs

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ pub const WINDOW_SUBMENU_ID: &str = "__tauri_window_menu__";
2121
pub const HELP_SUBMENU_ID: &str = "__tauri_help_menu__";
2222

2323
impl<R: Runtime> super::ContextMenu for Menu<R> {
24+
#[cfg(target_os = "windows")]
25+
fn hpopupmenu(&self) -> crate::Result<isize> {
26+
run_item_main_thread!(self, |self_: Self| (*self_.0).as_ref().hpopupmenu())
27+
}
28+
2429
fn popup<T: Runtime>(&self, window: Window<T>) -> crate::Result<()> {
2530
self.popup_inner(window, None::<Position>)
2631
}

crates/tauri/src/menu/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,15 @@ pub trait IsMenuItem<R: Runtime>: sealed::IsMenuItemBase {
732732
///
733733
/// This trait is ONLY meant to be implemented internally by the crate.
734734
pub trait ContextMenu: sealed::ContextMenuBase + Send + Sync {
735+
/// Get the popup [`HMENU`] for this menu.
736+
///
737+
/// The returned [`HMENU`] is valid as long as the [`ContextMenu`] is.
738+
///
739+
/// [`HMENU`]: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types#HMENU
740+
#[cfg(windows)]
741+
#[cfg_attr(docsrs, doc(cfg(windows)))]
742+
fn hpopupmenu(&self) -> crate::Result<isize>;
743+
735744
/// Popup this menu as a context menu on the specified window at the cursor position.
736745
fn popup<R: crate::Runtime>(&self, window: crate::Window<R>) -> crate::Result<()>;
737746

crates/tauri/src/menu/submenu.rs

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ use crate::{AppHandle, Manager, Position, Runtime, Window};
1313
use muda::{ContextMenu, MenuId};
1414

1515
impl<R: Runtime> super::ContextMenu for Submenu<R> {
16+
#[cfg(target_os = "windows")]
17+
fn hpopupmenu(&self) -> crate::Result<isize> {
18+
run_item_main_thread!(self, |self_: Self| (*self_.0).as_ref().hpopupmenu())
19+
}
20+
1621
fn popup<T: Runtime>(&self, window: Window<T>) -> crate::Result<()> {
1722
self.popup_inner(window, None::<Position>)
1823
}

0 commit comments

Comments
 (0)