diff --git a/runtime/src/window.rs b/runtime/src/window.rs index 217b6a00c0..8416cc4b71 100644 --- a/runtime/src/window.rs +++ b/runtime/src/window.rs @@ -179,6 +179,11 @@ pub fn change_level(id: Id, level: Level) -> Command { Command::single(command::Action::Window(Action::ChangeLevel(id, level))) } +/// Show window menu at cursor position. +pub fn show_window_menu(id: Id) -> Command { + Command::single(command::Action::Window(Action::ShowWindowMenu(id))) +} + /// Fetches an identifier unique to the window, provided by the underlying windowing system. This is /// not to be confused with [`Id`]. pub fn fetch_id( diff --git a/runtime/src/window/action.rs b/runtime/src/window/action.rs index 8b5325692c..dc168c5d4b 100644 --- a/runtime/src/window/action.rs +++ b/runtime/src/window/action.rs @@ -79,6 +79,11 @@ pub enum Action { GainFocus(Id), /// Change the window [`Level`]. ChangeLevel(Id, Level), + /// Show window menu at cursor position. + /// + /// ## Platform-specific + /// Android / iOS / macOS / Orbital / Wayland / Web / X11: Unsupported. + ShowWindowMenu(Id), /// Fetch the raw identifier unique to the window. FetchId(Id, Box T + 'static>), /// Change the window [`Icon`]. @@ -137,6 +142,7 @@ impl Action { } Self::GainFocus(id) => Action::GainFocus(id), Self::ChangeLevel(id, level) => Action::ChangeLevel(id, level), + Self::ShowWindowMenu(id) => Action::ShowWindowMenu(id), Self::FetchId(id, o) => { Action::FetchId(id, Box::new(move |s| f(o(s)))) } @@ -193,6 +199,9 @@ impl fmt::Debug for Action { Self::ChangeLevel(id, level) => { write!(f, "Action::ChangeLevel({id:?}, {level:?})") } + Self::ShowWindowMenu(id) => { + write!(f, "Action::ShowWindowMenu({id:?})") + } Self::FetchId(id, _) => write!(f, "Action::FetchId({id:?})"), Self::ChangeIcon(id, _icon) => { write!(f, "Action::ChangeIcon({id:?})") diff --git a/winit/src/application.rs b/winit/src/application.rs index 36a39d5cc6..414f2f115f 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -1014,6 +1014,14 @@ pub fn run_command( window::Action::ChangeLevel(_id, level) => { window.set_window_level(conversion::window_level(level)); } + window::Action::ShowWindowMenu(_id) => { + if let mouse::Cursor::Available(point) = state.cursor() { + window.show_window_menu(winit::dpi::LogicalPosition { + x: point.x, + y: point.y, + }); + } + } window::Action::FetchId(_id, tag) => { proxy .send_event(UserEventWrapper::Message(tag(window diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index 88992bc137..b2e48210af 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -5,6 +5,7 @@ mod window_manager; use crate::application::UserEventWrapper; use crate::conversion; use crate::core; +use crate::core::mouse; use crate::core::renderer; use crate::core::widget::operation; use crate::core::widget::Operation; @@ -1271,6 +1272,20 @@ fn run_command( .set_window_level(conversion::window_level(level)); } } + window::Action::ShowWindowMenu(id) => { + if let Some(window) = window_manager.get_mut(id) { + if let mouse::Cursor::Available(point) = + window.state.cursor() + { + window.raw.show_window_menu( + winit::dpi::LogicalPosition { + x: point.x, + y: point.y, + }, + ); + } + } + } window::Action::FetchId(id, tag) => { if let Some(window) = window_manager.get_mut(id) { proxy