diff --git a/runtime/src/window.rs b/runtime/src/window.rs index 04bcfcd8b3..b442939c2b 100644 --- a/runtime/src/window.rs +++ b/runtime/src/window.rs @@ -106,6 +106,14 @@ pub fn move_to(id: Id, position: Point) -> Command { Command::single(command::Action::Window(Action::Move(id, position))) } +/// Fetches the window's location in logical coordinates. +pub fn fetch_location( + id: Id, + f: impl FnOnce(Option) -> Message + 'static, +) -> Command { + Command::single(command::Action::Window(Action::FetchLocation(id, Box::new(f)))) +} + /// Changes the [`Mode`] of the window. pub fn change_mode(id: Id, mode: Mode) -> Command { Command::single(command::Action::Window(Action::ChangeMode(id, mode))) diff --git a/runtime/src/window/action.rs b/runtime/src/window/action.rs index 9bfc2b6203..39eb100833 100644 --- a/runtime/src/window/action.rs +++ b/runtime/src/window/action.rs @@ -42,6 +42,8 @@ pub enum Action { /// /// Unsupported on Wayland. Move(Id, Point), + /// Fetch the current logical coordinates of the window. + FetchLocation(Id, Box) -> T + 'static>), /// Change the [`Mode`] of the window. ChangeMode(Id, Mode), /// Fetch the current [`Mode`] of the window. @@ -135,6 +137,9 @@ impl Action { } Self::Minimize(id, minimized) => Action::Minimize(id, minimized), Self::Move(id, position) => Action::Move(id, position), + Self::FetchLocation(id, o) => { + Action::FetchLocation(id, Box::new(move |s| f(o(s)))) + } Self::ChangeMode(id, mode) => Action::ChangeMode(id, mode), Self::FetchMode(id, o) => { Action::FetchMode(id, Box::new(move |s| f(o(s)))) @@ -189,6 +194,9 @@ impl fmt::Debug for Action { Self::Move(id, position) => { write!(f, "Action::Move({id:?}, {position})") } + Self::FetchLocation(id, _) => { + write!(f, "Action::FetchLocation({id:?})") + } Self::ChangeMode(id, mode) => { write!(f, "Action::SetMode({id:?}, {mode:?})") } diff --git a/winit/src/application.rs b/winit/src/application.rs index 1fd51d82f5..d2a373e40f 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -773,6 +773,16 @@ pub fn run_command( y: position.y, }); } + window::Action::FetchLocation(_id, callback) => { + let position = window.inner_position().map(|p| { + let pos = p.to_logical::(window.scale_factor()); + crate::core::Point::new(pos.x, pos.y) + }).ok(); + + proxy + .send_event(callback(position)) + .expect("Send message to event loop"); + } window::Action::ChangeMode(_id, mode) => { window.set_visible(conversion::visible(mode)); window.set_fullscreen(conversion::fullscreen( diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index c63dd43332..27552554c2 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -1003,6 +1003,23 @@ fn run_command( ); } } + window::Action::FetchLocation(id, callback) => { + if let Some(window) = window_manager.get_mut(id) { + let position = window + .raw + .inner_position() + .map(|p| { + let pos = p.to_logical::( + window.raw.scale_factor(), + ); + crate::core::Point::new(pos.x, pos.y) + }).ok(); + + proxy + .send_event(callback(position)) + .expect("Send message to event loop"); + } + } window::Action::ChangeMode(id, mode) => { if let Some(window) = window_manager.get_mut(id) { window.raw.set_visible(conversion::visible(mode));